GNSS-SDR  0.0.20
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 display_data();
87  void send_data_to_pvt(const std::vector<OSNMA_NavData>& data);
88 
89  bool verify_tesla_key(std::vector<uint8_t>& key, uint32_t TOW);
90  bool verify_tag(Tag& tag) const;
91  bool tag_has_nav_data_available(const Tag& t) const;
92  bool tag_has_key_available(const Tag& t) const;
93  bool verify_macseq(const MACK_message& mack);
94 
95  bool store_dsm_kroot(const std::vector<uint8_t>& dsm, const uint8_t nma_header) const;
96 
97  std::pair<std::vector<uint8_t>, uint8_t> parse_dsm_kroot() const;
98  std::vector<uint8_t> get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const;
99  std::vector<uint8_t> compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const;
100  std::vector<uint8_t> build_message(Tag& tag) const;
101  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;
102  std::vector<MACK_tag_and_info> verify_macseq_new(const MACK_message& mack);
103 
104  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).
105  std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys; // tesla keys over time, sorted by TOW
106  std::multimap<uint32_t, Tag> d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW
107 
108  std::vector<uint8_t> d_new_public_key;
109  std::vector<uint8_t> d_tags_to_verify{0, 4, 12};
110  std::vector<MACK_message> d_macks_awaiting_MACSEQ_verification;
111 
112  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.
113  std::array<std::array<uint8_t, 16>, 16> d_dsm_id_received{};
114  std::array<uint16_t, 16> d_number_of_blocks{};
115  std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
116 
117  std::unique_ptr<Gnss_Crypto> d_crypto; // class for cryptographic functions
118  std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
119  std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
120  std::unique_ptr<OSNMA_NavDataManager> d_nav_data_manager; // refactor for holding and processing navigation data
121 
122  OSNMA_data d_osnma_data{};
123 
124  uint32_t d_last_received_GST{0}; // latest GST received
125  uint32_t d_GST_Sf{}; // Scaled GST time for cryptographic computations
126  uint32_t d_GST_Rx{0}; // local GST receiver time
127  uint32_t d_last_verified_key_GST{0}; // GST for the latest verified TESLA key
128  uint32_t d_GST_0{}; // Time of applicability GST (KROOT + 30 s)
129  uint32_t d_GST_SIS{}; // GST coming from W6 and W5 of SIS
130  uint32_t d_GST_PKR_PKREV_start{};
131  uint32_t d_GST_PKR_AM_start{};
132  uint32_t d_GST_chain_renewal_start{};
133  uint32_t d_GST_chain_revocation_start{};
134 
135  uint32_t d_count_successful_tags{0};
136  uint32_t d_count_failed_tags{0};
137  uint32_t d_count_failed_Kroot{0};
138  uint32_t d_count_failed_pubKey{0}; // failed public key verifications against Merkle root
139  uint32_t d_count_failed_macseq{0};
140 
141  uint8_t const d_T_L{30}; // s RG Section 2.1
142  uint8_t d_new_public_key_id{};
143 
144  bool d_new_data{false};
145  bool d_public_key_verified{false};
146  bool d_kroot_verified{false};
147  bool d_tesla_key_verified{false};
148  bool d_strict_mode{false};
149  bool d_flag_hot_start{false};
150  bool d_flag_PK_renewal{false};
151  bool d_flag_PK_revocation{false};
152  bool d_flag_NPK_set{false};
153  bool d_flag_alert_message{false};
154  bool d_flag_chain_renewal{false};
155  bool d_flag_chain_revocation{false};
156 
157  // Provide access to inner functions to Gtest
158  FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification);
159  FRIEND_TEST(OsnmaMsgReceiverTest, TagVerification);
160  FRIEND_TEST(OsnmaMsgReceiverTest, BuildTagMessageM0);
161  FRIEND_TEST(OsnmaMsgReceiverTest, VerifyPublicKey);
162  FRIEND_TEST(OsnmaMsgReceiverTest, ComputeBaseLeaf);
163  FRIEND_TEST(OsnmaMsgReceiverTest, ComputeMerkleRoot);
164  FRIEND_TEST(OsnmaTestVectors, NominalTestConf1);
165  FRIEND_TEST(OsnmaTestVectors, NominalTestConf2);
166  FRIEND_TEST(OsnmaTestVectors, PublicKeyRenewal);
167  FRIEND_TEST(OsnmaTestVectors, PublicKeyRevocation);
168  FRIEND_TEST(OsnmaTestVectors, ChainRenewal);
169  FRIEND_TEST(OsnmaTestVectors, ChainRevocation);
170  FRIEND_TEST(OsnmaTestVectors, AlertMessage);
171 };
172 
173 
174 /** \} */
175 /** \} */
176 #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.