DMR: Add Support for Callta BP 10/32/64; #360

DMR: Add optional discard value to -S straight_xor keystream application;
This commit is contained in:
lwvmobile
2026-09-20 04:31:06 -04:00
parent fa4a332582
commit 15515158b5
10 changed files with 338 additions and 84 deletions

View File

@@ -1,4 +1,4 @@
Build Version: AW 2026-43-g4139b19
Build Version: AW 2026-44-gfa4a332
MBElib Version: 1.3.4
CODEC2 Support Enabled
@@ -141,6 +141,11 @@ Advanced Decoder options:
-H '736B9A9C5645288B 243AD5CB8701EF8A'
-H '20029736A5D91042 C923EB0697484433 005EFC58A1905195 E28E9C7836AA2DB8'
-H <hex> Manually Enter Caltta 10/32/64 Char Basic Privacy Hex Key (see example below)
-H C:40:0292081081
-H C:128:736B9A9C5645288B243AD5CB8701EF8A'
-H C:256:20029736A5D91042C923EB0697484433005EFC58A1905195E28E9C7836AA2DB8'
-R <dec> Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value)
-1 <hex> Manually Enter RC4 or DES Key Value (DMR, P25, NXDN) (Hex Value)
@@ -199,6 +204,8 @@ Advanced Decoder options:
-S 49:ED0AED4AED4AED4A
For Example, Baofeng 49-bit Keystream for 56-bit Custom Encryption as:
-S 49:11AA22BB33CC44
For Example, Caltta 40-bit Keystream w/ optional 7-bit discard as:
-S 49:11AA22BB33CC44:7
-k <file> Import Key List from csv file (Decimal Format) -- Lower Case 'k'.
Only supports NXDN, DMR Basic Privacy (decimal value).
@@ -229,7 +236,7 @@ Advanced Decoder options:
-p Disable Tune to Private Calls (DMR TIII, P25, NXDN Type-C and Type-D)
-E Disable Tune to Group Calls (DMR TIII, Con+, Cap+, P25, NXDN Type-C, and Type-D)
-e Enable Tune to Data Calls (DMR TIII, Cap+, NXDN Type-C)
(NOTE: No Clear Distinction between Cap+ Private Voice Calls and Data Calls -- Both enabled with Data Calls
(NOTE: No Clear Distinction between Cap+ Private Voice Calls and Data Calls -- Both enabled with Data Calls)
-I <dec> Specify TG to Hold During Trunking (DMR, P25, NXDN Type-C Trunking)
-U <port> Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)
-B <Hertz> Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF)

View File

@@ -1018,6 +1018,7 @@ typedef struct
//generic ks
int straight_ks;
int straight_mod;
int straight_discard;
uint8_t static_ks_bits[2][882];
int static_ks_counter[2];
@@ -1665,6 +1666,7 @@ void anytone_bp_keystream_creation(dsd_state * state, char * input);
void baofeng_ap_pc5_keystream_creation(dsd_state *state, char *input);
void csi72_ambe2_codeword_keystream(dsd_state * state, char ambe_fr[4][24]);
void straight_mod_xor_keystream_creation(dsd_state * state, char * input);
void caltta_bp_keystream_creation(dsd_state * state, char * input);
void auctus_keystream_creation(dsd_state * state, char * input);
void vertex_keystream_setup(dsd_state * state, char * input);
void vertex_40_keystream_creation(dsd_state * state, unsigned long long int key_value);

View File

@@ -93,6 +93,9 @@ void straight_mod_xor_keystream_creation(dsd_state * state, char * input)
}
else goto END_KS;
//debug
// fprintf (stderr, "\ncurr: %s\n", curr);
uint8_t ks_bytes[112];
memset (ks_bytes, 0, sizeof(ks_bytes));
parse_raw_user_string(curr, ks_bytes);
@@ -123,6 +126,125 @@ void straight_mod_xor_keystream_creation(dsd_state * state, char * input)
if (curr == NULL)
fprintf (stderr, "Straight KS String Malformed! No KS Created!\n");
else
{
curr = strtok(NULL, ":"); //optional discard value
if (curr != NULL)
{
len = 0;
sscanf (curr, "%hd", &len);
if (len != 0 && len < 8)
{
state->straight_discard = (int)len;
fprintf (stderr, "Optional Straight XOR Keystream Discard: %d; \n", len);
}
}
}
}
void caltta_bp_keystream_creation(dsd_state * state, char * input)
{
uint16_t len = 0;
char * curr;
curr = strtok(input, ":"); //should be len (mod) of key (decimal)
if (curr != NULL)
sscanf (curr, "%hd", &len);
else goto END_KS;
//len sanity check, can't be greater than 882
if (len > 256)
len = 256;
curr = strtok(NULL, ":"); //should be key in hex
if (curr != NULL)
{
//continue
}
else goto END_KS;
uint8_t ks_bytes[112];
memset (ks_bytes, 0, sizeof(ks_bytes));
parse_raw_user_string(curr, ks_bytes);
uint8_t ks_bits[896];
memset(ks_bits, 0, sizeof(ks_bits));
uint16_t unpack_len = len / 8;
if (len % 8)
unpack_len++;
unpack_byte_array_into_bit_array(ks_bytes, ks_bits, unpack_len);
for (uint16_t i = 0; i < len; i++)
{
state->static_ks_bits[0][i] = ks_bits[i];
state->static_ks_bits[1][i] = ks_bits[i];
}
fprintf (stderr,"Caltta BP %d-bit Keystream: ", len);
for (uint16_t i = 0; i < unpack_len; i++)
fprintf (stderr, "%02X", ks_bytes[i]);
fprintf (stderr, "\n");
state->straight_ks = 0x26;
state->straight_mod = (int)len;
END_KS:
if (curr == NULL)
fprintf (stderr, "Caltta BP KS String Malformed! No KS Created!\n");
}
void hytera_bp_keystream_creation(dsd_state * state, char * input)
{
uint16_t len = 0;
char * curr;
curr = strtok(input, ":"); //should be len (mod) of key (decimal)
if (curr != NULL)
sscanf (curr, "%hd", &len);
else goto END_KS;
//len sanity check, can't be greater than 882
if (len > 256)
len = 256;
curr = strtok(NULL, ":"); //should be key in hex
if (curr != NULL)
{
//continue
}
else goto END_KS;
uint8_t ks_bytes[112];
memset (ks_bytes, 0, sizeof(ks_bytes));
parse_raw_user_string(curr, ks_bytes);
uint8_t ks_bits[896];
memset(ks_bits, 0, sizeof(ks_bits));
uint16_t unpack_len = len / 8;
if (len % 8)
unpack_len++;
unpack_byte_array_into_bit_array(ks_bytes, ks_bits, unpack_len);
for (uint16_t i = 0; i < len; i++)
{
state->static_ks_bits[0][i] = ks_bits[i];
state->static_ks_bits[1][i] = ks_bits[i];
}
fprintf (stderr,"Hytera BP %d-bit Keystream: ", len);
for (uint16_t i = 0; i < unpack_len; i++)
fprintf (stderr, "%02X", ks_bytes[i]);
state->straight_ks = 0x68;
state->straight_mod = (int)len;
END_KS:
if (curr == NULL)
fprintf (stderr, "Hytera BP KS String Malformed! No KS Created!\n");
}

View File

@@ -1203,6 +1203,12 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[])
}
else if (slco == 0x5)
{
uint32_t unk = (uint32_t)ConvertBitIntoBytes(&slco_bits[4], 24);
fprintf (stderr, " SLCO Caltta: %06X;", unk);
}
else if (slco == 0xE)
{
uint32_t update_tgt = (uint32_t)ConvertBitIntoBytes(&slco_bits[4], 24);

View File

@@ -86,7 +86,7 @@ void dmr_late_entry_mi (dsd_opts * opts, dsd_state * state)
if (g[0] && g[1] && g[2])
{
if (slot == 0 && state->payload_algid != 0)
if (slot == 0 && state->payload_algid != 0 && state->payload_algid != 0x26)
{
if (state->payload_mi != mi_final)
{
@@ -116,7 +116,7 @@ void dmr_late_entry_mi (dsd_opts * opts, dsd_state * state)
}
}
if (slot == 1 && state->payload_algidR != 0)
if (slot == 1 && state->payload_algidR != 0 && state->payload_algidR != 0x26)
{
if (state->payload_miR != mi_final)
{
@@ -528,6 +528,7 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
if (alg == 2) fprintf (stderr, " DES;");
if (alg == 4) fprintf (stderr, " AES128;");
if (alg == 5) fprintf (stderr, " AES256;");
if (alg == 6) fprintf (stderr, " Caltta BP");
fprintf (stderr, "%s ", KNRM);
if (opts->payload == 1) fprintf (stderr, "\n");
if (state->payload_keyid != key)
@@ -550,6 +551,11 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
fprintf (stderr, "%s", KCYN);
fprintf (stderr, " Slot 2");
fprintf (stderr, " DMR LE SB ALG ID: %02X; KEY ID: %02X;", alg + 0x20, key);
if (alg == 1) fprintf (stderr, " RC4;");
if (alg == 2) fprintf (stderr, " DES;");
if (alg == 4) fprintf (stderr, " AES128;");
if (alg == 5) fprintf (stderr, " AES256;");
if (alg == 6) fprintf (stderr, " Caltta BP");
fprintf (stderr, "%s ", KNRM);
if (opts->payload == 1) fprintf (stderr, "\n");
if (state->payload_keyidR != key)

View File

@@ -146,7 +146,7 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
state->payload_algid = PI_BYTE[0];
state->payload_keyid = PI_BYTE[2];
state->payload_mi = ((unsigned long long int)PI_BYTE[3] << 24ULL) | ((unsigned long long int)PI_BYTE[4] << 16ULL) | ((unsigned long long int)PI_BYTE[5] << 8ULL) | ((unsigned long long int)PI_BYTE[6] << 0ULL);
if (state->payload_algid < 0x26)
if (state->payload_algid < 0x28)
{
fprintf (stderr, "%s ", KYEL);
fprintf (stderr, "\n Slot 1");
@@ -182,6 +182,13 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
state->payload_algid = 0x25;
}
else if ((state->payload_algid & 0x07) == 0x06)
{
fprintf (stderr, " Caltta BP;");
state->payload_algid = 0x26;
state->payload_mi = 0;
}
fprintf (stderr, "%s ", KNRM);
//expand the 32-bit MI to a 64-bit DES IV
@@ -199,7 +206,7 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
}
}
if (state->payload_algid >= 0x26)
if (state->payload_algid >= 0x28)
{
state->payload_algid = 0;
state->payload_keyid = 0;
@@ -249,6 +256,12 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
state->payload_algidR = 0x25;
}
else if ((state->payload_algidR & 0x07) == 0x06)
{
fprintf (stderr, " Caltta BP;");
state->payload_algidR = 0x26;
state->payload_miR = 0;
}
fprintf (stderr, "%s ", KNRM);
@@ -267,7 +280,7 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
}
}
if (state->payload_algidR >= 0x26)
if (state->payload_algidR >= 0x28)
{
state->payload_algidR = 0;
state->payload_keyidR = 0;

View File

@@ -112,6 +112,13 @@ void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state)
encL = 0;
}
}
else if (state->payload_algid == 0x26)
{
if (state->straight_ks == 0x26)
{
encL = 0;
}
}
}
if (encR)
@@ -142,6 +149,13 @@ void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state)
encR = 0;
}
}
else if (state->payload_algidR == 0x26)
{
if (state->straight_ks == 0x26)
{
encL = 0;
}
}
}
//debug disable enc check for AES testing
@@ -1151,6 +1165,13 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state)
encL = 0;
}
}
else if (state->payload_algid == 0x26)
{
if (state->straight_ks == 0x26)
{
encL = 0;
}
}
}
if (encR)
@@ -1181,6 +1202,13 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state)
encR = 0;
}
}
else if (state->payload_algidR == 0x26)
{
if (state->straight_ks == 0x26)
{
encR = 0;
}
}
}
//debug for AES

View File

@@ -1073,6 +1073,7 @@
state->any_bp = 0;
state->straight_ks = 0;
state->straight_mod = 0;
state->straight_discard = 0;
//ks array storage and counters
memset (state->ks_octetL, 0, sizeof(state->ks_octetL));
@@ -1555,6 +1556,11 @@
printf (" -H '736B9A9C5645288B 243AD5CB8701EF8A' \n");
printf (" -H '20029736A5D91042 C923EB0697484433 005EFC58A1905195 E28E9C7836AA2DB8' \n");
printf ("\n");
printf (" -H <hex> Manually Enter Caltta 10/32/64 Char Basic Privacy Hex Key (see example below)\n");
printf (" -H C:40:0292081081 \n");
printf (" -H C:128:736B9A9C5645288B243AD5CB8701EF8A' \n");
printf (" -H C:256:20029736A5D91042C923EB0697484433005EFC58A1905195E28E9C7836AA2DB8' \n");
printf ("\n");
printf (" -R <dec> Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value)\n");
printf (" \n");
printf (" -1 <hex> Manually Enter RC4 or DES Key Value (DMR, P25, NXDN) (Hex Value) \n");
@@ -1613,6 +1619,8 @@
printf (" -S 49:ED0AED4AED4AED4A\n");
printf (" For Example, Baofeng 49-bit Keystream for 56-bit Custom Encryption as:\n");
printf (" -S 49:11AA22BB33CC44\n");
printf (" For Example, Caltta 40-bit Keystream w/ optional 7-bit discard as:\n");
printf (" -S 49:11AA22BB33CC44:7\n");
printf (" \n");
printf (" -k <file> Import Key List from csv file (Decimal Format) -- Lower Case 'k'.\n");
printf (" Only supports NXDN, DMR Basic Privacy (decimal value). \n");
@@ -1643,7 +1651,7 @@
printf (" -p Disable Tune to Private Calls (DMR TIII, P25, NXDN Type-C and Type-D)\n");
printf (" -E Disable Tune to Group Calls (DMR TIII, Con+, Cap+, P25, NXDN Type-C, and Type-D)\n");
printf (" -e Enable Tune to Data Calls (DMR TIII, Cap+, NXDN Type-C)\n");
printf (" (NOTE: No Clear Distinction between Cap+ Private Voice Calls and Data Calls -- Both enabled with Data Calls \n");
printf (" (NOTE: No Clear Distinction between Cap+ Private Voice Calls and Data Calls -- Both enabled with Data Calls) \n");
printf (" -I <dec> Specify TG to Hold During Trunking (DMR, P25, NXDN Type-C Trunking)\n");
printf (" -U <port> Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)\n");
printf (" -B <Hertz> Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF)\n");
@@ -2288,32 +2296,38 @@
break;
case 'H':
//new handling for 10/32/64 Char Key
strncpy(opts.szNumbers, optarg, 1023);
opts.szNumbers[1023] = '\0';
state.K1 = strtoull (opts.szNumbers, &pEnd, 16);
state.K2 = strtoull (pEnd, &pEnd, 16);
state.K3 = strtoull (pEnd, &pEnd, 16);
state.K4 = strtoull (pEnd, &pEnd, 16);
fprintf (stderr, "Hytera40/128/256 BP or AES128/256 Key = %016llX %016llX %016llX %016llX\n", state.K1, state.K2, state.K3, state.K4);
opts.dmr_mute_encL = 0;
opts.dmr_mute_encR = 0;
if (state.K1 == 0 && state.K2 == 0 && state.K3 == 0 && state.K4 == 0)
//check for caltta, if not, then use older loader
if (optarg[0] == 'C' && optarg[1] == ':')
{
opts.dmr_mute_encL = 1;
opts.dmr_mute_encR = 1;
caltta_bp_keystream_creation(&state, optarg+2);
}
else
{
strncpy(opts.szNumbers, optarg, 1023);
opts.szNumbers[1023] = '\0';
state.K1 = strtoull (opts.szNumbers, &pEnd, 16);
state.K2 = strtoull (pEnd, &pEnd, 16);
state.K3 = strtoull (pEnd, &pEnd, 16);
state.K4 = strtoull (pEnd, &pEnd, 16);
fprintf (stderr, "Hytera40/128/256 BP or AES128/256 Key = %016llX %016llX %016llX %016llX\n", state.K1, state.K2, state.K3, state.K4);
opts.dmr_mute_encL = 0;
opts.dmr_mute_encR = 0;
if (state.K1 == 0 && state.K2 == 0 && state.K3 == 0 && state.K4 == 0)
{
opts.dmr_mute_encL = 1;
opts.dmr_mute_encR = 1;
}
state.H = state.K1; //shim still required?
//load the AES keys into a seperate handler
state.A1[0] = state.A1[1] = state.K1;
state.A2[0] = state.A2[1] = state.K2;
state.A3[0] = state.A3[1] = state.K3;
state.A4[0] = state.A4[1] = state.K4;
//disable keyloader function
state.keyloader = 0;
//signal an aes key is loaded into each slot -- if no value presented, then this won't matter anyways
state.aes_key_loaded[0] = state.aes_key_loaded[1] = 1;
}
state.H = state.K1; //shim still required?
//load the AES keys into a seperate handler
state.A1[0] = state.A1[1] = state.K1;
state.A2[0] = state.A2[1] = state.K2;
state.A3[0] = state.A3[1] = state.K3;
state.A4[0] = state.A4[1] = state.K4;
//disable keyloader function
state.keyloader = 0;
//signal an aes key is loaded into each slot -- if no value presented, then this won't matter anyways
state.aes_key_loaded[0] = state.aes_key_loaded[1] = 1;
break;
case '4':

View File

@@ -640,72 +640,87 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
opts->dmr_mute_encL = 0; //shim to unmute
}
//Hytera BP //TODO: Clean this mess up
if ( (state->K1 > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0 && state->dmr_fid == 0x68) ||
(state->K1 > 0 && state->forced_alg_id == 1) )
{
int pos = 0;
int pos = 0;
unsigned long long int k1 = state->K1;
unsigned long long int k2 = state->K2;
unsigned long long int k3 = state->K3;
unsigned long long int k4 = state->K4;
unsigned long long int k1 = state->K1;
unsigned long long int k2 = state->K2;
unsigned long long int k3 = state->K3;
unsigned long long int k4 = state->K4;
int T_Key[256] = {0};
int pN[882] = {0};
int T_Key[256] = {0};
int pN[882] = {0};
int len = 0;
int len = 0;
if (k2 == 0)
{
len = 39;
k1 = k1 << 24;
}
if (k2 != 0)
{
len = 127;
}
if (k4 != 0)
{
len = 255;
}
for (i = 0; i < 64; i++)
{
T_Key[i] = ( ((k1 << i) & 0x8000000000000000) >> 63 );
T_Key[i+64] = ( ((k2 << i) & 0x8000000000000000) >> 63 );
T_Key[i+128] = ( ((k3 << i) & 0x8000000000000000) >> 63 );
T_Key[i+192] = ( ((k4 << i) & 0x8000000000000000) >> 63 );
}
for (i = 0; i < 882; i++)
{
pN[i] = T_Key[pos];
pos++;
if (pos > len)
if (k2 == 0)
{
pos = 0;
len = 39;
k1 = k1 << 24;
}
}
//sanity check
if (state->DMRvcL > 17) //18
{
state->DMRvcL = 17; //18
}
pos = state->DMRvcL * 49;
if (memcmp(ambe_d, ambe_silence, 49) == 0)
pos += 49;
else
{
for(i = 0; i < 49; i++)
if (k2 != 0)
{
ambe_d[i] ^= pN[pos];
len = 127;
}
if (k4 != 0)
{
len = 255;
}
for (i = 0; i < 64; i++)
{
T_Key[i] = ( ((k1 << i) & 0x8000000000000000) >> 63 );
T_Key[i+64] = ( ((k2 << i) & 0x8000000000000000) >> 63 );
T_Key[i+128] = ( ((k3 << i) & 0x8000000000000000) >> 63 );
T_Key[i+192] = ( ((k4 << i) & 0x8000000000000000) >> 63 );
}
for (i = 0; i < 882; i++)
{
pN[i] = T_Key[pos];
pos++;
if (pos > len)
{
pos = 0;
}
}
//sanity check
if (state->DMRvcL > 17) //18
{
state->DMRvcL = 17; //18
}
pos = state->DMRvcL * 49;
if (memcmp(ambe_d, ambe_silence, 49) == 0)
pos += 49;
else
{
for(i = 0; i < 49; i++)
{
ambe_d[i] ^= pN[pos];
pos++;
}
}
state->DMRvcL++;
}
state->DMRvcL++;
//Caltta BP
if ( (state->straight_ks == 0x26 && state->dmr_so & 0x40 && state->payload_algid == 0x26) || //&& state->payload_keyid != 0
(state->straight_ks == 0x26 && state->forced_alg_id == 0x26) )
{
if (memcmp(ambe_d, ambe_silence, 49) == 0)
state->static_ks_counter[state->currentslot] += 56;
else
{
for (int i = 0; i < 49; i++)
ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%state->straight_mod] & 1); //Yikes!
state->static_ks_counter[state->currentslot] += 7;
}
}
//DMR and P25p2 DES-OFB 56 Handling, Slot 1, VCH 0 -- consider moving into the AES handler
@@ -1037,6 +1052,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
state->payload_algid = 0;
for (int i = 0; i < 49; i++)
ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%state->straight_mod] & 1); //Yikes!
//apply optional discard (i.e., caltta bp)
if (state->straight_discard != 0)
state->static_ks_counter[state->currentslot] += state->straight_discard;
}
}
@@ -1128,6 +1146,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
opts->dmr_mute_encR = 0; //shim to unmute
}
//Hytera BP //TODO: Clean this mess up
if ( (state->K1 > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0 && state->dmr_fidR == 0x68) ||
(state->K1 > 0 && state->forced_alg_id == 1))
{
@@ -1196,6 +1215,20 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
state->DMRvcR++;
}
//Caltta BP
if ( (state->straight_ks == 0x26 && state->dmr_soR & 0x40 && state->payload_algidR == 0x26) || //&& state->payload_keyidR != 0
(state->straight_ks == 0x26 && state->forced_alg_id == 0x26) )
{
if (memcmp(ambe_d, ambe_silence, 49) == 0)
state->static_ks_counter[state->currentslot] += 56;
else
{
for (int i = 0; i < 49; i++)
ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%state->straight_mod] & 1); //Yikes!
state->static_ks_counter[state->currentslot] += 7;
}
}
//DMR and P25p2 DES-OFB 56 Handling, Slot 2, VCH 1 -- Consider moving into AES handler
if ( (state->currentslot == 1 && state->payload_algidR == 0x22 && state->RR != 0) ||
(state->currentslot == 1 && state->payload_algidR == 0x81 && state->RR != 0) )
@@ -1524,6 +1557,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
state->payload_algidR = 0;
for (int i = 0; i < 49; i++)
ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%state->straight_mod] & 1); //Yikes!
//apply optional discard (i.e., caltta bp)
if (state->straight_discard != 0)
state->static_ks_counter[state->currentslot] += state->straight_discard;
}
}
@@ -1580,6 +1616,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
if (state->ken_sc == 1)
state->dmr_encL = 0;
if (state->payload_algid == 0x26 && state->straight_ks == 0x26)
state->dmr_encL = 0;
//reverse mute testing, only mute unencrypted traffic (slave piggyback dsd+ method)
if (opts->reverse_mute == 1)
{
@@ -1660,6 +1699,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
if (state->ken_sc == 1)
state->dmr_encR = 0;
if (state->payload_algidR == 0x26 && state->straight_ks == 0x26)
state->dmr_encR = 0;
//reverse mute testing, only mute unencrypted traffic (slave piggyback dsd+ method)
if (opts->reverse_mute == 1)
{

View File

@@ -1110,6 +1110,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (state->aes_key_loaded[0] != 0) { printw("KS: %016llX ", state->A4[0]); }
attron(COLOR_PAIR(3));
}
if (state->payload_algid == 0x26)
{
attron(COLOR_PAIR(1));
printw("Caltta BP ");
// if (state->aes_key_loaded[0] != 0) { printw("KS: %016llX ", state->A4[0]); } //TODO: This
attron(COLOR_PAIR(3));
}
if (state->payload_algid == 0x02)
{
attron(COLOR_PAIR(1));
@@ -1305,6 +1312,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (state->aes_key_loaded[1] != 0) { printw("KS: %016llX ", state->A4[1]); }
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0x26)
{
attron(COLOR_PAIR(1));
printw("Caltta BP ");
// if (state->aes_key_loaded[1] != 0) { printw("KS: %016llX ", state->A4[1]); } //TODO: This
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0x02)
{
attron(COLOR_PAIR(1));