1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 04:00:34 +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= # Build type can still be overridden by setting -DCMAKE_BUILD_TYPE=
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") 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) project(gnss-sdr CXX C)
set(GNSSSDR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # Allows to be a sub-project 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 # 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_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.7.1") set(GNSSSDR_GLOG_LOCAL_VERSION "0.7.1")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.27") 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_PUGIXML_LOCAL_VERSION "1.14")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.14.0") set(GNSSSDR_GTEST_LOCAL_VERSION "1.14.0")
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "origin/master") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "origin/master")
set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.3.0") 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_MATHJAX_EXTERNAL_VERSION "2.7.7")
set(GNSSSDR_ABSL_LOCAL_VERSION "origin/master") # live at head (see https://abseil.io/about/releases) 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}) if(NOT ${FILESYSTEM_FOUND})
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem)
endif() 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) if(NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.") message(FATAL_ERROR "Fatal error: Boost (version >=${GNSSSDR_BOOST_MIN_VERSION}) required.")
endif() endif()
@ -2101,7 +2111,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} 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_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} -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/armadillo-${armadillo_RELEASE}
-DBUILD_SHARED_LIBS=OFF -DSTATIC_LIB=ON
-DBUILD_SMOKE_TEST=OFF -DBUILD_SMOKE_TEST=OFF
-DALLOW_BLAS_LAPACK_MACOS=ON -DALLOW_BLAS_LAPACK_MACOS=ON
${ARMADILLO_CXX_VERSION} ${ARMADILLO_CXX_VERSION}
@ -2120,7 +2130,7 @@ if(NOT ARMADILLO_FOUND OR ENABLE_OWN_ARMADILLO)
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} 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_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} -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/armadillo-${armadillo_RELEASE}
-DBUILD_SHARED_LIBS=OFF -DSTATIC_LIB=ON
-DBUILD_SMOKE_TEST=OFF -DBUILD_SMOKE_TEST=OFF
-DALLOW_BLAS_LAPACK_MACOS=ON -DALLOW_BLAS_LAPACK_MACOS=ON
${ARMADILLO_CXX_VERSION} ${ARMADILLO_CXX_VERSION}

View File

@ -66,7 +66,6 @@ information about this open-source, software-defined GNSS receiver.
- [Debian / Ubuntu](#debian--ubuntu) - [Debian / Ubuntu](#debian--ubuntu)
- [AlmaLinux](#almalinux) - [AlmaLinux](#almalinux)
- [Arch Linux](#arch-linux) - [Arch Linux](#arch-linux)
- [CentOS](#centos)
- [Fedora](#fedora) - [Fedora](#fedora)
- [openSUSE](#opensuse) - [openSUSE](#opensuse)
- [Rocky Linux](#rocky-linux) - [Rocky Linux](#rocky-linux)
@ -126,7 +125,7 @@ This section describes how to set up the compilation environment in GNU/Linux or
## GNU/Linux ## GNU/Linux
- Tested distributions: Ubuntu 14.04 LTS and above; Debian 9.0 "stretch" and - 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: - Supported microprocessor architectures:
- i386: Intel x86 instruction set (32-bit microprocessors). - i386: Intel x86 instruction set (32-bit microprocessors).
- amd64: also known as x86-64, the 64-bit version of the x86 instruction set, - 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 Once you have installed these packages, you can jump directly to
[download the source code and build GNSS-SDR](#clone-gnss-sdrs-git-repository). [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 #### Fedora
If you are using Fedora 26 or above, the required software dependencies can be 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 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 zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux $ sudo pacman -S blas lapack # For Arch Linux
$ wget https://sourceforge.net/projects/arma/files/armadillo-12.8.1.tar.xz $ wget https://sourceforge.net/projects/arma/files/armadillo-14.0.0.tar.xz
$ tar xvfz armadillo-12.8.1.tar.xz $ tar xvfz armadillo-14.0.0.tar.xz
$ cd armadillo-12.8.1 $ cd armadillo-14.0.0
$ cmake . $ cmake .
$ make $ make
$ sudo make install $ sudo make install

View File

@ -55,6 +55,7 @@ find_library(GFORTRAN NAMES gfortran
/usr/lib/gcc/sh4-linux-gnu /usr/lib/gcc/sh4-linux-gnu
/usr/lib/gcc/i686-redhat-linux # Fedora /usr/lib/gcc/i686-redhat-linux # Fedora
/usr/lib64/gcc/x86_64-redhat-linux /usr/lib64/gcc/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux
/usr/lib/gcc/armv7hl-redhat-linux-gnueabi /usr/lib/gcc/armv7hl-redhat-linux-gnueabi
/usr/lib/gcc/aarch64-redhat-linux /usr/lib/gcc/aarch64-redhat-linux
/usr/lib/gcc/ppc64le-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") if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_SIGN_ECDSA_SHA256")
set(GNUTLS_SIGN_ECDSA_SHA256 TRUE) set(GNUTLS_SIGN_ECDSA_SHA256 TRUE)
endif() 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") if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_DIG_SHA3_256")
set(GNUTLS_DIG_SHA3_256 TRUE) set(GNUTLS_DIG_SHA3_256 TRUE)
endif() endif()
@ -181,6 +184,9 @@ function(link_to_crypto_dependencies target)
if(GNUTLS_SIGN_ECDSA_SHA256) if(GNUTLS_SIGN_ECDSA_SHA256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA256=1) target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA256=1)
endif() endif()
if(GNUTLS_SIGN_ECDSA_SHA512)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_SIGN_ECDSA_SHA512=1)
endif()
if(GNUTLS_DIG_SHA3_256) if(GNUTLS_DIG_SHA3_256)
target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_DIG_SHA3_256=1) target_compile_definitions(${target} PRIVATE -DHAVE_GNUTLS_DIG_SHA3_256=1)
endif() 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_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_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_samplestamp_samples = rint(static_cast<double>(samp_count) * d_acq_parameters.resampler_ratio);
d_gnss_synchro->fs = d_acq_parameters.resampled_fs;
} }
else 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_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_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count; d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_gnss_synchro->fs = d_acq_parameters.fs_in;
} }
} }
else 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_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_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->Acq_doppler_step = d_acq_parameters.doppler_step2;
d_gnss_synchro->fs = d_acq_parameters.resampled_fs;
} }
else 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_doppler_hz = static_cast<double>(doppler);
d_gnss_synchro->Acq_samplestamp_samples = samp_count; d_gnss_synchro->Acq_samplestamp_samples = samp_count;
d_gnss_synchro->Acq_doppler_step = d_acq_parameters.doppler_step2; 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 # 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") set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose build type: None Debug Release RelWithDebInfo MinSizeRel")
project(volk_gnsssdr) project(volk_gnsssdr)
enable_language(CXX) enable_language(CXX)

View File

@ -3,14 +3,15 @@
* \brief GNU Radio block that processes Galileo OSNMA data received from * \brief GNU Radio block that processes Galileo OSNMA data received from
* Galileo E1B telemetry blocks. After successful decoding, sends the content to * Galileo E1B telemetry blocks. After successful decoding, sends the content to
* the PVT block. * 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. * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR. * 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 * SPDX-License-Identifier: GPL-3.0-or-later
* *
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
@ -24,12 +25,13 @@
#include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader #include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader
#include "osnma_helper.h" #include "osnma_helper.h"
#include <gnuradio/io_signature.h> // for gr::io_signature::make #include <gnuradio/io_signature.h> // for gr::io_signature::make
#include <chrono>
#include <cmath> #include <cmath>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <iomanip> // for std::setfill
#include <ios> // for std::hex, std::uppercase
#include <iostream> #include <iostream>
#include <numeric> #include <numeric> // for std::accumulate
#include <sstream> // std::stringstream
#include <typeinfo> // for typeid #include <typeinfo> // for typeid
#include <utility> #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 const auto sat = Gnss_Satellite(std::string("Galileo"), nma_msg->PRN); // TODO remove if unneeded
std::ostringstream output_message; std::ostringstream output_message;
output_message << "Galileo OSNMA: complete OSNMA message received starting at " output_message << "Galileo OSNMA: data received starting at "
<< "WN=" << "WN="
<< nma_msg->WN_sf0 << nma_msg->WN_sf0
<< ", TOW=" << ", TOW="
<< nma_msg->TOW_sf0 << nma_msg->TOW_sf0
<< ", from satellite " << ", from satellite "
<< sat; << sat;
LOG(WARNING) << output_message.str(); LOG(INFO) << output_message.str();
std::cout << output_message.str() << std::endl; std::cout << output_message.str() << std::endl;
process_osnma_message(nma_msg); 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)); 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); uint32_t PRNa = std::get<0>(*inav_data);
std::string nav_data = std::get<1>(*inav_data); std::string nav_data = std::get<1>(*inav_data);
;
uint32_t TOW = std::get<2>(*inav_data); uint32_t TOW = std::get<2>(*inav_data);
// iono data => 549 bits, utc data, 141 bits. // iono data => 549 bits, utc data, 141 bits.
if (nav_data.size() == 549) if (nav_data.size() == 549)
{ {
// LOG(INFO) << "Galileo OSNMA: received ADKD=0/12 navData, PRN_d (" << PRNa << ") " // LOG(INFO) << "Galileo OSNMA: received ADKD=0/12 navData, PRN_d (" << PRNa << ") "
// << "TOW_sf=" << TOW; // << "TOW_sf=" << TOW;
d_satellite_nav_data[PRNa][TOW].ephemeris_iono_vector_2 = nav_data; d_satellite_nav_data[PRNa][TOW].ephemeris_iono_vector_2 = nav_data;
} }
else if (nav_data.size() == 141) else if (nav_data.size() == 141)
{ {
// LOG(INFO) << "Galileo OSNMA: received ADKD=4 navData, PRN_d (" << PRNa << ") " // LOG(INFO) << "Galileo OSNMA: received ADKD=4 navData, PRN_d (" << PRNa << ") "
// << "TOW_sf=" << TOW; // << "TOW_sf=" << TOW;
d_satellite_nav_data[PRNa][TOW].utc_vector_2 = nav_data; d_satellite_nav_data[PRNa][TOW].utc_vector_2 = nav_data;
} }
else else
LOG(WARNING) << "osnma_msg_receiver incorrect navData parsing!"; {
LOG(WARNING) << "Galileo OSNMA: osnma_msg_receiver incorrect navData parsing!";
}
} }
else 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) 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 // 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)); this->message_port_pub(pmt::mp("OSNMA_to_PVT"), pmt::make_any(osnma_data_ptr));
d_new_data = false; d_new_data = false;
// d_osnma_data = OSNMA_data(); // 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); 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 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) 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. 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_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 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) 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); << " 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; 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) if (number_of_blocks == 0)
{ {
// Something is wrong, start over // Something is wrong, start over
@ -275,7 +278,7 @@ void osnma_msg_receiver::read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_
} }
else 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) 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 << "]"; available_blocks << "]";
LOG(INFO) << available_blocks.str(); 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 * @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_allowed = tags_to_verify::all;
d_tags_to_verify = {0, 4, 12}; d_tags_to_verify = {0, 4, 12};
LOG(INFO) << "Galileo OSNMA: time constraint OK ( delta_T=" << delta_T << " s)"; 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; // 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 // 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}; d_tags_to_verify = {12};
LOG(WARNING) << "Galileo OSNMA: time constraint allows only slow MACs to be verified"; 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) << "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 else
{ {
@ -342,7 +347,7 @@ void osnma_msg_receiver::local_time_verification(const std::shared_ptr<OSNMA_msg
d_tags_to_verify = {}; d_tags_to_verify = {};
LOG(WARNING) << "Galileo OSNMA: time constraint violation"; 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) << "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) if (d_osnma_data.d_dsm_header.dsm_id < 12)
{ {
// Parse Kroot message // 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.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.pkid = d_dsm_reader->get_pkid(dsm_msg);
d_osnma_data.d_dsm_kroot_message.cidkr = d_dsm_reader->get_cidkr(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; std::vector<uint8_t> hash;
if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8. 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) 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 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) << ", 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; << ", TOW=" << static_cast<uint32_t>(d_osnma_data.d_dsm_kroot_message.towh_k) * 3600;
local_time_verification(osnma_msg); 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) if (d_kroot_verified)
{ {
std::cout << "Galileo OSNMA: KROOT authentication successful!" << std::endl; 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 else
{ {
LOG(WARNING) << "Galileo OSNMA: KROOT authentication failed."; LOG(WARNING) << "Galileo OSNMA: KROOT authentication failed.";
std::cerr << "Galileo OSNMA: KROOT authentication failed." << std::endl;
} }
} }
else 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) 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 // 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.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); 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(); uint32_t l_dp_bytes = dsm_msg.size();
if (d_osnma_data.d_dsm_pkr_message.npkt == 4) 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 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 else
{ {
// Reserved message? // Reserved message?
LOG(WARNING) << "OSNMA Reserved message received"; LOG(WARNING) << "Galileo OSNMA: Reserved message received";
// d_osnma_data = OSNMA_data(); std::cerr << "Galileo OSNMA: Reserved message received" << std::endl;
} }
d_number_of_blocks[d_osnma_data.d_dsm_header.dsm_id] = 0; 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) if (d_kroot_verified == false && d_tesla_key_verified == false)
{ {
LOG(WARNING) << "Galileo OSNMA: MACK cannot be processed. " LOG(WARNING) << "Galileo OSNMA: MACK cannot be processed, "
<< ", " << "no Kroot nor TESLA key available.";
<< "No Kroot nor TESLA key available";
if (!d_flag_debug) 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. return; // early return, cannot proceed further without one of the two verified. this equals to having Kroot but no TESLa key yet.
} }
else 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 // 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 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)); d_tags_awaiting_verify.insert(std::pair<uint32_t, Tag>(mack->TOW, tag0));
// bool ret = verify_macseq(*mack); // bool ret = verify_macseq(*mack);
std::vector<MACK_tag_and_info> macseq_verified_tags = verify_macseq_new(*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 // 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); 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)); d_tags_awaiting_verify.insert(std::pair<uint32_t, Tag>(mack->TOW, t));
LOG(INFO) << "Galileo OSNMA: Add Tag Id= " LOG(INFO) << "Galileo OSNMA: Add Tag Id= "
@ -933,12 +946,13 @@ void osnma_msg_receiver::process_mack_message()
<< ", PRNd=" << ", PRNd="
<< static_cast<unsigned>(t.PRN_d); << 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); mack = d_macks_awaiting_MACSEQ_verification.erase(mack);
} }
else 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; ++mack;
} }
} }
@ -960,18 +974,24 @@ void osnma_msg_receiver::process_mack_message()
if (ret) if (ret)
{ {
it.second.status = Tag::SUCCESS; it.second.status = Tag::SUCCESS;
LOG(WARNING) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id= " LOG(INFO) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id="
<< it.second.tag_id << it.second.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< it.second.received_tag << std::dec << it.second.received_tag << std::dec
<< ", TOW=" << ", TOW="
<< it.second.TOW << it.second.TOW
<< ", ADKD=" << ", ADKD="
<< static_cast<unsigned>(it.second.ADKD) << static_cast<unsigned>(it.second.ADKD)
<< ", PRNa=" << ", PRNa="
<< static_cast<unsigned>(it.second.PRNa) << static_cast<unsigned>(it.second.PRNa)
<< ", PRNd=" << ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d); << 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 /* TODO notify PVT via pmt
* have_new_data() true * have_new_data() true
@ -980,7 +1000,7 @@ void osnma_msg_receiver::process_mack_message()
else else
{ {
it.second.status = Tag::FAIL; 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 << it.second.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< it.second.received_tag << std::dec << it.second.received_tag << std::dec
@ -992,6 +1012,12 @@ void osnma_msg_receiver::process_mack_message()
<< static_cast<unsigned>(it.second.PRNa) << static_cast<unsigned>(it.second.PRNa)
<< ", PRNd=" << ", PRNd="
<< static_cast<unsigned>(it.second.PRN_d); << 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) 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 * \pre DSM_PKR_message correctly filled in especially the 1024 intermediate tree nodes
* \returns true if computed merkle root matches received one, false otherwise * \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 const auto base_leaf = get_merkle_tree_leaves(message); // m_i
std::vector<uint8_t> base_leaf = compute_base_leaf(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); if (computed_merkle_root == d_crypto->get_merkle_root())
computed_merkle_root = compute_merke_root(message, base_leaf);
if (computed_merkle_root == d_crypto->getMerkleRoot())
{ {
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; return true;
} }
else 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; 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++) for (size_t i = 0; i < 4; i++)
{ {
x_next.clear(); 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. // Compute the next node.
x_current = d_crypto->computeSHA256(x_next); x_current = d_crypto->compute_SHA_256(x_next);
} }
return x_current; 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; 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); 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]); 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 // Debug
// LOG(INFO) << "Galileo OSNMA: Tag verification :: Start for tag Id= " // LOG(INFO) << "Galileo OSNMA: Tag verification :: Start for tag Id= "
// << tag.tag_id // << tag.tag_id
// << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase // << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
// << tag.received_tag << std::dec; // << tag.received_tag << std::dec;
// build message // build message
std::vector<uint8_t> m = build_message(tag); 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; std::vector<uint8_t> applicable_key;
if (tag.ADKD == 0 || tag.ADKD == 4) if (tag.ADKD == 0 || tag.ADKD == 4)
{ {
applicable_key = d_tesla_keys[tag.TOW + 30]; const auto it = d_tesla_keys.find(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); 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 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 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 // 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 // Compare computed tag with received one truncated
if (tag.received_tag == computed_mac) 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 << tag.tag_id
<< ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< tag.received_tag << std::dec << tag.received_tag << std::dec
@ -1175,6 +1223,14 @@ bool osnma_msg_receiver::verify_tag(Tag& tag)
<< ", PRNa=" << ", PRNa="
<< static_cast<unsigned>(tag.PRNa) << static_cast<unsigned>(tag.PRNa)
<< ", PRNd=" << ", 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; << static_cast<unsigned>(tag.PRN_d) << std::endl;
return true; 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; std::vector<uint8_t> m;
if (tag.CTR != 1) 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)); 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 // 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); 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; 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. 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; const auto it = d_satellite_nav_data.find(tag.PRN_d);
// LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; 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) else if (tag.ADKD == 4)
{ {
applicable_nav_data = d_satellite_nav_data[tag.PRN_d][tag.TOW - 30].utc_vector_2; const auto it = d_satellite_nav_data.find(tag.PRN_d);
// LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; 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 else
LOG(WARNING) << "Galileo OSNMA :: Tag verification :: unknown ADKD"; {
LOG(WARNING) << "Galileo OSNMA: Tag verification :: unknown ADKD";
}
// convert std::string to vector<uint8_t> // convert std::string to vector<uint8_t>
applicable_nav_data_bytes = d_helper->bytes(applicable_nav_data); 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. uint32_t GST_SFi = d_receiver_time - 30; // GST of target key is to be used.
std::vector<uint8_t> hash; 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; 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) if (d_tesla_key_verified)
{ // have to go up to last verified key { // 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 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"; 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 else
{ // have to go until Kroot { // 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 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"; 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 // truncate hash
std::vector<uint8_t> computed_key; std::vector<uint8_t> computed_key;
computed_key.reserve(key.size()); 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]); 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_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(TOW, key));
d_tesla_key_verified = true; d_tesla_key_verified = true;
d_last_verified_key_GST = d_receiver_time; d_last_verified_key_GST = d_receiver_time;
} }
else if (num_of_hashes_needed > 0) 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) if (d_flag_debug)
{ {
d_tesla_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(TOW, key)); 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); it = d_tags_awaiting_verify.erase(it);
} }
else 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) while (d_tags_awaiting_verify.size() > 500)
{ {
auto it = d_tags_awaiting_verify.begin(); auto it = d_tags_awaiting_verify.begin();
LOG(WARNING) << "Galileo OSNMA: Tag verification :: DELETED tag due to exceeding buffer size. " LOG(INFO) << "Galileo OSNMA: Tag verification :: DELETED tag due to exceeding buffer size. "
<< "Tag Id= " << it->second.tag_id << "Tag Id= " << it->second.tag_id
<< ", TOW=" << it->first << ", TOW=" << it->first
<< ", ADKD=" << static_cast<unsigned>(it->second.ADKD) << ", ADKD=" << static_cast<unsigned>(it->second.ADKD)
<< ", from satellite " << it->second.PRNa; << ", from satellite " << it->second.PRNa;
d_tags_awaiting_verify.erase(it); 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::vector<uint8_t> flxTags{};
std::string tempADKD; std::string tempADKD;
// MACLT verification // 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]; tempADKD = applicable_sequence[i + 1];
if (tempADKD == "FLX") if (tempADKD == "FLX")
@ -1463,7 +1543,7 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
if (flxTags.empty()) 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; return true;
} }
// Fixed as well as FLX Tags share first part - Eq. 22 ICD // 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[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF); m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
// Case tags flexible - Eq. 21 ICD // 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 + 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 | 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; std::vector<uint8_t> mac;
if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256 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 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 // Truncate the twelve MSBits and compare with received MACSEQ
uint16_t mac_msb = 0; 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; uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4;
if (computed_macseq == mack.header.macseq) 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; return true;
} }
else else
{ {
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed"; 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); auto prn_it = d_satellite_nav_data.find(t.PRN_d);
if (prn_it != d_satellite_nav_data.end()) if (prn_it != d_satellite_nav_data.end())
{ {
// PRN was found, check if TOW exists in inner map // PRN was found, check if TOW exists in inner map
//LOG(INFO) << "Galileo OSNMA: hasData = true " << std::endl; //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); auto tow_it = tow_map.find(t.TOW - 30);
if (tow_it != tow_map.end()) 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 // check adkd of tag
// if adkd = 0 or 4 => look for d_tesla_keys[t.TOW+30] // 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_II = key;
std::vector<uint8_t> K_I; // result of the recursive hash operations std::vector<uint8_t> K_I; // result of the recursive hash operations
std::vector<uint8_t> msg; 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; std::vector<uint8_t> hash;
if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8. 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) 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 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 // check that the final time matches the Kroot time
bool check; bool check;
if (!d_tesla_key_verified) if (!d_tesla_key_verified)
check = GST_SFi + 30 == d_GST_0 - 30; {
check = GST_SFi + 30 == d_GST_0 - 30;
}
else else
check = GST_SFi + 30 == d_last_verified_key_GST; {
check = GST_SFi + 30 == d_last_verified_key_GST;
}
if (!check) 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 else
LOG(INFO) << "Galileo OSNMA: TESLA verification. Kroot time matches!"; // ICD. Eq. 18 {
// compare computed current key against received key LOG(INFO) << "Galileo OSNMA: TESLA key chain verification: KROOT time matches."; // ICD. Eq. 18
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.";
return K_II; return K_II;
} }
/** /**
* @brief Verifies the MAC sequence of a received MACK message. * @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> 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 // 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.. 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 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> sq1{};
std::vector<std::string> sq2{}; std::vector<std::string> sq2{};
std::vector<std::string> applicable_sequence; 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::vector<uint8_t> flxTags{};
std::string tempADKD; std::string tempADKD;
// MACLT verification // 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]; tempADKD = applicable_sequence[i + 1];
if (tempADKD == "FLX") 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])) else if (mack.tag_and_info[i].tag_info.ADKD == std::stoi(applicable_sequence[i + 1]))
{ {
// fill index of tags failed // fill index of tags failed
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD match against MAC Look-up table for " LOG(INFO) << "Galileo OSNMA: MACSEQ verification :: SUCCESS :: ADKD match against MAC Look-up table for Tag=0x"
"Tag=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec; << mack.tag_and_info[i].tag << std::dec;
verified_tags.push_back(mack.tag_and_info[i]); verified_tags.push_back(mack.tag_and_info[i]);
} }
else else
{ {
// discard tag // discard tag
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table for " LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table for Tag=0x"
"Tag=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase << std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec; << mack.tag_and_info[i].tag << std::dec;
} }
} }
if (flxTags.empty() /*TODO add check d_flag_check_mackseq_fixed_tags*/) 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; return verified_tags;
} }
// Fixed as well as FLX Tags share first part - Eq. 22 ICD // 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[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF); m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
// Case tags flexible - Eq. 21 ICD // 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 + 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 | 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; std::vector<uint8_t> mac;
if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256 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 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 // Truncate the twelve MSBits and compare with received MACSEQ
uint16_t mac_msb = 0; 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; uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4;
if (computed_macseq == mack.header.macseq) 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";
for (uint8_t i = 0; i < flxTags.size(); i++) 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; 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"; LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed";
return verified_tags; return verified_tags;
} }
} }

View File

@ -3,14 +3,15 @@
* \brief GNU Radio block that processes Galileo OSNMA data received from * \brief GNU Radio block that processes Galileo OSNMA data received from
* Galileo E1B telemetry blocks. After successful decoding, sends the content to * Galileo E1B telemetry blocks. After successful decoding, sends the content to
* the PVT block. * 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. * GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
* This file is part of GNSS-SDR. * 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 * SPDX-License-Identifier: GPL-3.0-or-later
* *
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
@ -18,20 +19,23 @@
#ifndef GNSS_SDR_OSNMA_MSG_RECEIVER_H #ifndef GNSS_SDR_OSNMA_MSG_RECEIVER_H
#define 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 "galileo_inav_message.h" // for OSNMA_msg
#include "gnss_block_interface.h" // for gnss_shared_ptr #include "gnss_block_interface.h" // for gnss_shared_ptr
#include "gnss_sdr_make_unique.h" // for std::make:unique in C++11 #include "gnss_sdr_make_unique.h" // for std::make:unique in C++11
#include "osnma_data.h" // for OSNMA_data #include "osnma_data.h" // for OSNMA_data structures
#include <boost/circular_buffer.hpp> #include <gnuradio/block.h> // for gr::block
#include <gnuradio/block.h> // for gr::block #include <pmt/pmt.h> // for pmt::pmt_t
#include <pmt/pmt.h> // for pmt::pmt_t #include <array> // for std::array
#include <array> // for std::array #include <cstdint> // for uint8_t
#include <memory> // for std::shared_ptr #include <ctime> // for std::time_t
#include <string> #include <map> // for std::map, std::multimap
#include <vector> #include <memory> // for std::shared_ptr
#include <string> // for std::string
#include <vector> // for std::vector
/** \addtogroup Core /** \addtogroup Core
* \{ */ * \{ */
@ -73,58 +77,69 @@ private:
void read_mack_header(); void read_mack_header();
void read_mack_body(); void read_mack_body();
void process_mack_message(); 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 remove_verified_tags();
void control_tags_awaiting_verify_size(); 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(); 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_tesla_key(std::vector<uint8_t>& key, uint32_t TOW);
bool verify_tag(Tag& tag); bool verify_tag(const Tag& tag) const;
bool is_next_subframe(); bool tag_has_nav_data_available(const Tag& t) const;
bool tag_has_nav_data_available(Tag& t); bool tag_has_key_available(const Tag& t) const;
bool tag_has_key_available(Tag& t);
bool verify_macseq(const MACK_message& mack); 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}; std::vector<uint8_t> get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const;
tags_to_verify d_tags_allowed{tags_to_verify::all}; std::vector<uint8_t> compute_merkle_root(const DSM_PKR_message& dsm_pkr_message, const std::vector<uint8_t>& m_i) const;
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::vector<uint8_t> build_message(const Tag& tag) const;
std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys; // tesla keys over time, sorted by TOW 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::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<std::array<uint8_t, 16>, 16> d_dsm_id_received{};
std::array<uint16_t, 16> d_number_of_blocks{}; 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{}; 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_new_data{false};
bool d_public_key_verified{false}; bool d_public_key_verified{false};
bool d_kroot_verified{false}; bool d_kroot_verified{false};
bool d_tesla_key_verified{false}; bool d_tesla_key_verified{false};
bool d_flag_debug{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 // Provide access to inner functions to Gtest
FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification); 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)); 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)); 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 = 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 = static_cast<double>(read_navigation_signed(subframe_bits, D1_A1UTC));
d_A1UTC = d_A1UTC * D1_A1UTC_LSB; 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 /** \addtogroup System_Parameters
* \{ */ * \{ */
/*!
* \brief Class implementing cryptographic functions
* for Navigation Message Authentication
*/
class Gnss_Crypto class Gnss_Crypto
{ {
public: 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(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; //!< Returns true if the ECDSA Public Key is already loaded
bool have_public_key() const;
bool verify_signature(const std::vector<uint8_t>& message, const std::vector<uint8_t>& signature) const; /*!
* 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; 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 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)
return d_x_4_0;
} std::vector<uint8_t> compute_SHA_256(const std::vector<uint8_t>& input) const; //!< Computes SHA-256 hash
inline void setMerkleRoot(const std::vector<uint8_t>& v) 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
d_x_4_0 = v; 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: private:
void read_merkle_xml(const std::string& merkleFilePath); void read_merkle_xml(const std::string& merkleFilePath);
@ -79,10 +91,6 @@ private:
#endif #endif
#endif #endif
std::vector<uint8_t> d_x_4_0; 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: public:
DSM_PKR_message() = default; 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> npk;
std::vector<uint8_t> p_dp; std::vector<uint8_t> p_dp;
uint8_t nb_dp{}; uint8_t nb_dp{};

View File

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

View File

@ -29,7 +29,7 @@ public:
uint32_t compute_gst(uint32_t WN, uint32_t TOW) const; 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> gst_to_uint8(uint32_t GST) const;
std::vector<uint8_t> bytes(const std::string& binaryString) 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::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 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_link_libraries(gnss-sdr PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gnss-sdr PUBLIC -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(gnss-sdr PUBLIC -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
if(NOT ENABLE_LOG) 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_link_libraries(run_tests PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(run_tests PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(run_tests PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
target_include_directories(run_tests target_include_directories(run_tests
INTERFACE 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_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) target_compile_definitions(gps_l1_ca_dll_pll_tracking_test_fpga PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
target_include_directories(gps_l1_ca_dll_pll_tracking_test_fpga target_include_directories(gps_l1_ca_dll_pll_tracking_test_fpga
INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files 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 INTERFACE ${GNSSSDR_SOURCE_DIR}/src/tests/common-files
) )
target_link_libraries(${executable} PRIVATE ${OPT_LIBS_} algorithms_libs) 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) if(GNURADIO_USES_STD_POINTERS)
target_compile_definitions(${executable} target_compile_definitions(${executable}
PRIVATE -DGNURADIO_USES_STD_POINTERS=1 PRIVATE -DGNURADIO_USES_STD_POINTERS=1
@ -873,7 +878,7 @@ if(ENABLE_SYSTEM_TESTING)
if(ENABLE_GLOG_AND_GFLAGS) if(ENABLE_GLOG_AND_GFLAGS)
set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog) set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog)
else() 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() endif()
if(NOT ENABLE_PACKAGING) if(NOT ENABLE_PACKAGING)
add_system_test(ttff add_system_test(ttff
@ -897,7 +902,7 @@ if(ENABLE_SYSTEM_TESTING)
if(ENABLE_GLOG_AND_GFLAGS) if(ENABLE_GLOG_AND_GFLAGS)
set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog) set(OPT_LIBS_ ${OPT_LIBS_} Gflags::gflags Glog::glog)
else() 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() endif()
add_system_test(position_test 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> 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_link_libraries(flowgraph_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(flowgraph_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(flowgraph_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
target_include_directories(flowgraph_test 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_link_libraries(gnss_block_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gnss_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(gnss_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
target_include_directories(gnss_block_test 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_link_libraries(gnuradio_block_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(gnuradio_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(gnuradio_block_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
xcode_remove_warning_duplicates(gnuradio_block_test) 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_link_libraries(matio_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(matio_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(matio_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
target_include_directories(matio_test 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_link_libraries(acq_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(acq_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(acq_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
target_include_directories(acq_test target_include_directories(acq_test
INTERFACE INTERFACE
@ -1251,7 +1261,8 @@ if(NOT ENABLE_PACKAGING AND NOT ENABLE_FPGA)
target_link_libraries(trk_test PRIVATE Gflags::gflags Glog::glog) target_link_libraries(trk_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(trk_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(trk_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
if(USE_GENERIC_LAMBDAS) if(USE_GENERIC_LAMBDAS)
set(has_generic_lambdas HAS_GENERIC_LAMBDA=1) 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_link_libraries(control_thread_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(control_thread_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(control_thread_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
xcode_remove_warning_duplicates(control_thread_test) 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_link_libraries(osnma_msg_receiver_test PRIVATE Gflags::gflags Glog::glog)
target_compile_definitions(osnma_msg_receiver_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1) target_compile_definitions(osnma_msg_receiver_test PRIVATE -DUSE_GLOG_AND_GFLAGS=1)
else() 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() endif()
xcode_remove_warning_duplicates(osnma_msg_receiver_test) # TODO - unsure if needed 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_crypto.h"
#include "gnss_sdr_filesystem.h" #include "gnss_sdr_filesystem.h"
#include "gnss_sdr_make_unique.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) TEST(GnssCryptoTest, VerifyPubKeyImport)
{ {
auto d_crypto = std::make_unique<Gnss_Crypto>(); auto d_crypto = std::make_unique<Gnss_Crypto>();
std::vector<uint8_t> publicKey{// PEM // PEM format
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, std::vector<uint8_t> publicKey = {
0x4D, 0x46, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55,
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, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
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, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49,
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, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A,
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, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76,
0x44, 0x79, 0x48, 0x58, 0x51, 0x3D, 0x3D, 0x0A, 0x50, 0x75, 0x4F, 0x70, 0x51, 0x6C, 0x4A, 0x54, 0x31, 0x56, 0x77, 0x6C, 0x72,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x43, 0x4C, 0x63, 0x38, 0x55, 0x54, 0x54, 0x6B, 0x4E, 0x73, 0x66, 0x78, 0x2F,
0x2D, 0x2D, 0x2D, 0x0A}; 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); d_crypto->set_public_key(publicKey);
@ -92,14 +62,22 @@ TEST(GnssCryptoTest, VerifyPublicKeyStorage)
const std::string f1("./osnma_test_file1.pem"); const std::string f1("./osnma_test_file1.pem");
const std::string f2("./osnma_test_file2.pem"); const std::string f2("./osnma_test_file2.pem");
std::vector<uint8_t> publicKey{ // PEM format
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, std::vector<uint8_t> publicKey = {
0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55,
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, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x46, 0x6B, 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, 0x2B, 0x37, 0x0A, 0x4D, 0x46, 0x6B, 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49,
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, 0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49, 0x7A,
0x4C, 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, 0x3D, 0x3D, 0x0A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45, 0x53, 0x76,
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}; 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); d_crypto->set_public_key(publicKey);
bool result = d_crypto->store_public_key(f1); bool result = d_crypto->store_public_key(f1);
@ -118,7 +96,7 @@ TEST(GnssCryptoTest, VerifyPublicKeyStorage)
ASSERT_EQ(content_file, content_file2); 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); ASSERT_EQ(publicKey, readkey);
errorlib::error_code ec; 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. // Unit test for computeHMAC_SHA_256 function.
TEST(GnssCryptoTest, TestComputeHMACSHA256) TEST(GnssCryptoTest, TestComputeHMACSHA256)
{ {
@ -138,14 +150,16 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256)
0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3, 0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3,
0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA}; 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 = { std::vector<uint8_t> expected_output = {
0xC3, 0x51, 0xF6, 0xFD, 0xDD, 0xC9, 0x8B, 0x41, 0xC3, 0x51, 0xF6, 0xFD, 0xDD, 0xC9, 0x8B, 0x41,
0xD6, 0xF4, 0x77, 0x6D, 0xAC, 0xE8, 0xE0, 0x14, 0xD6, 0xF4, 0x77, 0x6D, 0xAC, 0xE8, 0xE0, 0x14,
0xB2, 0x7A, 0xCC, 0x22, 0x00, 0xAA, 0xD2, 0x37, 0xB2, 0x7A, 0xCC, 0x22, 0x00, 0xAA, 0xD2, 0x37,
0xD0, 0x79, 0x06, 0x12, 0x83, 0x40, 0xB7, 0xA6}; 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); ASSERT_EQ(expected_output, output);
} }
@ -156,23 +170,31 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_m0)
// key and message generated from RG A.6.5.1 // key and message generated from RG A.6.5.1
auto d_crypto = std::make_unique<Gnss_Crypto>(); 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, 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6,
0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73};
std::vector<uint8_t> message{// m0 // m0
0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, std::vector<uint8_t> message = {
0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5,
0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B,
0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00, 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB,
0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00}; 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 = { std::vector<uint8_t> expected_output = {
0xE3, 0x7B, 0xC4, 0xF8, 0x58, 0xAE, 0x1E, 0x5C, 0xE3, 0x7B, 0xC4, 0xF8, 0x58, 0xAE, 0x1E, 0x5C,
0xFD, 0xC4, 0x6F, 0x05, 0x4B, 0x1F, 0x47, 0xB9, 0xD2, 0xEA, 0x61, 0xE1, 0xFD, 0xC4, 0x6F, 0x05, 0x4B, 0x1F, 0x47, 0xB9,
0xEF, 0x09, 0x11, 0x5C, 0xFE, 0x70, 0x68, 0x52, 0xBF, 0xF2, 0x3A, 0x83}; 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); ASSERT_EQ(expected_output, output);
} }
@ -183,21 +205,24 @@ TEST(GnssCryptoTest, TestComputeHMACSHA256_adkd4)
// key and message generated from RG A.6.5.2 // key and message generated from RG A.6.5.2
auto d_crypto = std::make_unique<Gnss_Crypto>(); 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, 0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6,
0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; 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, 0x02, 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x03, 0xBF,
0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x44, 0x92, 0x38, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x44, 0x92,
0x22, 0x78, 0x97, 0xFD, 0xEF, 0xF9, 0x30, 0x40}; 0x38, 0x22, 0x78, 0x97, 0xFD, 0xEF, 0xF9, 0x30,
0x40};
std::vector<uint8_t> expected_output = { std::vector<uint8_t> expected_output = {
0x7B, 0xB2, 0x38, 0xC8, 0x83, 0xC0, 0x6A, 0x2B, 0x50, 0x8F, 0x7B, 0xB2, 0x38, 0xC8, 0x83, 0xC0, 0x6A, 0x2B,
0xE6, 0x3F, 0xB7, 0xF4, 0xF5, 0x4D, 0x44, 0xAB, 0xEE, 0x4D, 0x50, 0x8F, 0xE6, 0x3F, 0xB7, 0xF4, 0xF5, 0x4D,
0xCE, 0xB9, 0x3D, 0xCF, 0x65, 0xCB, 0x3A, 0x5B, 0x81, 0x4A, 0x34, 0xE9}; 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); ASSERT_EQ(expected_output, output);
} }
@ -220,7 +245,122 @@ TEST(GnssCryptoTest, TestComputeCMAC_AES)
0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44,
0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C}; 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); 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 // 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 // Assert
// ---------- // ----------
@ -102,7 +102,7 @@ TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf)
// Act // 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 // Assert
// ---------- // ----------
@ -112,7 +112,7 @@ TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf)
TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey){ // values taken from RG A.7 TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey){ // values taken from RG A.7
// Arrange // 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 dsm_pkr_message;
dsm_pkr_message.npkt = 0x01; dsm_pkr_message.npkt = 0x01;
dsm_pkr_message.npktid = 0x2; dsm_pkr_message.npktid = 0x2;

View File

@ -4,7 +4,7 @@
# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause # 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) project(nav-msg-listener CXX)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)

View File

@ -34,7 +34,7 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND
endif() endif()
target_include_directories(obsdiff PUBLIC ${GNSSSDR_SOURCE_DIR}/src/tests/common-files) 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 set_property(TARGET obsdiff PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0
endif() endif()
# Do not show warnings raised by GPSTk v3.0.0 # 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()
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(CMAKE_VERSION VERSION_LESS 3.5)
if(NOT TARGET Boost::iostreams) if(NOT TARGET Boost::iostreams)
add_library(Boost::iostreams IMPORTED SHARED) add_library(Boost::iostreams IMPORTED SHARED)
@ -47,7 +59,7 @@ find_program(UNCOMPRESS_EXECUTABLE uncompress
/usr/sbin /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}'") message(STATUS "The rinex2assist utility tool will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'")
if(USE_CMAKE_TARGET_SOURCES) if(USE_CMAKE_TARGET_SOURCES)
add_executable(rinex2assist) add_executable(rinex2assist)
@ -59,7 +71,7 @@ if(Boost_FOUND)
add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc) add_executable(rinex2assist ${CMAKE_CURRENT_SOURCE_DIR}/main.cc)
endif() 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 set_property(TARGET rinex2assist PROPERTY CXX_STANDARD 14) # Required by GPSTk v3.0.0
endif() endif()