Event History Setup: #287

Make Tweaks / Fixes to DMR Talker Alias;

Setup for Hytera Enhanced RC4 Cipher (LFSR Works, Cipher Untested / Unknown Working State);
This commit is contained in:
lwvmobile
2025-05-01 20:40:35 -04:00
parent 3563399126
commit 934b95cde8
8 changed files with 141 additions and 16 deletions

View File

@@ -1586,7 +1586,9 @@ void aes_ctr_bytewise_payload_crypt (uint8_t * iv, uint8_t * key, uint8_t * payl
void aes_ctr_bitwise_payload_crypt (uint8_t * iv, uint8_t * key, uint8_t * payload, int type);
//Hytera Enhanced
void hytera_enhanced_enc_setup(dsd_opts * opts, dsd_state * state, unsigned long long int key_value, unsigned long long int mi_value);
void hytera_enhanced_rc4_setup(dsd_opts * opts, dsd_state * state, unsigned long long int key_value, unsigned long long int mi_value);
unsigned long long int hytera_lfsr(uint8_t * mi, uint8_t * taps, uint8_t len);
void hytera_enhanced_alg_refresh(dsd_state * state);
//LFSR to expand either a DMR 32-bit or P25/NXDN 64-bit MI into a 128-bit IV for AES
void LFSR128(dsd_state * state);

View File

@@ -86,4 +86,60 @@ void rc4_block_output (int drop, int keylen, int meslen, uint8_t * key, uint8_t
}
}
//NOTE: This has not been verified to work properly
//NOTE: This is for Hytera Enhanced RC4, if AES, this will not work
void hytera_enhanced_rc4_setup(dsd_opts * opts, dsd_state * state, unsigned long long int key_value, unsigned long long int mi_value)
{
UNUSED(opts);
uint8_t key[5]; memset (key, 0, sizeof(key));
uint8_t kiv[5]; memset (kiv, 0, sizeof(kiv));
uint8_t mi[5]; memset (mi, 0, sizeof(mi));
uint8_t ks[135]; memset (ks, 0, sizeof(ks));
//load key_value into key array
key[0] = ((key_value & 0xFF00000000) >> 32UL);
key[1] = ((key_value & 0xFF000000) >> 24);
key[2] = ((key_value & 0xFF0000) >> 16);
key[3] = ((key_value & 0xFF00) >> 8);
key[4] = ((key_value & 0xFF) >> 0);
//load mi_value into mi array
mi[0] = ((mi_value & 0xFF00000000) >> 32UL);
mi[1] = ((mi_value & 0xFF000000) >> 24);
mi[2] = ((mi_value & 0xFF0000) >> 16);
mi[3] = ((mi_value & 0xFF00) >> 8);
mi[4] = ((mi_value & 0xFF) >> 0);
//pointer to the ks_octet storage
uint8_t * ks_octets;
if (state->currentslot == 0)
ks_octets = state->ks_octetL;
else ks_octets = state->ks_octetR;
rc4_block_output(256, 5, 135, key, ks);
for (int i = 0; i < 5; i++)
kiv[i] = key[i] ^ mi[i];
for (int i = 0; i < 135; i++)
ks_octets[i] = kiv[i%5] ^ ks[i];
//debug
// fprintf (stderr, " KS: ");
// for (int i = 0; i < 135; i++)
// {
// if ((i != 0) && ((i%7) == 0))
// fprintf (stderr, " ");
// fprintf (stderr, "%02X", ks[i]); //ks_octets
// }
//NULL pointer to ks_octets
ks_octets = NULL;
//end line break
// fprintf (stderr, "\n");
}

View File

@@ -425,6 +425,9 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
if (internalslot == 0 && vc1 == 6)
{
//this needs to run prior to embedded link control
if (state->payload_algid == 0x02)
hytera_enhanced_alg_refresh(state);
//process embedded link control
fprintf (stderr, "\n");
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
@@ -435,6 +438,9 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
if (internalslot == 1 && vc2 == 6)
{
//this needs to run prior to embedded link control
if (state->payload_algidR == 0x02)
hytera_enhanced_alg_refresh(state);
//process embedded link control
fprintf (stderr, "\n");
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);

View File

@@ -227,7 +227,13 @@ void dmr_alg_refresh (dsd_opts * opts, dsd_state * state)
if (state->payload_algid == 0x02)
{
state->DMRvcL = 0;
//LFSR MI propegation function
//LFSR already calculated, just dump it now
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " Slot 1");
fprintf (stderr, " DMR PI C- ALG ID: %02X; KEY ID: %02X;", state->payload_algid, state->payload_keyid);
fprintf (stderr, " MI(40): %010llX;", state->payload_mi);
fprintf (stderr, " Hytera Enhanced;");
fprintf (stderr, "%s\n", KNRM);
}
}
@@ -251,7 +257,13 @@ void dmr_alg_refresh (dsd_opts * opts, dsd_state * state)
if (state->payload_algidR == 0x02)
{
state->DMRvcR = 0;
//LFSR MI propegation function
//LFSR already calculated, just dump it now
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " Slot 2");
fprintf (stderr, " DMR PI C- ALG ID: %02X; KEY ID: %02X;", state->payload_algidR, state->payload_keyidR);
fprintf (stderr, " MI(40): %010llX;", state->payload_miR);
fprintf (stderr, " Hytera Enhanced;");
fprintf (stderr, "%s\n", KNRM);
}
}

View File

@@ -274,6 +274,10 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
if (vc == 6)
{
//this needs to run prior to embedded link control
if (state->payload_algid == 0x02)
hytera_enhanced_alg_refresh(state);
dmr_data_burst_handler(opts, state, (uint8_t *)dummy_bits, 0xEB);
//check the single burst/reverse channel opportunity
dmr_sbrc (opts, state, power);

View File

@@ -410,13 +410,58 @@ void LFSR128d(dsd_state * state)
}
void hytera_enhanced_enc_setup(dsd_opts * opts, dsd_state * state, unsigned long long int key_value, unsigned long long int mi_value)
unsigned long long int hytera_lfsr(uint8_t * mi, uint8_t * taps, uint8_t len)
{
UNUSED(opts);
UNUSED(state);
UNUSED(key_value);
UNUSED(mi_value);
for (uint8_t i = 0; i < len; i++)
{
uint8_t bit = (mi[i] >> 7) & 1;
mi[i] <<= 1;
if (bit) mi[i] ^= taps[i%5];
mi[i] |= bit;
}
unsigned long long int mi_value = 0;
for (uint8_t i = 0; i < 5; i++)
{
mi_value <<= 8;
mi_value |= mi[i];
}
//debug
// fprintf (stderr, " Next MI: %010llX \n", mi_value);
return mi_value;
}
void hytera_enhanced_alg_refresh(dsd_state * state)
{
uint8_t mi[5]; memset (mi, 0, sizeof(mi));
unsigned long long int mi_value = 0;
if (state->currentslot == 0)
mi_value = state->payload_mi;
else mi_value = state->payload_miR;
//load mi_value into mi array
mi[0] = ((mi_value & 0xFF00000000) >> 32UL);
mi[1] = ((mi_value & 0xFF000000) >> 24);
mi[2] = ((mi_value & 0xFF0000) >> 16);
mi[3] = ((mi_value & 0xFF00) >> 8);
mi[4] = ((mi_value & 0xFF) >> 0);
//calculate the next MI value
uint8_t taps[5]; memset(taps, 0, sizeof(taps));
//the tap values
taps[0] = 0x12;
taps[1] = 0x24;
taps[2] = 0x48;
taps[3] = 0x22;
taps[4] = 0x14;
mi_value = hytera_lfsr(mi, taps, 5);
if (state->currentslot == 0)
state->payload_mi = mi_value;
else state->payload_miR = mi_value;
}

View File

@@ -685,9 +685,9 @@ void dmr_talker_alias_lc_blocks (dsd_opts * opts, dsd_state * state, uint8_t slo
//set the pointer to the current index of the dmr_pdu_sf
if (char_size == 16)
ptr = 48 + (block_num * 48);
ptr = 48 + (block_num * 56);
else if (char_size == 8)
ptr = 48 + (block_num * 48);
ptr = 48 + (block_num * 56);
else if (char_size == 7)
ptr = 49 + (block_num * 56);
@@ -717,14 +717,14 @@ void dmr_talker_alias_lc_blocks (dsd_opts * opts, dsd_state * state, uint8_t slo
}
else if (char_size == 16)
{
memcpy(state->dmr_pdu_sf[slot]+ptr, lc_bits+16, 48*sizeof(uint8_t));
ptr += 48;
memcpy(state->dmr_pdu_sf[slot]+ptr, lc_bits+16, 56*sizeof(uint8_t));
ptr += 56;
if (block_len == 0)
end = ptr / 16;
else end = block_len;
}
dmr_talker_alias_lc_decode (opts, state, slot, block_num, char_size, end);
dmr_talker_alias_lc_decode (opts, state, slot, block_num+1, char_size, end);
}
}
@@ -733,7 +733,7 @@ void dmr_talker_alias_lc_decode (dsd_opts * opts, dsd_state * state, uint8_t slo
{
UNUSED(opts);
uint16_t i = 0;
fprintf (stderr, " Slot %d - Talker Alias Block Num: %d; Valid Block;", slot, block_num+1);
fprintf (stderr, " Slot %d - Talker Alias Block Num: %d; Valid Block;", slot, block_num);
fprintf (stderr, " Talker Alias: ");
char alias_string[500]; memset (alias_string, 0, sizeof(alias_string));

View File

@@ -775,7 +775,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
if(state->payload_algid == 0x02)
{
n = 0;
hytera_enhanced_enc_setup(opts, state, state->R, state->payload_mi);
hytera_enhanced_rc4_setup(opts, state, state->R, state->payload_mi);
}
//Load Keystream Octet Bytes directly into keystream array //TODO: Convert to unpack function
@@ -1152,7 +1152,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
if(state->payload_algidR == 0x02)
{
n = 0;
hytera_enhanced_enc_setup(opts, state, state->RR, state->payload_miR);
hytera_enhanced_rc4_setup(opts, state, state->RR, state->payload_miR);
}
//Load Keystream Octet Bytes directly into keystream array