diff --git a/include/dsd.h b/include/dsd.h index f883fcf..9fe6dfe 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -1660,6 +1660,7 @@ 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 lfsr_32_to_128(uint8_t * iv); void lfsr_64_to_128(uint8_t * iv); void LFSR128(dsd_state * state); void LFSR128n(dsd_state * state); diff --git a/src/dmr_pi.c b/src/dmr_pi.c index e6873df..defc7e3 100644 --- a/src/dmr_pi.c +++ b/src/dmr_pi.c @@ -374,6 +374,33 @@ void LFSR64(dsd_state * state) } } +//if supplied IV is only 32-bit in value, then expand it to a 128-bit IV using these LFSR taps (packed array) +void lfsr_32_to_128(uint8_t * iv) +{ + uint64_t lfsr = 0, bit = 0; + + lfsr = ((uint64_t)iv[0] << 24ULL) + ((uint64_t)iv[1] << 16ULL) + ((uint64_t)iv[2] << 8ULL) + ((uint64_t)iv[3] << 0ULL); + + uint8_t cnt = 0, x = 32; + + for(cnt = 0;cnt < 96; cnt++) + { + //32,22,2,1 (per Xilinx XAPP 052) Table 3: Taps for Maximum-Length LFSR Counters + bit = ( (lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0) ) & 0x1; + lfsr = (lfsr << 1) | bit; + + //continue packing iv + iv[x/8] = (iv[x/8] << 1) + bit; + + x++; + } + + fprintf (stderr, "\n IV(128): "); + for (x = 0; x < 16; x++) + fprintf (stderr, "%02X", iv[x]); + fprintf (stderr, "\n"); + +} //Expand a 32-bit MI into a 128-bit IV for AES void LFSR128d(dsd_state * state) diff --git a/src/dsd_file.c b/src/dsd_file.c index 8395a3a..27a045d 100644 --- a/src/dsd_file.c +++ b/src/dsd_file.c @@ -1027,7 +1027,7 @@ uint16_t ambe2_str_to_decode(dsd_opts * opts, dsd_state * state, char * ambe_str //force slot to 0 state->currentslot = 0; - uint8_t c3_hex = (uint64_t)ConvertBitIntoBytes(c3, 4); + uint8_t c3_hex = (uint8_t)ConvertBitIntoBytes(c3, 4); //debug // fprintf (stderr, "\n AMBE#: %02d / %d / %d; F: %X;", ambe2_counter, ambe2_counter/3, ambe2_counter%3, c3_hex); @@ -1035,17 +1035,6 @@ uint16_t ambe2_str_to_decode(dsd_opts * opts, dsd_state * state, char * ambe_str //use div and mod 3 to set current storage fragment state->late_entry_mi_fragment[0][(ambe2_counter/3)+1][ambe2_counter%3] = c3_hex; - //run LFSR evaluate stored codewords for matching IV or replace if not match or not set - if (ambe2_counter == 17) - { - if (state->forced_alg_id == 0x21 && state->payload_mi != 0) - { - fprintf (stderr, "\n"); - LFSR(state); - } - fprintf (stderr, "\n"); - dmr_late_entry_mi (opts, state); - } } char ambe_d[49]; memset(ambe_d, 0, sizeof(ambe_d)); @@ -1598,6 +1587,23 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state) } + //Forced Application of DMRA DES Mode (untested on .mbe real samples) + if (alg_id == 0x22 && state->R != 0 && state->payload_mi != 0) + { + //expand IV from 32 to 64 (late entry iv should fix this) + // if (alg_id == 0x22) + // LFSR64(state); + + uint8_t ks_bytes[375]; + memset(ks_bytes, 0, sizeof(ks_bytes)); + + des_multi_keystream_output(iv_hex, state->R, ks_bytes, 1, 32); //32*8=256 + + unpack_byte_array_into_bit_array(ks_bytes+8, ks, 256-8); + + ks_available = 1; + } + } //TODO: This else if (state->forced_alg_id == 1) //Basic Privacy @@ -1737,7 +1743,11 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state) //debug set value if (opts->payload == 1) - fprintf (stderr, "\n IV: %016llX;", iv_hex); //not really needed if loaded into array + { + if (iv_hex > 0xFFFFFFFF) + fprintf (stderr, "\n IV: %016llX;", iv_hex); + else fprintf (stderr, "\n IV: %08llX;", iv_hex); + } //debug print current str_buffer // fprintf (stderr, "\n Encryption MI/IV: %s", str_buffer); @@ -1789,10 +1799,14 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state) } - //P25 DES (v1 tested and working on P1, v2 should be okay now) - else if (alg_id == 0x81 && state->R != 0) + //P25 and DMR DES (v1 tested and working on P1, v2 should be okay now), DMR Untested but should be okay + else if ((alg_id == 0x22 || alg_id == 0x81) && state->R != 0) { + //expand IV from 32 to 64 + if (alg_id == 0x22) + LFSR64(state); + des_multi_keystream_output(iv_hex, state->R, ks_bytes, 1, 32); //32*8=256 if (protocol == 1) //Phase 1 IMBE start on 19 for DES-OFB (8 discard + 9 LCW + 2 reserved) @@ -1829,8 +1843,8 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state) } - //P25 AES (v1 and v2 tested working on P1) - else if ( (alg_id == 0x84 || alg_id == 0x89) && state->aes_key_loaded[0] == 1 ) + //P25 and DMR AES (v1 and v2 tested working on P1), working on DMR + else if ( (alg_id == 0x24 || alg_id == 0x25 || alg_id == 0x84 || alg_id == 0x89) && state->aes_key_loaded[0] == 1 ) { uint8_t aes_key[32]; @@ -1858,9 +1872,11 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state) aes_last_iv[i] = aes_iv[i]; //Resolve the longer IV from the shorter one - lfsr_64_to_128(aes_iv); + if (alg_id == 0x24 || alg_id == 0x25) + lfsr_32_to_128(aes_iv); + else lfsr_64_to_128(aes_iv); - if (alg_id == 0x89) //128, or 256 + if (alg_id == 0x89 || alg_id == 0x24) //128, or 256 aes_ofb_keystream_output(aes_iv, aes_key, ks_bytes, 0, 16); //16*16=256 else aes_ofb_keystream_output(aes_iv, aes_key, ks_bytes, 2, 16); //16*16=256 @@ -2024,6 +2040,15 @@ void read_sdrtrunk_json_format (dsd_opts * opts, dsd_state * state) //reset if over for DMR 18 AMBE+2 frames if (dmra_le && ambe2_counter == 18) { + //run LFSR evaluate stored codewords for matching IV or replace if not match or not set + if (state->forced_alg_id == 0x21 && state->payload_mi != 0) + { + fprintf (stderr, "\n"); + LFSR(state); + } + fprintf (stderr, "\n"); + dmr_late_entry_mi (opts, state); + ambe2_counter = 0; ks_idx = 0; }