diff --git a/examples/cygwin_bat/complete_usage_options.txt b/examples/cygwin_bat/complete_usage_options.txt index dc051e4..a7d2e0f 100644 --- a/examples/cygwin_bat/complete_usage_options.txt +++ b/examples/cygwin_bat/complete_usage_options.txt @@ -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 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 Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value) -1 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 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 Specify TG to Hold During Trunking (DMR, P25, NXDN Type-C Trunking) -U Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++) -B Set RIGCTL Setmod Bandwidth in Hertz (0 - default - OFF) diff --git a/include/dsd.h b/include/dsd.h index 2d8ddc0..d504639 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -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); diff --git a/src/crypt-etc.c b/src/crypt-etc.c index 835b469..97aaf80 100644 --- a/src/crypt-etc.c +++ b/src/crypt-etc.c @@ -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"); } diff --git a/src/dmr_flco.c b/src/dmr_flco.c index cf138ba..7b3990b 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -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); diff --git a/src/dmr_le.c b/src/dmr_le.c index 2789930..cf617a8 100644 --- a/src/dmr_le.c +++ b/src/dmr_le.c @@ -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) diff --git a/src/dmr_pi.c b/src/dmr_pi.c index defc7e3..6772e8a 100644 --- a/src/dmr_pi.c +++ b/src/dmr_pi.c @@ -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; diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c index 4f0402b..53902dd 100644 --- a/src/dsd_audio2.c +++ b/src/dsd_audio2.c @@ -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 diff --git a/src/dsd_main.c b/src/dsd_main.c index d43da5d..021717b 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -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 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 Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value)\n"); printf (" \n"); printf (" -1 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 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 Specify TG to Hold During Trunking (DMR, P25, NXDN Type-C Trunking)\n"); printf (" -U Enable RIGCTL/TCP; Set TCP Port for RIGCTL. (4532 on SDR++)\n"); printf (" -B 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': diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index 0110f19..3f925a3 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -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) { diff --git a/src/dsd_ncurses_printer.c b/src/dsd_ncurses_printer.c index 8839da5..57f4447 100644 --- a/src/dsd_ncurses_printer.c +++ b/src/dsd_ncurses_printer.c @@ -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));