GNSS-SDR  0.0.21
An Open Source GNSS Software Defined Receiver
osnma_msg_receiver.h
Go to the documentation of this file.
1 /*!
2  * \file osnma_msg_receiver.h
3  * \brief GNU Radio block that processes Galileo OSNMA data received from
4  * Galileo E1B telemetry blocks. After successful decoding, sends the content to
5  * the PVT block.
6  * \author Carles Fernandez-Prades, 2023-2024. cfernandez(at)cttc.es
7  * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de
8  *
9  * -----------------------------------------------------------------------------
10  *
11  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
12  * This file is part of GNSS-SDR.
13  *
14  * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
15  * SPDX-License-Identifier: GPL-3.0-or-later
16  *
17  * -----------------------------------------------------------------------------
18  */
19 
20 #ifndef GNSS_SDR_OSNMA_MSG_RECEIVER_H
21 #define GNSS_SDR_OSNMA_MSG_RECEIVER_H
22 
23 #define FRIEND_TEST(test_case_name, test_name) \
24  friend class test_case_name##_##test_name##_Test
25 
26 #include "galileo_inav_message.h" // for OSNMA_msg
27 #include "gnss_block_interface.h" // for gnss_shared_ptr
28 #include "osnma_data.h" // for OSNMA_data structures
29 #include "osnma_nav_data_manager.h" // for OSNMA_NavDataManager
30 #include <gnuradio/block.h> // for gr::block
31 #include <pmt/pmt.h> // for pmt::pmt_t
32 #include <array> // for std::array
33 #include <cstdint> // for uint8_t
34 #include <ctime> // for std::time_t
35 #include <map> // for std::map, std::multimap
36 #include <memory> // for std::shared_ptr
37 #include <string> // for std::string
38 #include <utility> // for std::pair
39 #include <vector> // for std::vector
40 
41 /** \addtogroup Core
42  * \{ */
43 /** \addtogroup Core_Receiver_Library
44  * \{ */
45 
46 class OSNMA_DSM_Reader;
47 class Gnss_Crypto;
48 class Osnma_Helper;
49 class osnma_msg_receiver;
50 
51 using osnma_msg_receiver_sptr = gnss_shared_ptr<osnma_msg_receiver>;
52 
53 osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode = false);
54 
55 /*!
56  * \brief GNU Radio block that receives asynchronous OSNMA messages
57  * from the telemetry blocks, stores them in memory, and decodes OSNMA info
58  * when enough data have been received.
59  * The decoded OSNMA data is sent to the PVT block.
60  */
61 class osnma_msg_receiver : public gr::block
62 {
63 public:
64  ~osnma_msg_receiver() = default; //!< Default destructor
65  bool verify_dsm_pkr(const DSM_PKR_message& message) const; //!< Public for benchmarking purposes
66  void msg_handler_osnma(const pmt::pmt_t& msg); //!< For testing purposes
67  void read_merkle_xml(const std::string& merklepath); //!< Public for testing purposes
68  void set_merkle_root(const std::vector<uint8_t>& v); //!< Public for benchmarking purposes
69 
70 private:
71  friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode);
72  osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, bool strict_mode);
73 
74  void process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg);
75  void read_nma_header(uint8_t nma_header);
76  void read_dsm_header(uint8_t dsm_header);
77  void read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_msg);
78  void process_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_msg);
79  void process_dsm_message(const std::vector<uint8_t>& dsm_msg, const uint8_t& nma_header);
80  void read_and_process_mack_block(const std::shared_ptr<OSNMA_msg>& osnma_msg);
81  void read_mack_header();
82  void read_mack_body();
83  void process_mack_message();
84  void remove_verified_tags();
85  void control_tags_awaiting_verify_size();
86  void send_data_to_pvt(const std::vector<OSNMA_NavData>& data);
87 
88  bool verify_tesla_key(std::vector<uint8_t>& key, uint32_t TOW);
89  bool verify_tag(Tag& tag) const;
90  bool tag_has_nav_data_available(const Tag& t) const;
91  bool tag_has_key_available(const Tag& t) const;
92  bool store_dsm_kroot(const std::vector<uint8_t>& dsm, const uint8_t nma_header) const;
93 
94  std::pair<std::vector<uint8_t>, uint8_t> parse_dsm_kroot() const;
95  std::vector<uint8_t> get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const;
96  std::vector<uint8_t> compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const;
97  std::vector<uint8_t> build_message(Tag& tag) const;
98  std::vector<uint8_t> hash_chain(uint32_t num_of_hashes_needed, const std::vector<uint8_t>& key, uint32_t GST_SFi, const uint8_t lk_bytes) const;
99  std::vector<MACK_tag_and_info> verify_macseq(const MACK_message& mack);
100 
101  std::map<uint32_t, std::map<uint32_t, OSNMA_NavData>> d_satellite_nav_data; // map holding OSNMA_NavData sorted by SVID (first key) and TOW (second key).
102  std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys; // tesla keys over time, sorted by TOW
103  std::multimap<uint32_t, Tag> d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW
104 
105  std::vector<uint8_t> d_new_public_key;
106  std::vector<uint8_t> d_tags_to_verify{0, 4, 12};
107  std::vector<MACK_message> d_macks_awaiting_MACSEQ_verification;
108 
109  std::array<std::array<uint8_t, 256>, 16> d_dsm_message{}; // structure for recording DSM blocks, when filled it sends them to parse and resets itself.
110  std::array<std::array<uint8_t, 16>, 16> d_dsm_id_received{};
111  std::array<uint16_t, 16> d_number_of_blocks{};
112  std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
113 
114  std::unique_ptr<Gnss_Crypto> d_crypto; // class for cryptographic functions
115  std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
116  std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
117  std::unique_ptr<OSNMA_NavDataManager> d_nav_data_manager; // refactor for holding and processing navigation data
118 
119  OSNMA_data d_osnma_data{};
120 
121  uint32_t d_last_received_GST{0}; // latest GST received
122  uint32_t d_GST_Sf{}; // Scaled GST time for cryptographic computations
123  uint32_t d_GST_Rx{0}; // local GST receiver time
124  uint32_t d_last_verified_key_GST{0}; // GST for the latest verified TESLA key
125  uint32_t d_GST_0{}; // Time of applicability GST (KROOT + 30 s)
126  uint32_t d_GST_SIS{}; // GST coming from W6 and W5 of SIS
127  uint32_t d_GST_PKR_PKREV_start{};
128  uint32_t d_GST_PKR_AM_start{};
129  uint32_t d_GST_chain_renewal_start{};
130  uint32_t d_GST_chain_revocation_start{};
131 
132  uint32_t d_count_successful_tags{0};
133  uint32_t d_count_failed_tags{0};
134  uint32_t d_count_failed_Kroot{0};
135  uint32_t d_count_failed_pubKey{0}; // failed public key verifications against Merkle root
136  uint32_t d_count_failed_macseq{0};
137 
138  uint8_t const d_T_L{30}; // s RG Section 2.1
139  uint8_t d_new_public_key_id{};
140 
141  bool d_new_data{false};
142  bool d_public_key_verified{false};
143  bool d_kroot_verified{false};
144  bool d_tesla_key_verified{false};
145  bool d_strict_mode{false};
146  bool d_flag_hot_start{false};
147  bool d_flag_PK_renewal{false};
148  bool d_flag_PK_revocation{false};
149  bool d_flag_NPK_set{false};
150  bool d_flag_alert_message{false};
151  bool d_flag_chain_renewal{false};
152  bool d_flag_chain_revocation{false};
153 
154  // Provide access to inner functions to Gtest
155  FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification);
156  FRIEND_TEST(OsnmaMsgReceiverTest, TagVerification);
157  FRIEND_TEST(OsnmaMsgReceiverTest, BuildTagMessageM0);
158  FRIEND_TEST(OsnmaMsgReceiverTest, VerifyPublicKey);
159  FRIEND_TEST(OsnmaMsgReceiverTest, ComputeBaseLeaf);
160  FRIEND_TEST(OsnmaMsgReceiverTest, ComputeMerkleRoot);
161  FRIEND_TEST(OsnmaTestVectors, NominalTestConf1);
162  FRIEND_TEST(OsnmaTestVectors, NominalTestConf2);
163  FRIEND_TEST(OsnmaTestVectors, PublicKeyRenewal);
164  FRIEND_TEST(OsnmaTestVectors, PublicKeyRevocation);
165  FRIEND_TEST(OsnmaTestVectors, ChainRenewal);
166  FRIEND_TEST(OsnmaTestVectors, ChainRevocation);
167  FRIEND_TEST(OsnmaTestVectors, AlertMessage);
168 };
169 
170 
171 /** \} */
172 /** \} */
173 #endif // GNSS_SDR_OSNMA_MSG_RECEIVER_H
Class implementing cryptographic functions for Navigation Message Authentication. ...
Definition: gnss_crypto.h:41
This class handles ONSMA data See https://www.gsc-europa.eu/sites/default/files/sites/all/files/Galil...
Definition: osnma_data.h:178
void set_merkle_root(const std::vector< uint8_t > &v)
Public for benchmarking purposes.
Class for Galileo OSNMA navigation data management.
bool verify_dsm_pkr(const DSM_PKR_message &message) const
Public for benchmarking purposes.
Class for Galileo OSNMA data storage.
~osnma_msg_receiver()=default
Default destructor.
Implementation of a Galileo I/NAV Data message as described in Galileo OS SIS ICD Issue 2...
This interface represents a GNSS block.
void msg_handler_osnma(const pmt::pmt_t &msg)
For testing purposes.
GNU Radio block that receives asynchronous OSNMA messages from the telemetry blocks, stores them in memory, and decodes OSNMA info when enough data have been received. The decoded OSNMA data is sent to the PVT block.
void read_merkle_xml(const std::string &merklepath)
Public for testing purposes.