1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-13 11:40:33 +00:00

Merge pull request #9 from carlesfernandez/osnma-cesare-fix9

Add ECDSA P-521 algorithm and unit test
This commit is contained in:
cesaaargm 2024-07-22 19:07:29 +02:00 committed by GitHub
commit 6c9f999583
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 1275 additions and 852 deletions

View File

@ -16,7 +16,7 @@ endif()
# Build type can still be overridden by setting -DCMAKE_BUILD_TYPE=
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
cmake_minimum_required(VERSION 2.8.12...3.29)
cmake_minimum_required(VERSION 2.8.12...3.30)
project(gnss-sdr CXX C)
set(GNSSSDR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # Allows to be a sub-project
@ -349,16 +349,16 @@ set(GNSSSDR_ABSEIL_MIN_VERSION "20240116")
################################################################################
# Versions to download and build (but not to install system-wide) if not found
################################################################################
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.8.x")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "14.0.x")
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.7.1")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.27")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "27.1")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "27.2")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.14")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.14.0")
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "origin/master")
set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.3.0")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.8.4")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.8.5")
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")
set(GNSSSDR_ABSL_LOCAL_VERSION "origin/master") # live at head (see https://abseil.io/about/releases)
@ -756,8 +756,18 @@ set(BOOST_COMPONENTS atomic chrono date_time serialization system thread)
if(NOT ${FILESYSTEM_FOUND})
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem)
endif()
find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
if(CMAKE_VERSION VERSION_LESS 3.30)
find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
else()
find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS})
if(NOT Boost_FOUND)
message(STATUS "Trying deprecated FindBoost Module ...")
if(POLICY CMP0167)
cmake_policy(SET CMP0167 OLD)
find_package(Boost ${GNSSSDR_BOOST_MIN_VERSION} REQUIRED COMPONENTS ${BOOST_COMPONENTS})
endif()
endif()
endif()
if(NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.")
endif()
@ -2101,7 +2111,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
-DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/armadillo-${armadillo_RELEASE}
-DBUILD_SHARED_LIBS=OFF
-DSTATIC_LIB=ON
-DBUILD_SMOKE_TEST=OFF
-DALLOW_BLAS_LAPACK_MACOS=ON
${ARMADILLO_CXX_VERSION}
@ -2120,7 +2130,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
-DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/armadillo-${armadillo_RELEASE}
-DBUILD_SHARED_LIBS=OFF
-DSTATIC_LIB=ON
-DBUILD_SMOKE_TEST=OFF
-DALLOW_BLAS_LAPACK_MACOS=ON
${ARMADILLO_CXX_VERSION}

View File

@ -66,7 +66,6 @@ information about this open-source, software-defined GNSS receiver.
- [Debian / Ubuntu](#debian--ubuntu)
- [AlmaLinux](#almalinux)
- [Arch Linux](#arch-linux)
- [CentOS](#centos)
- [Fedora](#fedora)
- [openSUSE](#opensuse)
- [Rocky Linux](#rocky-linux)
@ -126,7 +125,7 @@ This section describes how to set up the compilation environment in GNU/Linux or
## GNU/Linux
- Tested distributions: Ubuntu 14.04 LTS and above; Debian 9.0 "stretch" and
above; Arch Linux; CentOS 7; Fedora 26 and above; OpenSUSE 42.3 and above.
above; Arch Linux; Fedora 26 and above; OpenSUSE 42.3 and above.
- Supported microprocessor architectures:
- i386: Intel x86 instruction set (32-bit microprocessors).
- amd64: also known as x86-64, the 64-bit version of the x86 instruction set,
@ -233,25 +232,6 @@ $ pacman -S gcc make cmake pkgconf git boost boost-libs libvolk gnuradio \
Once you have installed these packages, you can jump directly to
[download the source code and build GNSS-SDR](#clone-gnss-sdrs-git-repository).
#### CentOS
If you are using CentOS 7, you can install the dependencies via Extra Packages
for Enterprise Linux ([EPEL](https://fedoraproject.org/wiki/EPEL)):
```
$ sudo yum install wget
$ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo rpm -Uvh epel-release-latest-7.noarch.rpm
$ sudo yum install make automake gcc gcc-c++ kernel-devel libtool \
hdf5-devel cmake git boost-devel boost-date-time boost-system \
boost-filesystem boost-thread boost-chrono boost-serialization \
log4cpp-devel gnuradio-devel gr-osmosdr-devel blas-devel lapack-devel \
armadillo-devel openssl-devel libpcap-devel python-mako python-six pugixml-devel
```
Once you have installed these packages, you can jump directly to
[download the source code and build GNSS-SDR](#clone-gnss-sdrs-git-repository).
#### Fedora
If you are using Fedora 26 or above, the required software dependencies can be
@ -403,12 +383,12 @@ or manually as explained below, and then please follow instructions on how to
```
$ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo yum install lapack-devel blas-devel # For Fedora/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux
$ wget https://sourceforge.net/projects/arma/files/armadillo-12.8.1.tar.xz
$ tar xvfz armadillo-12.8.1.tar.xz
$ cd armadillo-12.8.1
$ wget https://sourceforge.net/projects/arma/files/armadillo-14.0.0.tar.xz
$ tar xvfz armadillo-14.0.0.tar.xz
$ cd armadillo-14.0.0
$ cmake .
$ make
$ sudo make install

View File

@ -55,6 +55,7 @@ find_library(GFORTRAN NAMES gfortran
/usr/lib/gcc/sh4-linux-gnu
/usr/lib/gcc/i686-redhat-linux # Fedora
/usr/lib64/gcc/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux
/usr/lib/gcc/armv7hl-redhat-linux-gnueabi
/usr/lib/gcc/aarch64-redhat-linux
/usr/lib/gcc/ppc64le-redhat-linux

View File

@ -117,6 +117,9 @@ else()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA256")
set(GNUTLS_SIGN_ECDSA_SHA256 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA512")
set(GNUTLS_SIGN_ECDSA_SHA512 TRUE)
endif()
if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_DIG_SHA3_256")
set(GNUTLS_DIG_SHA3_256 TRUE)
endif()
@ -181,6 +184,9 @@ function(link_to_crypto_dependencies target)
if(GNUTLS_SIGN_ECDSA_SHA256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA256=1)
endif()
if(GNUTLS_SIGN_ECDSA_SHA512)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA512=1)
endif()
if(GNUTLS_DIG_SHA3_256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_DIG_SHA3_256=1)
endif()

View File

@ -692,12 +692,14 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
d_gnss_synchro->Acq_delay_samples -= static_cast<double>(d_acq_parameters.resampler_latency_samples); // account the resampler filter latency
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(samp_count) * d_acq_parameters.resampler_ratio);
d_gnss_synchro->fs = d_acq_parameters.resampled_fs;
}
else
{
d_gnss_synchro->Acq_delay_samples = static_cast<double>(std::fmod(static_cast<float>(indext), d_acq_parameters.samples_per_code));
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_gnss_synchro->fs = d_acq_parameters.fs_in;
}
}
else
@ -751,6 +753,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = rint(static_cast<double>(samp_count) * d_acq_parameters.resampler_ratio);
d_gnss_synchro->Acq_doppler_step = d_acq_parameters.doppler_step2;
d_gnss_synchro->fs = d_acq_parameters.resampled_fs;
}
else
{
@ -758,6 +761,7 @@ void pcps_acquisition::acquisition_core(uint64_t samp_count)
d_gnss_synchro->Acq_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_gnss_synchro->Acq_doppler_step = d_acq_parameters.doppler_step2;
d_gnss_synchro->fs = d_acq_parameters.fs_in;
}
}

View File

@ -8,7 +8,7 @@
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.8.12...3.29)
cmake_minimum_required(VERSION 2.8.12...3.30)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose build type: None Debug Release RelWithDebInfo MinSizeRel")
project(volk_gnsssdr)
enable_language(CXX)

View File

@ -3,14 +3,15 @@
* \brief GNU Radio block that processes Galileo OSNMA data received from
* Galileo E1B telemetry blocks. After successful decoding, sends the content to
* the PVT block.
* \author Carles Fernandez-Prades, 2023. cfernandez(at)cttc.es
* \author Carles Fernandez-Prades, 2023-2024. cfernandez(at)cttc.es
* Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
@ -24,12 +25,13 @@
#include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader
#include "osnma_helper.h"
#include <gnuradio/io_signature.h> // for gr::io_signature::make
#include <chrono>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <iomanip> // for std::setfill
#include <ios> // for std::hex, std::uppercase
#include <iostream>
#include <numeric>
#include <numeric> // for std::accumulate
#include <sstream> // std::stringstream
#include <typeinfo> // for typeid
#include <utility>
@ -101,14 +103,14 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
const auto sat = Gnss_Satellite(std::string("Galileo"), nma_msg->PRN); // TODO remove if unneeded
std::ostringstream output_message;
output_message << "Galileo OSNMA: complete OSNMA message received starting at "
output_message << "Galileo OSNMA: data received starting at "
<< "WN="
<< nma_msg->WN_sf0
<< ", TOW="
<< nma_msg->TOW_sf0
<< ", from satellite "
<< sat;
LOG(WARNING) << output_message.str();
LOG(INFO) << output_message.str();
std::cout << output_message.str() << std::endl;
process_osnma_message(nma_msg);
@ -119,33 +121,34 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
const auto inav_data = wht::any_cast<std::shared_ptr<std::tuple<uint32_t, std::string, uint32_t>>>(pmt::any_ref(msg));
uint32_t PRNa = std::get<0>(*inav_data);
std::string nav_data = std::get<1>(*inav_data);
;
uint32_t TOW = std::get<2>(*inav_data);
// iono data => 549 bits, utc data, 141 bits.
if (nav_data.size() == 549)
{
// LOG(INFO) << "Galileo OSNMA: received ADKD=0/12 navData, PRN_d (" << PRNa << ") "
// << "TOW_sf=" << TOW;
// LOG(INFO) << "Galileo OSNMA: received ADKD=0/12 navData, PRN_d (" << PRNa << ") "
// << "TOW_sf=" << TOW;
d_satellite_nav_data[PRNa][TOW].ephemeris_iono_vector_2 = nav_data;
}
else if (nav_data.size() == 141)
{
// LOG(INFO) << "Galileo OSNMA: received ADKD=4 navData, PRN_d (" << PRNa << ") "
// << "TOW_sf=" << TOW;
// LOG(INFO) << "Galileo OSNMA: received ADKD=4 navData, PRN_d (" << PRNa << ") "
// << "TOW_sf=" << TOW;
d_satellite_nav_data[PRNa][TOW].utc_vector_2 = nav_data;
}
else
LOG(WARNING) << "osnma_msg_receiver incorrect navData parsing!";
{
LOG(WARNING) << "Galileo OSNMA: osnma_msg_receiver incorrect navData parsing!";
}
}
else
{
LOG(WARNING) << "osnma_msg_receiver received an unknown object type!";
LOG(WARNING) << "Galileo OSNMA: osnma_msg_receiver received an unknown object type!";
}
}
catch (const wht::bad_any_cast& e)
{
LOG(WARNING) << "osnma_msg_receiver Bad any_cast: " << e.what();
LOG(WARNING) << "Galileo OSNMA: osnma_msg_receiver Bad any_cast: " << e.what();
}
// Send the resulting decoded NMA data (if available) to PVT
@ -155,7 +158,7 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
this->message_port_pub(pmt::mp("OSNMA_to_PVT"), pmt::make_any(osnma_data_ptr));
d_new_data = false;
// d_osnma_data = OSNMA_data();
DLOG(INFO) << "NMA info sent to the PVT block through the OSNMA_to_PVT async message port";
DLOG(INFO) << "Galileo OSNMA: NMA info sent to the PVT block through the OSNMA_to_PVT async message port";
}
}
@ -172,7 +175,9 @@ void osnma_msg_receiver::process_osnma_message(const std::shared_ptr<OSNMA_msg>&
read_dsm_block(osnma_msg);
process_dsm_block(osnma_msg); // will process dsm block if received a complete one, then will call mack processing upon re-setting the dsm block to 0
if (d_osnma_data.d_dsm_kroot_message.towh_k != 0)
local_time_verification(osnma_msg);
{
local_time_verification(osnma_msg);
}
read_and_process_mack_block(osnma_msg); // only process them if at least 3 available.
}
@ -203,8 +208,6 @@ void osnma_msg_receiver::read_dsm_header(uint8_t dsm_header)
{
d_osnma_data.d_dsm_header.dsm_id = d_dsm_reader->get_dsm_id(dsm_header);
d_osnma_data.d_dsm_header.dsm_block_id = d_dsm_reader->get_dsm_block_id(dsm_header); // BID
// LOG(INFO) << "OSNMA: DSM_ID=" << static_cast<uint32_t>(d_osnma_data.d_dsm_header.dsm_id);
// LOG(INFO) << "OSNMA: DSM_BID=" << static_cast<uint32_t>(d_osnma_data.d_dsm_header.dsm_block_id);
LOG(INFO) << "Galileo OSNMA: Received block DSM_BID=" << static_cast<uint32_t>(d_osnma_data.d_dsm_header.dsm_block_id)
<< " with DSM_ID " << static_cast<uint32_t>(d_osnma_data.d_dsm_header.dsm_id);
}
@ -246,7 +249,7 @@ void osnma_msg_receiver::read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_
}
d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = number_of_blocks;
LOG(INFO) << "OSNMA: number_of_blocks=" << static_cast<uint32_t>(number_of_blocks);
LOG(INFO) << "Galileo OSNMA: number of blocks in this message: " << static_cast<uint32_t>(number_of_blocks);
if (number_of_blocks == 0)
{
// Something is wrong, start over
@ -275,7 +278,7 @@ void osnma_msg_receiver::read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_
}
else
{
for (uint8_t k = 0; k < d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id]; k++)
for (uint16_t k = 0; k < d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id]; k++)
{
if (d_dsm_id_received[d_osnma_data.d_dsm_header.dsm_id][k] == 0)
{
@ -289,8 +292,10 @@ void osnma_msg_receiver::read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_
}
available_blocks << "]";
LOG(INFO) << available_blocks.str();
std::cout << available_blocks.str() << std::endl;
}
/**
* @brief Function to verify the local time based on GST_SIS and GST_0
*
@ -323,7 +328,7 @@ void osnma_msg_receiver::local_time_verification(const std::shared_ptr<OSNMA_msg
d_tags_allowed = tags_to_verify::all;
d_tags_to_verify = {0, 4, 12};
LOG(INFO) << "Galileo OSNMA: time constraint OK ( delta_T=" << delta_T << " s)";
// LOG(INFO) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
// LOG(INFO) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
// std::cout << "( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS)<< " | < " << static_cast<int>(d_T_L) << " ]" << std::endl;
// TODO set flag to false to avoid processing dsm and MACK messages
@ -334,7 +339,7 @@ void osnma_msg_receiver::local_time_verification(const std::shared_ptr<OSNMA_msg
d_tags_to_verify = {12};
LOG(WARNING) << "Galileo OSNMA: time constraint allows only slow MACs to be verified";
LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
LOG(WARNING) << "( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
LOG(WARNING) << "Galileo OSNMA: ( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
}
else
{
@ -342,7 +347,7 @@ void osnma_msg_receiver::local_time_verification(const std::shared_ptr<OSNMA_msg
d_tags_to_verify = {};
LOG(WARNING) << "Galileo OSNMA: time constraint violation";
LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
LOG(WARNING) << "( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
LOG(WARNING) << "Galileo OSNMA: ( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
}
}
@ -391,7 +396,7 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
if (d_osnma_data.d_dsm_header.dsm_id < 12)
{
// Parse Kroot message
LOG(INFO) << "OSNMA: DSM-KROOT message received.";
LOG(INFO) << "Galileo OSNMA: DSM-KROOT message received.";
d_osnma_data.d_dsm_kroot_message.nb_dk = d_dsm_reader->get_number_blocks_index(dsm_msg[0]);
d_osnma_data.d_dsm_kroot_message.pkid = d_dsm_reader->get_pkid(dsm_msg);
d_osnma_data.d_dsm_kroot_message.cidkr = d_dsm_reader->get_cidkr(dsm_msg);
@ -457,11 +462,11 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
std::vector<uint8_t> hash;
if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8.
{
hash = d_crypto->computeSHA256(MSG);
hash = d_crypto->compute_SHA_256(MSG);
}
else if (d_osnma_data.d_dsm_kroot_message.hf == 2)
{
hash = d_crypto->computeSHA3_256(MSG);
hash = d_crypto->compute_SHA3_256(MSG);
}
else
{
@ -483,7 +488,14 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
<< ", WN=" << static_cast<uint32_t>(d_osnma_data.d_dsm_kroot_message.wn_k)
<< ", TOW=" << static_cast<uint32_t>(d_osnma_data.d_dsm_kroot_message.towh_k) * 3600;
local_time_verification(osnma_msg);
d_kroot_verified = d_crypto->verify_signature(message, d_osnma_data.d_dsm_kroot_message.ds);
if(l_ds_bits == 512)
{
d_kroot_verified = d_crypto->verify_signature_ecdsa_p256(message, d_osnma_data.d_dsm_kroot_message.ds);
}
else if(l_ds_bits == 1056)
{
d_kroot_verified = d_crypto->verify_signature_ecdsa_p521(message, d_osnma_data.d_dsm_kroot_message.ds);
}
if (d_kroot_verified)
{
std::cout << "Galileo OSNMA: KROOT authentication successful!" << std::endl;
@ -495,6 +507,7 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
else
{
LOG(WARNING) << "Galileo OSNMA: KROOT authentication failed.";
std::cerr << "Galileo OSNMA: KROOT authentication failed." << std::endl;
}
}
else
@ -506,7 +519,7 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
}
else if (d_osnma_data.d_dsm_header.dsm_id >= 12 && d_osnma_data.d_dsm_header.dsm_id < 16)
{
LOG(WARNING) << "Galileo OSNMA: DSM-PKR message received.";
LOG(INFO) << "Galileo OSNMA: DSM-PKR message received.";
// Save DSM-PKR message
d_osnma_data.d_dsm_pkr_message.nb_dp = d_dsm_reader->get_number_blocks_index(dsm_msg[0]);
d_osnma_data.d_dsm_pkr_message.mid = d_dsm_reader->get_mid(dsm_msg);
@ -530,7 +543,7 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
uint32_t l_dp_bytes = dsm_msg.size();
if (d_osnma_data.d_dsm_pkr_message.npkt == 4)
{
LOG(WARNING) << "OSNMA: OAM received";
LOG(WARNING) << "Galileo OSNMA: OAM received";
l_npk_bytes = l_dp_bytes - 130; // bytes
}
@ -576,8 +589,8 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
else
{
// Reserved message?
LOG(WARNING) << "OSNMA Reserved message received";
// d_osnma_data = OSNMA_data();
LOG(WARNING) << "Galileo OSNMA: Reserved message received";
std::cerr << "Galileo OSNMA: Reserved message received" << std::endl;
}
d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = 0;
}
@ -883,15 +896,16 @@ void osnma_msg_receiver::process_mack_message()
{
if (d_kroot_verified == false && d_tesla_key_verified == false)
{
LOG(WARNING) << "Galileo OSNMA: MACK cannot be processed. "
<< ", "
<< "No Kroot nor TESLA key available";
LOG(WARNING) << "Galileo OSNMA: MACK cannot be processed, "
<< "no Kroot nor TESLA key available.";
if (!d_flag_debug)
{
return; // early return, cannot proceed further without one of the two verified. this equals to having Kroot but no TESLa key yet.
}
else
LOG(WARNING) << "But it will be processed for debugging purposes.";
{
LOG(WARNING) << "Galileo OSNMA: But it will be processed for debugging purposes.";
}
}
// verify tesla key and add it to the container of verified keys if successful
if (d_tesla_keys.find(d_osnma_data.d_nav_data.TOW_sf0) == d_tesla_keys.end()) // check if already available => no need to verify
@ -914,10 +928,9 @@ void osnma_msg_receiver::process_mack_message()
d_tags_awaiting_verify.insert(std::pair<uint32_t, Tag>(mack->TOW, tag0));
// bool ret = verify_macseq(*mack);
std::vector<MACK_tag_and_info> macseq_verified_tags = verify_macseq_new(*mack);
for (std::size_t i = 0; i < macseq_verified_tags.size(); ++i)
for (auto & tag_and_info : macseq_verified_tags)
{
// add tags of current mack to the verification queue
auto& tag_and_info = macseq_verified_tags[i];
Tag t(tag_and_info, mack->TOW, mack->WN, mack->PRNa, tag_and_info.counter);
d_tags_awaiting_verify.insert(std::pair<uint32_t, Tag>(mack->TOW, t));
LOG(INFO) << "Galileo OSNMA: Add Tag Id= "
@ -933,12 +946,13 @@ void osnma_msg_receiver::process_mack_message()
<< ", PRNd="
<< static_cast<unsigned>(t.PRN_d);
}
std::cout << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size() << std::endl;
LOG(INFO) << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size();
mack = d_macks_awaiting_MACSEQ_verification.erase(mack);
}
else
{ // key not yet available - keep in container until then -- might be deleted if container size exceeds max allowed
{
// key not yet available - keep in container until then -- might be deleted if container size exceeds max allowed
++mack;
}
}
@ -960,18 +974,24 @@ void osnma_msg_receiver::process_mack_message()
if (ret)
{
it.second.status = Tag::SUCCESS;
LOG(WARNING) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id= "
<< it.second.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< it.second.received_tag << std::dec
<< ", TOW="
<< it.second.TOW
<< ", ADKD="
<< static_cast<unsigned>(it.second.ADKD)
<< ", PRNa="
<< static_cast<unsigned>(it.second.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d);
LOG(INFO) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id="
<< it.second.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< it.second.received_tag << std::dec
<< ", TOW="
<< it.second.TOW
<< ", ADKD="
<< static_cast<unsigned>(it.second.ADKD)
<< ", PRNa="
<< static_cast<unsigned>(it.second.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d);
std::cout << "Galileo OSNMA: Tag verification :: SUCCESS for tag ADKD="
<< static_cast<unsigned>(it.second.ADKD)
<< ", PRNa="
<< static_cast<unsigned>(it.second.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d) << std::endl;
}
/* TODO notify PVT via pmt
* have_new_data() true
@ -980,7 +1000,7 @@ void osnma_msg_receiver::process_mack_message()
else
{
it.second.status = Tag::FAIL;
LOG(WARNING) << "Galileo OSNMA: Tag verification :: FAILURE for tag Id="
LOG(WARNING) << "Galileo OSNMA: Tag verification :: FAILURE for tag Id="
<< it.second.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< it.second.received_tag << std::dec
@ -992,6 +1012,12 @@ void osnma_msg_receiver::process_mack_message()
<< static_cast<unsigned>(it.second.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d);
std::cerr << "Galileo OSNMA: Tag verification :: FAILURE for tag ADKD="
<< static_cast<unsigned>(it.second.ADKD)
<< ", PRNa="
<< static_cast<unsigned>(it.second.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d) << std::endl;
}
}
else if (it.second.TOW > d_osnma_data.d_nav_data.TOW_sf0)
@ -1031,29 +1057,32 @@ void osnma_msg_receiver::process_mack_message()
* \pre DSM_PKR_message correctly filled in especially the 1024 intermediate tree nodes
* \returns true if computed merkle root matches received one, false otherwise
*/
bool osnma_msg_receiver::verify_dsm_pkr(DSM_PKR_message message)
bool osnma_msg_receiver::verify_dsm_pkr(const DSM_PKR_message& message) const
{
std::vector<uint8_t> computed_merkle_root; // x_4_0
std::vector<uint8_t> base_leaf = compute_base_leaf(message); // m_i
const auto base_leaf = get_merkle_tree_leaves(message); // m_i
const auto computed_merkle_root = compute_merkle_root(message, base_leaf); // x_4_0
const auto msg_id = static_cast<int>(message.mid);
LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: leaf provided for Message ID " << msg_id;
LOG(INFO) << "Galileo OSNMA: DSM-PKR :: leaf provided: m_" << static_cast<int>(message.mid);
computed_merkle_root = compute_merke_root(message, base_leaf);
if (computed_merkle_root == d_crypto->getMerkleRoot())
if (computed_merkle_root == d_crypto->get_merkle_root())
{
LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: SUCCESS!." << std::endl;
LOG(INFO) << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: SUCCESS.";
std::cout << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: SUCCESS." << std::endl;
return true;
}
else
{
LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: FAILURE." << std::endl;
LOG(WARNING) << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: FAILURE.";
std::cerr << "Galileo OSNMA: DSM-PKR verification for Message ID " << msg_id << " :: FAILURE." << std::endl;
return false;
}
}
std::vector<uint8_t> osnma_msg_receiver::compute_merke_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const
std::vector<uint8_t> osnma_msg_receiver::compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const
{
std::vector<uint8_t> x_next, x_current = d_crypto->computeSHA256(m_i);
std::vector<uint8_t> x_next;
std::vector<uint8_t> x_current = d_crypto->compute_SHA_256(m_i);
for (size_t i = 0; i < 4; i++)
{
x_next.clear();
@ -1073,16 +1102,20 @@ std::vector<uint8_t> osnma_msg_receiver::compute_merke_root(const DSM_PKR_messag
}
// Compute the next node.
x_current = d_crypto->computeSHA256(x_next);
x_current = d_crypto->compute_SHA_256(x_next);
}
return x_current;
}
std::vector<uint8_t> osnma_msg_receiver::compute_base_leaf(const DSM_PKR_message& dsm_pkr_message) const
{ // build base leaf m_i
std::vector<uint8_t> osnma_msg_receiver::get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const
{
// build base leaf m_i according to OSNMA SIS ICD v1.1, section 6.2 DSM-PKR Verification
std::vector<uint8_t> m_i;
m_i.reserve(2 + dsm_pkr_message.npk.size());
const size_t size_npk = dsm_pkr_message.npk.size();
m_i.reserve(1 + size_npk);
m_i.push_back((dsm_pkr_message.npkt << 4) + dsm_pkr_message.npktid);
for (uint8_t i = 0; i < dsm_pkr_message.npk.size(); i++)
for (size_t i = 0; i < size_npk; i++)
{
m_i.push_back(dsm_pkr_message.npk[i]);
}
@ -1090,13 +1123,13 @@ std::vector<uint8_t> osnma_msg_receiver::compute_base_leaf(const DSM_PKR_message
}
bool osnma_msg_receiver::verify_tag(Tag& tag)
bool osnma_msg_receiver::verify_tag(const Tag& tag) const
{
// Debug
// LOG(INFO) << "Galileo OSNMA: Tag verification :: Start for tag Id= "
// << tag.tag_id
// << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
// << tag.received_tag << std::dec;
// LOG(INFO) << "Galileo OSNMA: Tag verification :: Start for tag Id= "
// << tag.tag_id
// << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
// << tag.received_tag << std::dec;
// build message
std::vector<uint8_t> m = build_message(tag);
@ -1104,23 +1137,38 @@ bool osnma_msg_receiver::verify_tag(Tag& tag)
std::vector<uint8_t> applicable_key;
if (tag.ADKD == 0 || tag.ADKD == 4)
{
applicable_key = d_tesla_keys[tag.TOW + 30];
// LOG(INFO) << "|---> Galileo OSNMA :: applicable key: 0x" << d_helper->convert_to_hex_string(applicable_key) << "TOW="<<static_cast<int>(tag.TOW + 30);
const auto it = d_tesla_keys.find(tag.TOW + 30);
if(it != d_tesla_keys.cend())
{
applicable_key = it->second;
}
else
{
return false;
}
// LOG(INFO) << "|---> Galileo OSNMA :: applicable key: 0x" << d_helper->convert_to_hex_string(applicable_key) << "TOW="<<static_cast<int>(tag.TOW + 30);
}
else // ADKD 12
{
const auto it = d_tesla_keys.find(tag.TOW + 330);
if(it != d_tesla_keys.cend())
{
applicable_key = it->second;
}
else
{
return false;
}
// LOG(INFO) << "|---> Galileo OSNMA :: applicable key: 0x" << d_helper->convert_to_hex_string(applicable_key) << "TOW="<<static_cast<int>(tag.TOW + 330);
}
else // ADKD 12
{
applicable_key = d_tesla_keys[tag.TOW + 330];
// LOG(INFO) << "|---> Galileo OSNMA :: applicable key: 0x" << d_helper->convert_to_hex_string(applicable_key) << "TOW="<<static_cast<int>(tag.TOW + 330);
}
if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256
{
mac = d_crypto->computeHMAC_SHA_256(applicable_key, m);
mac = d_crypto->compute_HMAC_SHA_256(applicable_key, m);
}
else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES
{
mac = d_crypto->computeCMAC_AES(applicable_key, m);
mac = d_crypto->compute_CMAC_AES(applicable_key, m);
}
// truncate the computed mac: trunc(l_t, mac(K,m)) Eq. 23 ICD
@ -1164,7 +1212,7 @@ bool osnma_msg_receiver::verify_tag(Tag& tag)
// Compare computed tag with received one truncated
if (tag.received_tag == computed_mac)
{
std::cout << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id= "
LOG(INFO) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id="
<< tag.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< tag.received_tag << std::dec
@ -1175,6 +1223,14 @@ bool osnma_msg_receiver::verify_tag(Tag& tag)
<< ", PRNa="
<< static_cast<unsigned>(tag.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(tag.PRN_d);
std::cout << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id="
<< tag.tag_id
<< ", ADKD="
<< static_cast<unsigned>(tag.ADKD)
<< ", PRNa="
<< static_cast<unsigned>(tag.PRNa)
<< ", PRNd="
<< static_cast<unsigned>(tag.PRN_d) << std::endl;
return true;
}
@ -1182,11 +1238,13 @@ bool osnma_msg_receiver::verify_tag(Tag& tag)
}
std::vector<uint8_t> osnma_msg_receiver::build_message(const Tag& tag)
std::vector<uint8_t> osnma_msg_receiver::build_message(const Tag& tag) const
{
std::vector<uint8_t> m;
if (tag.CTR != 1)
m.push_back(static_cast<uint8_t>(tag.PRN_d));
{
m.push_back(static_cast<uint8_t>(tag.PRN_d));
}
m.push_back(static_cast<uint8_t>(tag.PRNa));
// TODO: maybe here I have to use d_receiver_time instead of d_GST_SIS which is what I am computing
uint32_t GST = d_helper->compute_gst(tag.WN, tag.TOW);
@ -1203,16 +1261,34 @@ std::vector<uint8_t> osnma_msg_receiver::build_message(const Tag& tag)
std::vector<uint8_t> applicable_nav_data_bytes;
if (tag.ADKD == 0 || tag.ADKD == 12) // note: for ADKD=12 still the same logic applies. Only the Key selection is shifted 10 Subframes into the future.
{
applicable_nav_data = d_satellite_nav_data[tag.PRN_d][tag.TOW - 30].ephemeris_iono_vector_2;
// LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data;
const auto it = d_satellite_nav_data.find(tag.PRN_d);
if (it != d_satellite_nav_data.cend())
{
const auto it2 = it->second.find(tag.TOW - 30);
if (it2 != it->second.cend())
{
applicable_nav_data = it2->second.ephemeris_iono_vector_2;
}
}
// LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data;
}
else if (tag.ADKD == 4)
{
applicable_nav_data = d_satellite_nav_data[tag.PRN_d][tag.TOW - 30].utc_vector_2;
// LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data;
const auto it = d_satellite_nav_data.find(tag.PRN_d);
if (it != d_satellite_nav_data.cend())
{
const auto it2 = it->second.find(tag.TOW - 30);
if (it2 != it->second.cend())
{
applicable_nav_data = it2->second.utc_vector_2;
}
}
// LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data;
}
else
LOG(WARNING) << "Galileo OSNMA :: Tag verification :: unknown ADKD";
{
LOG(WARNING) << "Galileo OSNMA: Tag verification :: unknown ADKD";
}
// convert std::string to vector<uint8_t>
applicable_nav_data_bytes = d_helper->bytes(applicable_nav_data);
@ -1283,10 +1359,10 @@ bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TO
uint32_t GST_SFi = d_receiver_time - 30; // GST of target key is to be used.
std::vector<uint8_t> hash;
const uint8_t lk_bytes = d_dsm_reader->get_lk_bits(d_osnma_data.d_dsm_kroot_message.ks) / 8;
// std::vector<uint8_t> validated_key;
std::vector<uint8_t> validated_key;
if (d_tesla_key_verified)
{ // have to go up to last verified key
d_validated_key = d_tesla_keys.rbegin()->second;
validated_key = d_tesla_keys.rbegin()->second;
num_of_hashes_needed = (d_receiver_time - d_last_verified_key_GST) / 30; // Eq. 19 ICD modified
LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) need to be performed up to closest verified TESLA key";
@ -1294,7 +1370,7 @@ bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TO
}
else
{ // have to go until Kroot
d_validated_key = d_osnma_data.d_dsm_kroot_message.kroot;
validated_key = d_osnma_data.d_dsm_kroot_message.kroot;
num_of_hashes_needed = (d_receiver_time - d_GST_0) / 30 + 1; // Eq. 19 IC
LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) need to be performed up to Kroot";
@ -1303,20 +1379,22 @@ bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TO
// truncate hash
std::vector<uint8_t> computed_key;
computed_key.reserve(key.size());
for (uint16_t i = 0; i < key.size(); i++)
for (size_t i = 0; i < key.size(); i++)
{
computed_key.push_back(hash[i]);
}
if (computed_key == d_validated_key && num_of_hashes_needed > 0)
if (computed_key == validated_key && num_of_hashes_needed > 0)
{
LOG(WARNING) << "Galileo OSNMA:: TESLA key verification :: SUCCESS!";
LOG(INFO) << "Galileo OSNMA: TESLA key verification :: SUCCESS!";
std::cout << "Galileo OSNMA: TESLA key verification :: SUCCESS!" << std::endl;
d_tesla_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(TOW, key));
d_tesla_key_verified = true;
d_last_verified_key_GST = d_receiver_time;
}
else if (num_of_hashes_needed > 0)
{
LOG(WARNING) << "Galileo OSNMA:: TESLA key verification :: FAILED";
LOG(WARNING) << "Galileo OSNMA: TESLA key verification :: FAILED";
std::cerr << "Galileo OSNMA: TESLA key verification :: FAILED" << std::endl;
if (d_flag_debug)
{
d_tesla_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(TOW, key));
@ -1375,9 +1453,11 @@ void osnma_msg_receiver::remove_verified_tags()
it = d_tags_awaiting_verify.erase(it);
}
else
++it;
{
++it;
}
}
std::cout << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size() << std::endl;
LOG(INFO) << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size();
}
@ -1394,11 +1474,11 @@ void osnma_msg_receiver::control_tags_awaiting_verify_size()
while (d_tags_awaiting_verify.size() > 500)
{
auto it = d_tags_awaiting_verify.begin();
LOG(WARNING) << "Galileo OSNMA: Tag verification :: DELETED tag due to exceeding buffer size. "
<< "Tag Id= " << it->second.tag_id
<< ", TOW=" << it->first
<< ", ADKD=" << static_cast<unsigned>(it->second.ADKD)
<< ", from satellite " << it->second.PRNa;
LOG(INFO) << "Galileo OSNMA: Tag verification :: DELETED tag due to exceeding buffer size. "
<< "Tag Id= " << it->second.tag_id
<< ", TOW=" << it->first
<< ", ADKD=" << static_cast<unsigned>(it->second.ADKD)
<< ", from satellite " << it->second.PRNa;
d_tags_awaiting_verify.erase(it);
}
}
@ -1446,7 +1526,7 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
std::vector<uint8_t> flxTags{};
std::string tempADKD;
// MACLT verification
for (uint8_t i = 0; i < mack.tag_and_info.size(); i++)
for (size_t i = 0; i < mack.tag_and_info.size(); i++)
{
tempADKD = applicable_sequence[i + 1];
if (tempADKD == "FLX")
@ -1463,7 +1543,7 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
if (flxTags.empty())
{
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD matches MAC Look-up table.";
LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD matches MAC Look-up table.";
return true;
}
// Fixed as well as FLX Tags share first part - Eq. 22 ICD
@ -1474,7 +1554,7 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
m[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
// Case tags flexible - Eq. 21 ICD
for (uint8_t i = 0; i < flxTags.size(); i++)
for (size_t i = 0; i < flxTags.size(); i++)
{
m[2 * i + 5] = mack.tag_and_info[flxTags[i]].tag_info.PRN_d;
m[2 * i + 6] = mack.tag_and_info[flxTags[i]].tag_info.ADKD << 4 |
@ -1484,11 +1564,11 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
std::vector<uint8_t> mac;
if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256
{
mac = d_crypto->computeHMAC_SHA_256(applicable_key, m);
mac = d_crypto->compute_HMAC_SHA_256(applicable_key, m);
}
else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES
{
mac = d_crypto->computeCMAC_AES(applicable_key, m);
mac = d_crypto->compute_CMAC_AES(applicable_key, m);
}
// Truncate the twelve MSBits and compare with received MACSEQ
uint16_t mac_msb = 0;
@ -1499,10 +1579,9 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4;
if (computed_macseq == mack.header.macseq)
{
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: FLX tags verification OK";
LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: FLX tags verification OK";
return true;
}
else
{
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed";
@ -1511,14 +1590,14 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
}
bool osnma_msg_receiver::tag_has_nav_data_available(Tag& t)
bool osnma_msg_receiver::tag_has_nav_data_available(const Tag& t) const
{
auto prn_it = d_satellite_nav_data.find(t.PRN_d);
if (prn_it != d_satellite_nav_data.end())
{
// PRN was found, check if TOW exists in inner map
//LOG(INFO) << "Galileo OSNMA: hasData = true " << std::endl;
std::map<uint32_t, NavData>& tow_map = prn_it->second;
std::map<uint32_t, NavData> tow_map = prn_it->second;
auto tow_it = tow_map.find(t.TOW - 30);
if (tow_it != tow_map.end())
{
@ -1540,7 +1619,7 @@ bool osnma_msg_receiver::tag_has_nav_data_available(Tag& t)
}
bool osnma_msg_receiver::tag_has_key_available(Tag& t)
bool osnma_msg_receiver::tag_has_key_available(const Tag& t) const
{
// check adkd of tag
// if adkd = 0 or 4 => look for d_tesla_keys[t.TOW+30]
@ -1570,9 +1649,8 @@ bool osnma_msg_receiver::tag_has_key_available(Tag& t)
}
std::vector<uint8_t> osnma_msg_receiver::hash_chain(uint32_t num_of_hashes_needed, std::vector<uint8_t> key, uint32_t GST_SFi, const uint8_t lk_bytes)
std::vector<uint8_t> osnma_msg_receiver::hash_chain(uint32_t num_of_hashes_needed, const std::vector<uint8_t>& key, uint32_t GST_SFi, const uint8_t lk_bytes) const
{
auto start = std::chrono::high_resolution_clock::now();
std::vector<uint8_t> K_II = key;
std::vector<uint8_t> K_I; // result of the recursive hash operations
std::vector<uint8_t> msg;
@ -1598,11 +1676,11 @@ std::vector<uint8_t> osnma_msg_receiver::hash_chain(uint32_t num_of_hashes_neede
std::vector<uint8_t> hash;
if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8.
{
hash = d_crypto->computeSHA256(msg);
hash = d_crypto->compute_SHA_256(msg);
}
else if (d_osnma_data.d_dsm_kroot_message.hf == 2)
{
hash = d_crypto->computeSHA3_256(msg);
hash = d_crypto->compute_SHA3_256(msg);
}
else
{
@ -1624,20 +1702,26 @@ std::vector<uint8_t> osnma_msg_receiver::hash_chain(uint32_t num_of_hashes_neede
// check that the final time matches the Kroot time
bool check;
if (!d_tesla_key_verified)
check = GST_SFi + 30 == d_GST_0 - 30;
{
check = GST_SFi + 30 == d_GST_0 - 30;
}
else
check = GST_SFi + 30 == d_last_verified_key_GST;
{
check = GST_SFi + 30 == d_last_verified_key_GST;
}
if (!check)
LOG(WARNING) << "Galileo OSNMA: TESLA verification error. Kroot time mismatch!"; // ICD. Eq. 18
{
LOG(WARNING) << "Galileo OSNMA: TESLA key chain verification error: KROOT time mismatch!"; // ICD. Eq. 18
std::cerr << "Galileo OSNMA: TESLA key chain verification error: KROOT time mismatch!" << std::endl;
}
else
LOG(INFO) << "Galileo OSNMA: TESLA verification. Kroot time matches!"; // ICD. Eq. 18
// compare computed current key against received key
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
// LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) took " << elapsed.count() << " seconds.";
{
LOG(INFO) << "Galileo OSNMA: TESLA key chain verification: KROOT time matches."; // ICD. Eq. 18
}
return K_II;
}
/**
* @brief Verifies the MAC sequence of a received MACK message.
*
@ -1650,11 +1734,16 @@ std::vector<uint8_t> osnma_msg_receiver::hash_chain(uint32_t num_of_hashes_neede
*/
std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_message& mack)
{
std::vector<MACK_tag_and_info> verified_tags {};
std::vector<MACK_tag_and_info> verified_tags{};
// MACSEQ verification
d_GST_Sf = d_receiver_time - 30; // time of the start of SF containing MACSEQ // TODO buffer with times? since out of debug not every 30 s a Sf is necessarily received..
std::vector<uint8_t> applicable_key = d_tesla_keys[mack.TOW + 30]; // current tesla key ie transmitted in the next subframe
d_GST_Sf = d_receiver_time - 30; // time of the start of SF containing MACSEQ // TODO buffer with times? since out of debug not every 30 s a Sf is necessarily received.
std::vector<uint8_t> applicable_key;
const auto key_it = d_tesla_keys.find(mack.TOW + 30); // current tesla key ie transmitted in the next subframe
if (key_it != d_tesla_keys.cend())
{
applicable_key = key_it->second;
}
std::vector<std::string> sq1{};
std::vector<std::string> sq2{};
std::vector<std::string> applicable_sequence;
@ -1682,7 +1771,7 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
std::vector<uint8_t> flxTags{};
std::string tempADKD;
// MACLT verification
for (uint8_t i = 0; i < mack.tag_and_info.size(); i++)
for (size_t i = 0; i < mack.tag_and_info.size(); i++)
{
tempADKD = applicable_sequence[i + 1];
if (tempADKD == "FLX")
@ -1692,23 +1781,23 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
else if (mack.tag_and_info[i].tag_info.ADKD == std::stoi(applicable_sequence[i + 1]))
{
// fill index of tags failed
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD match against MAC Look-up table for "
"Tag=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec;
LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD match against MAC Look-up table for Tag=0x"
<< std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec;
verified_tags.push_back(mack.tag_and_info[i]);
}
else
{
// discard tag
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table for "
"Tag=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec;
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table for Tag=0x"
<< std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec;
}
}
if (flxTags.empty() /*TODO add check d_flag_check_mackseq_fixed_tags*/)
{
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: No FLX tags to verify.";
LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: No FLX tags to verify.";
return verified_tags;
}
// Fixed as well as FLX Tags share first part - Eq. 22 ICD
@ -1719,7 +1808,7 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
m[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
// Case tags flexible - Eq. 21 ICD
for (uint8_t i = 0; i < flxTags.size(); i++)
for (size_t i = 0; i < flxTags.size(); i++)
{
m[2 * i + 5] = mack.tag_and_info[flxTags[i]].tag_info.PRN_d;
m[2 * i + 6] = mack.tag_and_info[flxTags[i]].tag_info.ADKD << 4 |
@ -1729,11 +1818,11 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
std::vector<uint8_t> mac;
if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256
{
mac = d_crypto->computeHMAC_SHA_256(applicable_key, m);
mac = d_crypto->compute_HMAC_SHA_256(applicable_key, m);
}
else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES
{
mac = d_crypto->computeCMAC_AES(applicable_key, m);
mac = d_crypto->compute_CMAC_AES(applicable_key, m);
}
// Truncate the twelve MSBits and compare with received MACSEQ
uint16_t mac_msb = 0;
@ -1744,10 +1833,10 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4;
if (computed_macseq == mack.header.macseq)
{
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: FLX tags verification OK";
for (uint8_t i = 0; i < flxTags.size(); i++)
LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: FLX tags verification OK";
for (uint8_t flxTag : flxTags)
{
verified_tags.push_back(mack.tag_and_info[flxTags[i]]);
verified_tags.push_back(mack.tag_and_info[flxTag]);
}
return verified_tags;
}
@ -1757,5 +1846,4 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed";
return verified_tags;
}
}

View File

@ -3,14 +3,15 @@
* \brief GNU Radio block that processes Galileo OSNMA data received from
* Galileo E1B telemetry blocks. After successful decoding, sends the content to
* the PVT block.
* \author Carles Fernandez-Prades, 2023. cfernandez(at)cttc.es
* \author Carles Fernandez-Prades, 2023-2024. cfernandez(at)cttc.es
* Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)
* Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
@ -18,20 +19,23 @@
#ifndef GNSS_SDR_OSNMA_MSG_RECEIVER_H
#define GNSS_SDR_OSNMA_MSG_RECEIVER_H
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test
#include "galileo_inav_message.h" // for OSNMA_msg
#include "gnss_block_interface.h" // for gnss_shared_ptr
#include "gnss_sdr_make_unique.h" // for std::make:unique in C++11
#include "osnma_data.h" // for OSNMA_data
#include <boost/circular_buffer.hpp>
#include <gnuradio/block.h> // for gr::block
#include <pmt/pmt.h> // for pmt::pmt_t
#include <array> // for std::array
#include <memory> // for std::shared_ptr
#include <string>
#include <vector>
#include "osnma_data.h" // for OSNMA_data structures
#include <gnuradio/block.h> // for gr::block
#include <pmt/pmt.h> // for pmt::pmt_t
#include <array> // for std::array
#include <cstdint> // for uint8_t
#include <ctime> // for std::time_t
#include <map> // for std::map, std::multimap
#include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector
/** \addtogroup Core
* \{ */
@ -73,58 +77,69 @@ private:
void read_mack_header();
void read_mack_body();
void process_mack_message();
void add_satellite_data(uint32_t SV_ID, uint32_t TOW, const NavData &data);
void add_satellite_data(uint32_t SV_ID, uint32_t TOW, const NavData& data);
void remove_verified_tags();
void control_tags_awaiting_verify_size();
std::vector<uint8_t> build_message(const Tag& tag);
std::vector<uint8_t> hash_chain(uint32_t num_of_hashes_needed, std::vector<uint8_t> key, uint32_t GST_SFi, const uint8_t lk_bytes);
std::vector<uint8_t> compute_base_leaf(const DSM_PKR_message& dsm_pkr_message) const;
std::vector<uint8_t> compute_merke_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const;
std::vector<MACK_tag_and_info> verify_macseq_new(const MACK_message& mack);
void display_data();
bool verify_tag(MACK_tag_and_info tag_and_info, OSNMA_data applicable_OSNMA, uint8_t tag_position, const std::vector<uint8_t>& applicable_key, NavData applicable_NavData);
bool verify_tesla_key(std::vector<uint8_t>& key, uint32_t TOW);
bool verify_tag(Tag& tag);
bool is_next_subframe();
bool tag_has_nav_data_available(Tag& t);
bool tag_has_key_available(Tag& t);
bool verify_tag(const Tag& tag) const;
bool tag_has_nav_data_available(const Tag& t) const;
bool tag_has_key_available(const Tag& t) const;
bool verify_macseq(const MACK_message& mack);
bool verify_dsm_pkr(DSM_PKR_message message);
bool verify_dsm_pkr(const DSM_PKR_message& message) const;
enum tags_to_verify{all,utc,slow_eph, eph, none};
tags_to_verify d_tags_allowed{tags_to_verify::all};
std::map<uint32_t, std::map<uint32_t, NavData>> d_satellite_nav_data; // map holding NavData sorted by SVID (first key) and TOW (second key).
std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys; // tesla keys over time, sorted by TOW
std::vector<uint8_t> get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const;
std::vector<uint8_t> compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const;
std::vector<uint8_t> build_message(const Tag& tag) const;
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;
std::vector<MACK_tag_and_info> verify_macseq_new(const MACK_message& mack);
std::map<uint32_t, std::map<uint32_t, NavData>> d_satellite_nav_data; // map holding NavData sorted by SVID (first key) and TOW (second key).
std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys; // tesla keys over time, sorted by TOW
std::multimap<uint32_t, Tag> d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW
std::vector<uint8_t> d_tags_to_verify{0, 4, 12};
std::vector<MACK_message> d_macks_awaiting_MACSEQ_verification;
std::multimap<uint32_t, Tag> d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions
std::unique_ptr<Osnma_Helper> d_helper;
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.
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.
std::array<std::array<uint8_t, 16>, 16> d_dsm_id_received{};
std::array<uint16_t, 16> d_number_of_blocks{};
std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions
std::unique_ptr<Osnma_Helper> d_helper;
OSNMA_data d_osnma_data{};
enum tags_to_verify
{
all,
utc,
slow_eph,
eph,
none
};
tags_to_verify d_tags_allowed{tags_to_verify::all};
std::time_t d_receiver_time{0};
uint32_t d_GST_Sf{}; // C: used for MACSEQ and Tesla Key verification TODO need really to be global var?
uint32_t d_last_verified_key_GST{0};
uint32_t d_GST_0{};
uint32_t d_GST_SIS{};
uint8_t d_Lt_min{}; // minimum equivalent tag length
uint8_t d_Lt_verified_eph{0}; // verified tag bits - ephemeris
uint8_t d_Lt_verified_utc{0}; // verified tag bits - timing
uint8_t const d_T_L{30}; // s RG Section 2.1
uint8_t const d_delta_COP{30}; // s SIS ICD Table 14
bool d_new_data{false};
bool d_public_key_verified{false};
bool d_kroot_verified{false};
bool d_tesla_key_verified{false};
bool d_flag_debug{false};
uint32_t d_GST_Sf {}; // C: used for MACSEQ and Tesla Key verification TODO need really to be global var?
uint32_t d_last_verified_key_GST{0};
uint32_t d_GST_0 {};
uint32_t d_GST_SIS {};
std::time_t d_receiver_time {0};
uint8_t d_Lt_min {}; // minimum equivalent tag length
uint8_t d_Lt_verified_eph {0}; // verified tag bits - ephemeris
uint8_t d_Lt_verified_utc {0}; // verified tag bits - timing
uint8_t const d_T_L{30}; // s RG Section 2.1
uint8_t const d_delta_COP{30}; // s SIS ICD Table 14
std::vector<uint8_t> d_tags_to_verify{0,4,12};
std::vector<uint8_t> d_validated_key{};
// Provide access to inner functions to Gtest
FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification);

View File

@ -353,7 +353,7 @@ int32_t Beidou_Dnav_Navigation_Message::d1_subframe_decoder(std::string const& s
d_DeltaT_LSF = static_cast<double>(read_navigation_signed(subframe_bits, D1_DELTA_T_LSF));
i_WN_LSF = static_cast<double>(read_navigation_signed(subframe_bits, D1_WN_LSF));
d_A0UTC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A0UTC));
d_A0UTC = d_A0GPS * D1_A0GPS_LSB;
d_A0UTC = d_A0UTC * D1_A0UTC_LSB;
d_A1UTC = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1UTC));
d_A1UTC = d_A1UTC * D1_A1UTC_LSB;

File diff suppressed because it is too large Load Diff

View File

@ -34,31 +34,43 @@
/** \addtogroup System_Parameters
* \{ */
/*!
* \brief Class implementing cryptographic functions
* for Navigation Message Authentication
*/
class Gnss_Crypto
{
public:
Gnss_Crypto();
Gnss_Crypto(); //!< Default constructor
/*!
* Constructor with a .crt or .pem file for the ECDSA Public Key
* and a XML file for the Merkle Tree root.
* Files can be downloaded by registering at https://www.gsc-europa.eu/
*/
Gnss_Crypto(const std::string& certFilePath, const std::string& merkleTreePath);
~Gnss_Crypto();
~Gnss_Crypto(); //!< Default destructor
void set_public_key(const std::vector<uint8_t>& publickey);
bool have_public_key() const;
bool verify_signature(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const;
bool have_public_key() const; //!< Returns true if the ECDSA Public Key is already loaded
/*!
* Stores the ECDSA Public Key in a .pem file, which is read in a following run if the .crt file is not found
*/
bool store_public_key(const std::string& pubKeyFilePath) const;
std::vector<uint8_t> getPublicKey() const;
std::vector<uint8_t> computeSHA256(const std::vector<uint8_t>& input) const;
std::vector<uint8_t> computeSHA3_256(const std::vector<uint8_t>& input) const;
std::vector<uint8_t> computeHMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const;
std::vector<uint8_t> computeCMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const;
inline std::vector<uint8_t> getMerkleRoot() const
{
return d_x_4_0;
}
inline void setMerkleRoot(const std::vector<uint8_t>& v)
{
d_x_4_0 = v;
}
bool verify_signature_ecdsa_p256(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const; //!< Verify ECDSA-P256 signature (message in plain hex, signature in raw format)
bool verify_signature_ecdsa_p521(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const; //!< Verify ECDSA-P521 signature (message in plain hex, signature in raw format)
std::vector<uint8_t> compute_SHA_256(const std::vector<uint8_t>& input) const; //!< Computes SHA-256 hash
std::vector<uint8_t> compute_SHA3_256(const std::vector<uint8_t>& input) const; //!< Computes SHA3-256 hash
std::vector<uint8_t> compute_HMAC_SHA_256(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const; //!< Computes HMAC-SHA-256 message authentication code
std::vector<uint8_t> compute_CMAC_AES(const std::vector<uint8_t>& key, const std::vector<uint8_t>& input) const; //!< Computes CMAC-AES message authentication code
std::vector<uint8_t> get_public_key() const; //!< Gets the ECDSA Public Key in PEM format
std::vector<uint8_t> get_merkle_root() const; //!< Gets the Merkle Tree root node (\f$ x_{4,0} \f$)
void set_public_key(const std::vector<uint8_t>& publickey); //!< Sets the ECDSA Public Key (publickey in PEM format)
void set_merkle_root(const std::vector<uint8_t>& v); //!< Sets the Merkle Tree root node x(\f$ x_{4,0} \f$)
private:
void read_merkle_xml(const std::string& merkleFilePath);
@ -79,10 +91,6 @@ private:
#endif
#endif
std::vector<uint8_t> d_x_4_0;
std::vector<uint8_t> d_x_3_1;
std::vector<uint8_t> d_x_2_1;
std::vector<uint8_t> d_x_1_1;
std::vector<uint8_t> d_x_0_1;
};
/** \} */

View File

@ -82,7 +82,7 @@ class DSM_PKR_message
public:
DSM_PKR_message() = default;
std::array<uint8_t, 128> itn; // bitset<1024>
std::array<uint8_t, 128> itn{}; // bitset<1024>
std::vector<uint8_t> npk;
std::vector<uint8_t> p_dp;
uint8_t nb_dp{};

View File

@ -1,17 +1,17 @@
/*!
* \file osnma_helper.h
* \brief Class for auxiliary osnma functions
* \author Carles Fernandez-Prades, 2024 cfernandez(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
* \file osnma_helper.h
* \brief Class for auxiliary osnma functions
* \author Carles Fernandez-Prades, 2024 cfernandez(at)cttc.es
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "osnma_helper.h"
@ -26,6 +26,7 @@ uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const
return GST;
}
std::vector<uint8_t> Osnma_Helper::gst_to_uint8(uint32_t GST) const
{
std::vector<uint8_t> res;
@ -37,6 +38,7 @@ std::vector<uint8_t> Osnma_Helper::gst_to_uint8(uint32_t GST) const
return res;
}
/**
* @brief Convert a binary string to a vector of bytes.
*
@ -47,7 +49,8 @@ std::vector<uint8_t> Osnma_Helper::gst_to_uint8(uint32_t GST) const
* @param binaryString The binary string to be converted.
* @return The vector of bytes converted from the binary string.
*/
std::vector<uint8_t> Osnma_Helper::bytes(const std::string& binaryString) const {
std::vector<uint8_t> Osnma_Helper::bytes(const std::string& binaryString) const
{
std::vector<uint8_t> bytes;
// Determine the size of the padding needed.
@ -55,12 +58,14 @@ std::vector<uint8_t> Osnma_Helper::bytes(const std::string& binaryString) const
std::string padded_binary = binaryString;
if (padding_size != 0) {
padding_size = 8 - padding_size; // Compute padding size
if (padding_size != 0)
{
padding_size = 8 - padding_size; // Compute padding size
padded_binary.append(padding_size, '0'); // Append zeros to the binary string
}
for (size_t i = 0; i < padded_binary.size(); i += 8) {
for (size_t i = 0; i < padded_binary.size(); i += 8)
{
uint8_t byte = std::bitset<8>(padded_binary.substr(i, 8)).to_ulong();
bytes.push_back(byte);
}
@ -68,37 +73,49 @@ std::vector<uint8_t> Osnma_Helper::bytes(const std::string& binaryString) const
return bytes;
}
std::string Osnma_Helper::verification_status_str(const int& status) const
std::string Osnma_Helper::verification_status_str(int status) const
{
switch (status) {
case 0: return "SUCCESS";
case 1: return "FAIL";
case 2: return "UNVERIFIED";
default: return "UNKNOWN";
}
switch (status)
{
case 0:
return "SUCCESS";
case 1:
return "FAIL";
case 2:
return "UNVERIFIED";
default:
return "UNKNOWN";
}
}
std::string Osnma_Helper::convert_to_hex_string(const std::vector<uint8_t>& vector) const
{
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (auto byte : vector) {
for (auto byte : vector)
{
ss << std::setw(2) << static_cast<int>(byte);
}
return ss.str();
}
std::vector<uint8_t> Osnma_Helper::convert_from_hex_string(const std::string& hex_string) const
{
std::vector<uint8_t> result;
std::string adjusted_hex_string = hex_string;
if (hex_string.length() % 2 != 0) {
if (hex_string.length() % 2 != 0)
{
adjusted_hex_string = "0" + hex_string;
}
for (std::size_t i = 0; i < adjusted_hex_string.length(); i += 2) {
for (std::size_t i = 0; i < adjusted_hex_string.length(); i += 2)
{
std::string byte_string = adjusted_hex_string.substr(i, 2);
uint8_t byte = static_cast<uint8_t>(std::stoul(byte_string, nullptr, 16));
auto byte = static_cast<uint8_t>(std::stoul(byte_string, nullptr, 16));
result.push_back(byte);
}

View File

@ -29,7 +29,7 @@ public:
uint32_t compute_gst(uint32_t WN, uint32_t TOW) const;
std::vector<uint8_t> gst_to_uint8(uint32_t GST) const;
std::vector<uint8_t> bytes(const std::string& binaryString) const;
std::string verification_status_str(const int& status) const;
std::string verification_status_str(int status) const;
std::string convert_to_hex_string(const std::vector<uint8_t>& vector) const ;
std::vector<uint8_t> convert_from_hex_string(const std::string& hex_string) const; // TODO remove similar function in gnss_crypto
};

View File

@ -26,7 +26,8 @@ if(ENABLE_GLOG_AND_GFLAGS)
target_link_libraries(gnss-sdr PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gnss-sdr PUBLIC -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(gnss-sdr PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize absl::log_sink absl::log_sink_registry)
target_link_libraries(gnss-sdr PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize absl::log_sink absl::log_sink_registry)
target_link_libraries(gnss-sdr INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
if(NOT ENABLE_LOG)

View File

@ -624,7 +624,8 @@ if(ENABLE_UNIT_TESTING)
target_link_libraries(run_tests PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(run_tests PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(run_tests PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(run_tests PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(run_tests INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
target_include_directories(run_tests
INTERFACE
@ -774,7 +775,8 @@ if(ENABLE_FPGA)
target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(gps_l1_ca_dll_pll_tracking_test_fpga INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
target_include_directories(gps_l1_ca_dll_pll_tracking_test_fpga
INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files
@ -815,6 +817,9 @@ function(add_system_test executable)
INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files
)
target_link_libraries(${executable} PRIVATE ${OPT_LIBS_} algorithms_libs)
if(NOT ENABLE_GLOG_AND_GFLAGS)
target_link_libraries(${executable} INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
if(GNURADIO_USES_STD_POINTERS)
target_compile_definitions(${executable}
PRIVATE -DGNURADIO_USES_STD_POINTERS=1
@ -873,7 +878,7 @@ if(ENABLE_SYSTEM_TESTING)
if(ENABLE_GLOG_AND_GFLAGS)
set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog)
else()
set(OPT_LIBS_ ${OPT_LIBS_} absl::flags_parse absl::flags absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize absl::log_sink absl::log_sink_registry)
set(OPT_LIBS_ ${OPT_LIBS_} absl::flags_parse absl::flags absl::log absl::log_initialize absl::log_sink absl::log_sink_registry)
endif()
if(NOT ENABLE_PACKAGING)
add_system_test(ttff
@ -897,7 +902,7 @@ if(ENABLE_SYSTEM_TESTING)
if(ENABLE_GLOG_AND_GFLAGS)
set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog)
else()
set(OPT_LIBS_ ${OPT_LIBS_} absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize absl::log_sink absl::log_sink_registry)
set(OPT_LIBS_ ${OPT_LIBS_} absl::flags_parse absl::log absl::log_initialize absl::log_sink absl::log_sink_registry)
endif()
add_system_test(position_test
CMAKE_ARGS -DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
@ -970,7 +975,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(flowgraph_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(flowgraph_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(flowgraph_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(flowgraph_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(flowgraph_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
target_include_directories(flowgraph_test
@ -1027,7 +1033,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(gnss_block_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gnss_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(gnss_block_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(gnss_block_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(gnss_block_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
target_include_directories(gnss_block_test
@ -1079,7 +1086,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(gnuradio_block_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gnuradio_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(gnuradio_block_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(gnuradio_block_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(gnuradio_block_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
xcode_remove_warning_duplicates(gnuradio_block_test)
@ -1115,7 +1123,8 @@ if(ENABLE_GLOG_AND_GFLAGS)
target_link_libraries(matio_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(matio_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(matio_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(matio_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(matio_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
target_include_directories(matio_test
@ -1165,7 +1174,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(acq_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(acq_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(acq_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(acq_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(acq_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
target_include_directories(acq_test
INTERFACE
@ -1251,7 +1261,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(trk_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(trk_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(trk_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(trk_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(trk_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
if(USE_GENERIC_LAMBDAS)
set(has_generic_lambdas HAS_GENERIC_LAMBDA=1)
@ -1314,7 +1325,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(control_thread_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(control_thread_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(control_thread_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(control_thread_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(control_thread_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
xcode_remove_warning_duplicates(control_thread_test)
@ -1375,7 +1387,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(osnma_msg_receiver_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(osnma_msg_receiver_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else()
target_link_libraries(osnma_msg_receiver_test PRIVATE absl::flags absl::flags_parse absl::log $<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags> absl::log_initialize)
target_link_libraries(osnma_msg_receiver_test PRIVATE absl::flags absl::flags_parse absl::log absl::log_initialize)
target_link_libraries(osnma_msg_receiver_test INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,absl::log_flags>")
endif()
xcode_remove_warning_duplicates(osnma_msg_receiver_test) # TODO - unsure if needed

View File

@ -1,3 +1,21 @@
/*!
* \file gnss_crypto_test.cc
* \brief Tests for the Gnss_Crypto class.
* \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es
* Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de
*
*
* -----------------------------------------------------------------------------
*
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR.
*
* Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* -----------------------------------------------------------------------------
*/
#include "gnss_crypto.h"
#include "gnss_sdr_filesystem.h"
#include "gnss_sdr_make_unique.h"
@ -10,74 +28,26 @@ class GnssCryptoTest : public ::testing::Test
};
TEST(GnssCryptoTest, TestComputeSHA_256)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world
std::vector<uint8_t> expected_output = {
0x18, 0x94, 0xA1, 0x9C, 0x85, 0xBA, 0x15, 0x3A, 0xCB, 0xF7,
0x43, 0xAC, 0x4E, 0x43, 0xFC, 0x00, 0x4C, 0x89, 0x16, 0x04, 0xB2,
0x6F, 0x8C, 0x69, 0xE1, 0xE8, 0x3E, 0xA2, 0xAF, 0xC7, 0xC4, 0x8F};
std::vector<uint8_t> output = d_crypto->computeSHA256(message);
ASSERT_EQ(expected_output, output);
}
TEST(GnssCryptoTest, TestComputeSHA3_256)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world
std::vector<uint8_t> expected_output = {
0xCC, 0xB8, 0xF9, 0x23, 0x5F, 0x4A, 0x93, 0x2C, 0xA0, 0xAB,
0xBB, 0x2C, 0x24, 0x36, 0x72, 0x5E, 0x2E, 0x8D, 0xC7, 0x5B,
0x99, 0xE7, 0xF6, 0xC4, 0x50, 0x5B, 0x2A, 0x93, 0x6E, 0xB6, 0x3B, 0x3F};
std::vector<uint8_t> output = d_crypto->computeSHA3_256(message);
ASSERT_EQ(expected_output, output);
}
TEST(GnssCryptoTest, VerifySignature)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
// RG example - import crt certificate - result: FAIL
std::vector<uint8_t> message = {0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF};
std::vector<uint8_t> signature = {0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, 0x28, 0xC1, 0x77, 0xFB};
std::vector<uint8_t> publicKey{// PEM format - 1000 bits
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,
0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49,
0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37,
0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D,
0x0A,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A};
d_crypto->set_public_key(publicKey);
bool result = d_crypto->verify_signature(message, signature);
ASSERT_TRUE(result);
}
TEST(GnssCryptoTest, VerifyPubKeyImport)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> publicKey{// PEM
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,
0x4D, 0x46,
0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63,
0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76, 0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72, 0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E,
0x73, 0x66, 0x78, 0x2F, 0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D, 0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30,
0x48, 0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74, 0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B, 0x69, 0x79,
0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x0A};
// PEM format
std::vector<uint8_t> publicKey = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55,
0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49,
0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A,
0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76,
0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72,
0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, 0x73, 0x66, 0x78, 0x2F,
0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D,
0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30, 0x48,
0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74,
0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B,
0x69, 0x79, 0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20,
0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A};
d_crypto->set_public_key(publicKey);
@ -92,14 +62,22 @@ TEST(GnssCryptoTest, VerifyPublicKeyStorage)
const std::string f1("./osnma_test_file1.pem");
const std::string f2("./osnma_test_file2.pem");
std::vector<uint8_t> publicKey{
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A,
0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49,
0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B,
0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37,
0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F,
0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A};
// PEM format
std::vector<uint8_t> publicKey = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55,
0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49,
0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A,
0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76,
0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72,
0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, 0x73, 0x66, 0x78, 0x2F,
0x0A, 0x4D, 0x56, 0x6F, 0x71, 0x47, 0x61, 0x35, 0x4F, 0x31, 0x73, 0x75, 0x6D,
0x57, 0x64, 0x61, 0x5A, 0x66, 0x4F, 0x69, 0x39, 0x48, 0x30, 0x4D, 0x30, 0x48,
0x46, 0x6E, 0x5A, 0x32, 0x63, 0x72, 0x44, 0x37, 0x6C, 0x6A, 0x6C, 0x36, 0x74,
0x4E, 0x56, 0x52, 0x4F, 0x71, 0x4A, 0x63, 0x57, 0x58, 0x51, 0x6B, 0x6E, 0x4B,
0x69, 0x79, 0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20,
0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A};
d_crypto->set_public_key(publicKey);
bool result = d_crypto->store_public_key(f1);
@ -118,7 +96,7 @@ TEST(GnssCryptoTest, VerifyPublicKeyStorage)
ASSERT_EQ(content_file, content_file2);
std::vector<uint8_t> readkey = d_crypto2->getPublicKey();
std::vector<uint8_t> readkey = d_crypto2->get_public_key();
ASSERT_EQ(publicKey, readkey);
errorlib::error_code ec;
@ -127,6 +105,40 @@ TEST(GnssCryptoTest, VerifyPublicKeyStorage)
}
TEST(GnssCryptoTest, TestComputeSHA_256)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> message{
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world
std::vector<uint8_t> expected_output = {
0x18, 0x94, 0xA1, 0x9C, 0x85, 0xBA, 0x15, 0x3A, 0xCB, 0xF7,
0x43, 0xAC, 0x4E, 0x43, 0xFC, 0x00, 0x4C, 0x89, 0x16, 0x04, 0xB2,
0x6F, 0x8C, 0x69, 0xE1, 0xE8, 0x3E, 0xA2, 0xAF, 0xC7, 0xC4, 0x8F};
std::vector<uint8_t> output = d_crypto->compute_SHA_256(message);
ASSERT_EQ(expected_output, output);
}
TEST(GnssCryptoTest, TestComputeSHA3_256)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> message{
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world
std::vector<uint8_t> expected_output = {
0xCC, 0xB8, 0xF9, 0x23, 0x5F, 0x4A, 0x93, 0x2C, 0xA0, 0xAB,
0xBB, 0x2C, 0x24, 0x36, 0x72, 0x5E, 0x2E, 0x8D, 0xC7, 0x5B,
0x99, 0xE7, 0xF6, 0xC4, 0x50, 0x5B, 0x2A, 0x93, 0x6E, 0xB6, 0x3B, 0x3F};
std::vector<uint8_t> output = d_crypto->compute_SHA3_256(message);
ASSERT_EQ(expected_output, output);
}
// Unit test for computeHMAC_SHA_256 function.
TEST(GnssCryptoTest, TestComputeHMACSHA256)
{
@ -138,14 +150,16 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256)
0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3,
0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA};
std::vector<uint8_t> message{0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world con 0x0A
std::vector<uint8_t> message{
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; // Hello world
std::vector<uint8_t> expected_output = {
0xC3, 0x51, 0xF6, 0xFD, 0xDD, 0xC9, 0x8B, 0x41,
0xD6, 0xF4, 0x77, 0x6D, 0xAC, 0xE8, 0xE0, 0x14,
0xB2, 0x7A, 0xCC, 0x22, 0x00, 0xAA, 0xD2, 0x37,
0xD0, 0x79, 0x06, 0x12, 0x83, 0x40, 0xB7, 0xA6};
std::vector<uint8_t> output = d_crypto->computeHMAC_SHA_256(key, message);
std::vector<uint8_t> output = d_crypto->compute_HMAC_SHA_256(key, message);
ASSERT_EQ(expected_output, output);
}
@ -156,23 +170,31 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_m0)
// key and message generated from RG A.6.5.1
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> key = {// RG K4 @ 345690
// RG K4 @ 345690
std::vector<uint8_t> key = {
0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6,
0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73};
std::vector<uint8_t> message{// m0
0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B,
0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21,
0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D,
0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00,
0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00};
// m0
std::vector<uint8_t> message = {
0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5,
0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B,
0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB,
0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21,
0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37,
0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D,
0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0,
0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00,
0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07,
0xF7, 0xFC, 0x00};
std::vector<uint8_t> expected_output = {
0xE3, 0x7B, 0xC4, 0xF8, 0x58, 0xAE, 0x1E, 0x5C,
0xFD, 0xC4, 0x6F, 0x05, 0x4B, 0x1F, 0x47, 0xB9, 0xD2, 0xEA, 0x61, 0xE1,
0xEF, 0x09, 0x11, 0x5C, 0xFE, 0x70, 0x68, 0x52, 0xBF, 0xF2, 0x3A, 0x83};
0xFD, 0xC4, 0x6F, 0x05, 0x4B, 0x1F, 0x47, 0xB9,
0xD2, 0xEA, 0x61, 0xE1, 0xEF, 0x09, 0x11, 0x5C,
0xFE, 0x70, 0x68, 0x52, 0xBF, 0xF2, 0x3A, 0x83};
std::vector<uint8_t> output = d_crypto->computeHMAC_SHA_256(key, message);
std::vector<uint8_t> output = d_crypto->compute_HMAC_SHA_256(key, message);
ASSERT_EQ(expected_output, output);
}
@ -183,21 +205,24 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4)
// key and message generated from RG A.6.5.2
auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> key = {// RG K4 @ 345690
// RG K4 @ 345690
std::vector<uint8_t> key = {
0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6,
0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73};
std::vector<uint8_t> message{
std::vector<uint8_t> message = {
0x02, 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x03, 0xBF,
0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x44, 0x92, 0x38,
0x22, 0x78, 0x97, 0xFD, 0xEF, 0xF9, 0x30, 0x40};
0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x44, 0x92,
0x38, 0x22, 0x78, 0x97, 0xFD, 0xEF, 0xF9, 0x30,
0x40};
std::vector<uint8_t> expected_output = {
0x7B, 0xB2, 0x38, 0xC8, 0x83, 0xC0, 0x6A, 0x2B, 0x50, 0x8F,
0xE6, 0x3F, 0xB7, 0xF4, 0xF5, 0x4D, 0x44, 0xAB, 0xEE, 0x4D,
0xCE, 0xB9, 0x3D, 0xCF, 0x65, 0xCB, 0x3A, 0x5B, 0x81, 0x4A, 0x34, 0xE9};
0x7B, 0xB2, 0x38, 0xC8, 0x83, 0xC0, 0x6A, 0x2B,
0x50, 0x8F, 0xE6, 0x3F, 0xB7, 0xF4, 0xF5, 0x4D,
0x44, 0xAB, 0xEE, 0x4D, 0xCE, 0xB9, 0x3D, 0xCF,
0x65, 0xCB, 0x3A, 0x5B, 0x81, 0x4A, 0x34, 0xE9};
std::vector<uint8_t> output = d_crypto->computeHMAC_SHA_256(key, message);
std::vector<uint8_t> output = d_crypto->compute_HMAC_SHA_256(key, message);
ASSERT_EQ(expected_output, output);
}
@ -220,7 +245,122 @@ TEST(GnssCryptoTest, TestComputeCMAC_AES)
0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44,
0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C};
std::vector<uint8_t> output = d_crypto->computeCMAC_AES(key, message);
std::vector<uint8_t> output = d_crypto->compute_CMAC_AES(key, message);
ASSERT_EQ(expected_output, output);
}
TEST(GnssCryptoTest, VerifySignatureP256)
{
auto d_crypto = std::make_unique<Gnss_Crypto>();
// RG example - import crt certificate
std::vector<uint8_t> message = {
0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF,
0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04,
0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF};
// ECDSA P-256 signature, raw format
std::vector<uint8_t> signature = {
0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20,
0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F,
0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B,
0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D,
0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22,
0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87,
0x28, 0xC1, 0x77, 0xFB};
// PEM format
std::vector<uint8_t> publicKey = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E,
0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45,
0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B,
0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A,
0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A,
0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51,
0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77,
0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B,
0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50,
0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59,
0x2B, 0x37, 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45,
0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38,
0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C,
0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A,
0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51,
0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E,
0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B,
0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A};
d_crypto->set_public_key(publicKey);
bool result = d_crypto->verify_signature_ecdsa_p256(message, signature);
ASSERT_TRUE(result);
std::vector<uint8_t> wrong_signature = signature;
wrong_signature[1] = 1;
bool result2 = d_crypto->verify_signature_ecdsa_p256(message, wrong_signature);
ASSERT_TRUE(!result2);
}
TEST(GnssCryptoTest, VerifySignatureP521)
{
std::unique_ptr<Gnss_Crypto> d_crypto = std::make_unique<Gnss_Crypto>();
// Message to be verified
std::vector<uint8_t> message = {
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 // "Hello World"
};
// Public key in PEM format
std::vector<uint8_t> publicKey = {
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50,
0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x47, 0x62, 0x4D, 0x42, 0x41, 0x47, 0x42,
0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42,
0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x6A, 0x41, 0x34, 0x47, 0x47, 0x41,
0x41, 0x51, 0x41, 0x6F, 0x35, 0x76, 0x77, 0x66, 0x6E, 0x47, 0x57, 0x47,
0x33, 0x44, 0x63, 0x59, 0x75, 0x2B, 0x2F, 0x61, 0x58, 0x47, 0x32, 0x7A,
0x74, 0x65, 0x41, 0x46, 0x50, 0x54, 0x33, 0x0A, 0x48, 0x36, 0x4C, 0x76,
0x4F, 0x4C, 0x76, 0x49, 0x51, 0x6A, 0x61, 0x2B, 0x6A, 0x74, 0x57, 0x73,
0x70, 0x4F, 0x38, 0x37, 0x6F, 0x50, 0x32, 0x4E, 0x6D, 0x72, 0x34, 0x6E,
0x50, 0x68, 0x76, 0x62, 0x53, 0x58, 0x52, 0x4D, 0x37, 0x6A, 0x49, 0x69,
0x46, 0x38, 0x47, 0x70, 0x6B, 0x75, 0x58, 0x6A, 0x75, 0x4E, 0x7A, 0x34,
0x72, 0x61, 0x56, 0x4F, 0x65, 0x49, 0x4D, 0x42, 0x77, 0x45, 0x2B, 0x61,
0x0A, 0x30, 0x4C, 0x76, 0x7A, 0x37, 0x69, 0x54, 0x4D, 0x5A, 0x46, 0x41,
0x41, 0x51, 0x64, 0x2B, 0x70, 0x47, 0x72, 0x56, 0x54, 0x47, 0x77, 0x66,
0x53, 0x48, 0x49, 0x72, 0x49, 0x49, 0x45, 0x78, 0x74, 0x5A, 0x35, 0x77,
0x30, 0x38, 0x51, 0x4F, 0x43, 0x58, 0x2F, 0x75, 0x46, 0x65, 0x2B, 0x30,
0x78, 0x52, 0x78, 0x4C, 0x64, 0x2F, 0x33, 0x36, 0x42, 0x4E, 0x74, 0x63,
0x74, 0x69, 0x2F, 0x45, 0x4C, 0x0A, 0x4B, 0x31, 0x35, 0x67, 0x2B, 0x4B,
0x32, 0x71, 0x67, 0x2F, 0x6C, 0x39, 0x46, 0x42, 0x47, 0x67, 0x4D, 0x2B,
0x51, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20,
0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x0A};
// ECDSA P-521 signature, raw format
std::vector<uint8_t> signature = {
0x01, 0x7B, 0x59, 0xAC, 0x3A, 0x03, 0x5C, 0xB4, 0x07, 0xCD,
0xC1, 0xEB, 0xBE, 0xE5, 0xA6, 0xCB, 0xDA, 0x0A, 0xFF, 0x4D,
0x38, 0x61, 0x16, 0x0F, 0xB3, 0x77, 0xE5, 0x8A, 0xDC, 0xF3,
0xFD, 0x79, 0x38, 0x1E, 0xE8, 0x08, 0x3D, 0x5D, 0xBC, 0xC2,
0x80, 0x6E, 0xE9, 0x2B, 0xC3, 0xEF, 0x07, 0x3D, 0x0C, 0x82,
0x4C, 0x9B, 0x7A, 0x5C, 0x2E, 0xD5, 0x46, 0xBD, 0x22, 0x21,
0x13, 0x8A, 0xB2, 0xCA, 0x96, 0x3D, 0x01, 0xBA, 0x2A, 0xC4,
0x3F, 0xDB, 0x66, 0x3C, 0x40, 0x26, 0xD9, 0xBC, 0x26, 0xD5,
0x57, 0xD4, 0xBD, 0x15, 0x16, 0x88, 0x21, 0x3B, 0xAA, 0x07,
0x89, 0xEF, 0x29, 0x8F, 0x2F, 0x85, 0x76, 0x58, 0x9D, 0xCA,
0x00, 0xCC, 0xC8, 0x30, 0x88, 0x31, 0x99, 0xC1, 0x94, 0xB9,
0xAF, 0x91, 0xDC, 0xC4, 0x6F, 0x19, 0x2B, 0x12, 0xA2, 0x82,
0xA5, 0x66, 0x5E, 0x4B, 0xBB, 0xDF, 0x65, 0x81, 0x52, 0x14,
0x01, 0xD7};
d_crypto->set_public_key(publicKey);
bool result = d_crypto->verify_signature_ecdsa_p521(message, signature);
ASSERT_TRUE(result);
std::vector<uint8_t> wrong_signature = signature;
wrong_signature[1] = 1;
bool result2 = d_crypto->verify_signature_ecdsa_p521(message, wrong_signature);
ASSERT_TRUE(!result2);
}

View File

@ -83,7 +83,7 @@ TEST_F(OsnmaMsgReceiverTest, ComputeMerkleRoot)
// Act
// ----------
computed_merkle_root = osnma->compute_merke_root(dsm_pkr_message,base_leaf);
computed_merkle_root = osnma->compute_merkle_root(dsm_pkr_message, base_leaf);
// Assert
// ----------
@ -102,7 +102,7 @@ TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf)
// Act
// ----------
std::vector<uint8_t> computed_base_leaf = osnma->compute_base_leaf(dsm_pkr_message);
std::vector<uint8_t> computed_base_leaf = osnma->get_merkle_tree_leaves(dsm_pkr_message);
// Assert
// ----------
@ -112,7 +112,7 @@ TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf)
TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey){ // values taken from RG A.7
// Arrange
// ----------
osnma->d_crypto->setMerkleRoot(helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D"));
osnma->d_crypto->set_merkle_root(helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D"));
DSM_PKR_message dsm_pkr_message;
dsm_pkr_message.npkt = 0x01;
dsm_pkr_message.npktid = 0x2;

View File

@ -4,7 +4,7 @@
# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.9...3.23)
cmake_minimum_required(VERSION 3.9...3.30)
project(nav-msg-listener CXX)
set(CMAKE_CXX_STANDARD 11)

View File

@ -34,7 +34,7 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND
endif()
target_include_directories(obsdiff PUBLIC ${GNSSSDR_SOURCE_DIR}/src/tests/common-files)
if("${GNSSTK_VERSION}" VERSION_LESS 3.0.1)
if(GNSSTK_VERSION AND "${GNSSTK_VERSION}" VERSION_LESS 3.0.1)
set_property(TARGET obsdiff PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0
endif()
# Do not show warnings raised by GPSTk v3.0.0

View File

@ -19,7 +19,19 @@ if(NOT GNSSTK_FOUND OR ENABLE_OWN_GNSSTK)
endif()
endif()
find_package(Boost COMPONENTS iostreams serialization QUIET)
if(CMAKE_VERSION VERSION_LESS 3.30)
find_package(Boost COMPONENTS iostreams serialization QUIET)
else()
find_package(Boost COMPONENTS iostreams serialization)
if(NOT TARGET Boost::iostreams)
message(STATUS "Trying deprecated FindBoost Module ...")
if(POLICY CMP0167)
cmake_policy(SET CMP0167 OLD)
find_package(Boost COMPONENTS iostreams serialization)
endif()
endif()
endif()
if(CMAKE_VERSION VERSION_LESS 3.5)
if(NOT TARGET Boost::iostreams)
add_library(Boost::iostreams IMPORTED SHARED)
@ -47,7 +59,7 @@ find_program(UNCOMPRESS_EXECUTABLE uncompress
/usr/sbin
)
if(Boost_FOUND)
if(TARGET Boost::iostreams AND TARGET Boost::serialization)
message(STATUS "The rinex2assist utility tool will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'")
if(USE_CMAKE_TARGET_SOURCES)
add_executable(rinex2assist)
@ -59,7 +71,7 @@ if(Boost_FOUND)
add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc)
endif()
if("${GNSSTK_VERSION}" VERSION_LESS 3.0.1)
if(GNSSTK_VERSION AND "${GNSSTK_VERSION}" VERSION_LESS 3.0.1)
set_property(TARGET rinex2assist PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0
endif()