1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-30 14:46:23 +00:00

[TAS-109] ADKD-MCLT check - changed GST mask, implement FLX tags

This commit is contained in:
Cesare G. Martínez 2024-01-06 16:47:29 +01:00
parent 451bae4a3b
commit fdbd99ce6b
4 changed files with 73 additions and 34 deletions

View File

@ -249,7 +249,7 @@ void osnma_msg_receiver::read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_
/* /*
* case DSM-Kroot: * case DSM-Kroot:
* - computes the padding * - computes the padding and compares with received message
* - if successful, tries to verify the digital signature * - if successful, tries to verify the digital signature
* case DSM-PKR: * case DSM-PKR:
* - calls verify_dsm_pkr to verify the public key * - calls verify_dsm_pkr to verify the public key
@ -459,9 +459,10 @@ void osnma_msg_receiver::read_mack_block(const std::shared_ptr<OSNMA_msg>& osnma
index = index + 4; index = index + 4;
} }
// compute time of subrame and kroot time of applicability, used in read_mack_body and process_mack_message // compute time of subrame and kroot time of applicability, used in read_mack_body and process_mack_message
d_GST_SIS = osnma_msg->TOW_sf0 + osnma_msg->WN_sf0 * 604800; // TODO - find a better placement // TODO - find a better placement
d_GST_SIS = osnma_msg->TOW_sf0 + osnma_msg->WN_sf0 * 604800;
d_GST_0 = d_osnma_data.d_dsm_kroot_message.towh_k + 604800 * d_osnma_data.d_dsm_kroot_message.wn_k; d_GST_0 = d_osnma_data.d_dsm_kroot_message.towh_k + 604800 * d_osnma_data.d_dsm_kroot_message.wn_k;
d_GST_Sf = d_GST_0 + 30 * std::floor((d_GST_SIS-d_GST_0)/30); // TODO - find a better placement d_GST_Sf = d_GST_0 + 30 * std::floor((d_GST_SIS-d_GST_0)/30); // Eq. 3 R.G.
if (d_osnma_data.d_dsm_kroot_message.ts != 0) // C: 4 ts < ts < 10 if (d_osnma_data.d_dsm_kroot_message.ts != 0) // C: 4 ts < ts < 10
{ {
read_mack_header(); read_mack_header();
@ -472,7 +473,7 @@ void osnma_msg_receiver::read_mack_block(const std::shared_ptr<OSNMA_msg>& osnma
void osnma_msg_receiver::read_mack_header() void osnma_msg_receiver::read_mack_header()
{ // C: still to review computations. { // C: TODO - still to review computations.
uint8_t lt_bits = 0; uint8_t lt_bits = 0;
const auto it = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts); const auto it = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts);
if (it != OSNMA_TABLE_11.cend()) if (it != OSNMA_TABLE_11.cend())
@ -729,10 +730,10 @@ void osnma_msg_receiver::read_mack_body()
std::vector<uint8_t> msg(sizeof(K_II) + sizeof(GST_SFi) + sizeof(d_osnma_data.d_dsm_kroot_message.alpha)); std::vector<uint8_t> msg(sizeof(K_II) + sizeof(GST_SFi) + sizeof(d_osnma_data.d_dsm_kroot_message.alpha));
std::copy(K_II.begin(),K_II.end(),msg.begin()); std::copy(K_II.begin(),K_II.end(),msg.begin());
msg.push_back((d_GST_Sf & 0xF000) >> 24); msg.push_back((d_GST_Sf & 0xFF000000) >> 24);
msg.push_back((d_GST_Sf & 0x0F00) >> 16); msg.push_back((d_GST_Sf & 0x00FF0000) >> 16);
msg.push_back((d_GST_Sf & 0x00F0) >> 8); msg.push_back((d_GST_Sf & 0x0000FF00) >> 8);
msg.push_back(d_GST_Sf & 0x000F); msg.push_back(d_GST_Sf & 0x000000FF);
for (uint8_t k = 5; k >= 0;k--) for (uint8_t k = 5; k >= 0;k--)
{ {
@ -767,7 +768,7 @@ void osnma_msg_receiver::read_mack_body()
K_I.clear(); // empty the actual one for a new computation K_I.clear(); // empty the actual one for a new computation
} }
// compare computed current key against received key // compare computed current key against received key
bool result_comparison; bool result_comparison; // TODO - not needed?
if(K_I.size() != d_osnma_data.d_mack_message.key.size()) if(K_I.size() != d_osnma_data.d_mack_message.key.size())
{ {
std::cout << "Galileo OSNMA: Error during tesla key verification. " << std::endl; std::cout << "Galileo OSNMA: Error during tesla key verification. " << std::endl;
@ -778,6 +779,9 @@ void osnma_msg_receiver::read_mack_body()
std::cout << "Galileo OSNMA: tesla key verified successfully " << std::endl; std::cout << "Galileo OSNMA: tesla key verified successfully " << std::endl;
// TODO - propagate result // TODO - propagate result
// TODO - save current tesla key as latest one? // TODO - save current tesla key as latest one?
// TODO - Tags Sequence Verification: check ADKD[i] follows MACLT sequence
} }
else else
@ -795,8 +799,8 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr<OSNMA_msg>&
// MACSEQ validation - case no FLX Tags // MACSEQ validation - case no FLX Tags
// C: TODO check ADKD-MACLT for match, also identify which tags are FLX // C: TODO check ADKD-MACLT for match, also identify which tags are FLX
// C: TODO if Tag_x FLX => MACSEQ, otherwise ___ ?
// Are there flexible tags?
// d_osnma_data.d_dsm_kroot_message.maclt // d_osnma_data.d_dsm_kroot_message.maclt
// d_osnma_data.d_mack_message.tag_and_info[k].tag // d_osnma_data.d_mack_message.tag_and_info[k].tag
@ -808,42 +812,69 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr<OSNMA_msg>&
const auto it = OSNMA_TABLE_16.find(d_osnma_data.d_dsm_kroot_message.maclt); const auto it = OSNMA_TABLE_16.find(d_osnma_data.d_dsm_kroot_message.maclt);
if (it != OSNMA_TABLE_16.cend()) if (it != OSNMA_TABLE_16.cend())
{ {
auto msg = it->second.msg; uint8_t msg = it->second.msg;
auto nt = it->second.nt; uint8_t nt = it->second.nt;
auto sq1 = it->second.sequence1; std::vector<std::string> sq1 = it->second.sequence1;
auto sq2 = it->second.sequence2; std::vector<std::string> sq2 = it->second.sequence2;
} }
if (msg == 0) if (msg == 0)
{ {
return; return;
} }
std::vector<std::string> sequence;
if (d_GST_Sf % 60 == 0)
{
sequence = sq1;
}
else if (d_GST_Sf % 60 == 30)
{
sequence = sq2;
}
else
{
std::cout << "Galileo OSNMA: Mismatch in the GST verification => should end in 30 or 60 seconds but it dit not." << std::endl;
}
// compare ADKD of Mack tags with MACLT defined ADKDs // compare ADKD of Mack tags with MACLT defined ADKDs
// TODO - "When it is equal to 2, the sequence starts with the MACK message transmitted in the first 30 seconds of a GST minute." if(d_osnma_data.d_mack_message.tag_and_info.size() != sq1.size())
if(d_osnma_data.d_mack_message.tag_and_info.size() != sq1.size()) // TODO - which sequence is retrieved in this Mack?
{ {
std::cout << "Galileo OSNMA: Number of retrieved tags does not match MACLT sequence size!" << std::endl; std::cout << "Galileo OSNMA: Number of retrieved tags does not match MACLT sequence size!" << std::endl;
return; return;
} }
bool allOk = true; bool allOk = true; // one being invalid spoils the entire MACK
std::string selfAutenticated {}; std::vector<uint8_t> flxTags {};
std::string tempADKD;
for (uint8_t i = 0; i < d_osnma_data.d_mack_message.tag_and_info.size(); i++) for (uint8_t i = 0; i < d_osnma_data.d_mack_message.tag_and_info.size(); i++)
{ {
if(d_osnma_data.d_mack_message.tag_and_info[i].tag_info.ADKD != std::stoi(sq1[i])) // C: undefined if format is not "00S" // TODO - logic for asserting if if sq[i] == "FLX" (string) or "00X" (int built with first two digits)
tempADKD = sequence[i];
if(tempADKD == "FLX")
{
flxTags.push_back(i); // C: just need to save the index in the sequence
}
else if(d_osnma_data.d_mack_message.tag_and_info[i].tag_info.ADKD != std::stoi(sequence[i]))
{ {
allOk = false; allOk = false;
break; std::cout << "Galileo OSNMA: Unsuccessful verification of received ADKD against MAC Look-up table. " << std::endl;
return; // C: suffices one incorrect to abort and not process the rest of the tags
} }
selfAutenticated = sq1[i][sq1[i].size()-1];
} }
// MACSEQ verification
std::vector<uint8_t> m(5); // C: ICD - Eq. 22 // Case no tags defined as FLX in the MACLT
std::vector<uint8_t> m(5 + flxTags.size()); // C: ICD - Eq. 22
m[0] = static_cast<uint8_t>(osnma_msg->PRN); // PRN_A m[0] = static_cast<uint8_t>(osnma_msg->PRN); // PRN_A
m[1] = ((d_GST_Sf & 0xF000) >> 24); m[1] = static_cast<uint8_t>((d_GST_Sf & 0xFF000000) >> 24);
m[2] = ((d_GST_Sf & 0x0F00) >> 16); m[2] = static_cast<uint8_t>((d_GST_Sf & 0x00FF0000) >> 16);
m[3] = ((d_GST_Sf & 0x00F0) >> 8); m[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
m[4] = (d_GST_Sf & 0x000F); m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
// Case tags flexible
for (uint8_t i = 0; i < flxTags.size() ; i++)
{
m[i+5] = d_osnma_data.d_mack_message.tag_and_info[flxTags[i]].tag_info.PRN_d;
m[i+6] = d_osnma_data.d_mack_message.tag_and_info[flxTags[i]].tag_info.ADKD << 4 | d_osnma_data.d_mack_message.tag_and_info[flxTags[i]].tag_info.cop;
}
std::vector<uint8_t> applicable_key; std::vector<uint8_t> applicable_key;
// if ADKD=12, pick d_old_mack_message.front() if d_old_mack_message[10] is full // if ADKD=12, pick d_old_mack_message.front() if d_old_mack_message[10] is full
// otherwise pick d_old_mack_message.back() // otherwise pick d_old_mack_message.back()
@ -857,27 +888,29 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr<OSNMA_msg>&
{ {
mac = d_crypto->computeCMAC_AES(applicable_key, m); mac = d_crypto->computeCMAC_AES(applicable_key, m);
} }
// Truncate the twelve MSBits and compare with received MACSEQ
uint16_t mac_msb = 0; uint16_t mac_msb = 0;
if (!mac.empty()) if (!mac.empty())
{ {
mac_msb = (mac[0] << 8) + mac[1]; mac_msb = (mac[0] << 8) + mac[1];
} }
uint16_t computed_macseq = (mac_msb & 0x0FFF); uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4; // TODO - double check, it was 0x0FFF which presuposes little endian...
int num_tags_added = 0; int num_tags_added = 0;
if (computed_macseq == d_osnma_data.d_mack_message.header.macseq) if (computed_macseq == d_osnma_data.d_mack_message.header.macseq)
{ {
// C: TODO - for each tag in tag_and_info[] && until l_t_verified <= L_t_min or tags of MACK are finished
// C: d_osnma_data.d_dsm_kroot_message.ts gives l_t of each tag for this mack
// C: tag = trunc(l_t, mac(applicable_key,m))
// C: where m = (PRNd || PRNa || GSTsf || CTR || NMAS || NavData || P)
// C: si l_t_verified >= L_t_min d_new_data = true
std::cout << "OSNMA: MACSEQ authenticated for PRN_A " std::cout << "OSNMA: MACSEQ authenticated for PRN_A "
<< osnma_msg->PRN << " with WN=" << osnma_msg->PRN << " with WN="
<< osnma_msg->WN_sf0 << ", TOW=" << osnma_msg->WN_sf0 << ", TOW="
<< osnma_msg->TOW_sf0 << ". Tags added: " << osnma_msg->TOW_sf0 << ". Tags added: "
<< num_tags_added << std::endl; << num_tags_added << std::endl;
} }
// C: TODO - for each tag in tag_and_info[] && until l_t_verified <= L_t_min
// C: d_osnma_data.d_dsm_kroot_message.ts gives l_t of each tag for this mack
// C: tag = trunc(l_t, mac(applicable_key,m))
// C: where m = (PRNd || PRNa || GSTsf || CTR || NMAS || NavData || P)
// C: si l_t_verified >= L_t_min d_new_data = true
} }
bool osnma_msg_receiver::verify_dsm_pkr(DSM_PKR_message message) bool osnma_msg_receiver::verify_dsm_pkr(DSM_PKR_message message)

View File

@ -1430,6 +1430,9 @@ OSNMA_msg Galileo_Inav_Message::get_osnma_msg()
TOW_sf0 += 604800; TOW_sf0 += 604800;
} }
nma_msg.TOW_sf0 = static_cast<uint32_t>(TOW_sf0); nma_msg.TOW_sf0 = static_cast<uint32_t>(TOW_sf0);
// TODO - draft for retrieving NavData for use during Tag verification.
nma_msg.t0e_1 = static_cast<uint32_t>(t0e_1);
nma_msg.IOD_nav = static_cast<uint32_t>(IOD_nav_1);
return nma_msg; return nma_msg;
} }

View File

@ -49,6 +49,8 @@ public:
uint32_t PRN{}; uint32_t PRN{};
uint32_t WN_sf0{}; uint32_t WN_sf0{};
uint32_t TOW_sf0{}; uint32_t TOW_sf0{};
uint32_t t0e_1{};
uint32_t IOD_nav{};
}; };
/*! /*!

View File

@ -70,6 +70,7 @@ public:
MACK_tag_and_info() = default; MACK_tag_and_info() = default;
uint64_t tag; // C: 20-40 bits uint64_t tag; // C: 20-40 bits
MACK_tag_info tag_info; MACK_tag_info tag_info;
// TODO - std::vector<uint8_t> with complete Tag
}; };
class DSM_PKR_message class DSM_PKR_message