From 0060378321a16cb533a6aee8e2e6a80f2e657653 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Thu, 16 Oct 2025 12:28:16 -0400 Subject: [PATCH] DMR: Connect Systems Extended Encryption Support; #321 --- .../cygwin_bat/complete_usage_options.txt | 5 +- include/dsd.h | 4 ++ src/crypt-tyt.c | 54 ++++++++++++++++++- src/dmr_bs.c | 14 +++++ src/dmr_ms.c | 14 +++++ src/dsd_main.c | 13 ++++- 6 files changed, 101 insertions(+), 3 deletions(-) diff --git a/examples/cygwin_bat/complete_usage_options.txt b/examples/cygwin_bat/complete_usage_options.txt index 36fffcb..173e86c 100644 --- a/examples/cygwin_bat/complete_usage_options.txt +++ b/examples/cygwin_bat/complete_usage_options.txt @@ -1,4 +1,4 @@ -Build Version: AW 2025-202-geb24239 +Build Version: AW 2025-203-g8ea6415 MBElib Version: 1.3.4 CODEC2 Support Enabled @@ -193,6 +193,9 @@ Advanced Decoder options: -+ 'ABCDABCDABCDABCD ABDCDABCDABCDABC' -+ 'ABCDABCDABCDABCD ABDCDABCDABCDABC EF01EF01EF01EF01 EF01EF01EF01EF01' + -^ Manually Enter and Enforce Connect Systems 72-bit (9-byte) Extended Encryption Hex Key (see example below) + -^ 3BBE782C0430008271 + -9 Manually Enter and Enforce Kenwood 15-bit Scrambler Key Value (DMR) (Dec Value) -A Manually Enter and Enforce Anytone 16-bit BP Key Value (DMR) (Hex Value) diff --git a/include/dsd.h b/include/dsd.h index 7fd0d1b..c4e97a5 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -1005,6 +1005,9 @@ typedef struct //baofeng ap int baofeng_ap; + //connect systems ee + int csi_ee; + //generic ks int straight_ks; int straight_mod; @@ -1648,6 +1651,7 @@ void retevis_rc2_keystream_creation(dsd_state *state, char *input); void ken_dmr_scrambler_keystream_creation(dsd_state * state, char * input); 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); //Kirisun diff --git a/src/crypt-tyt.c b/src/crypt-tyt.c index e9c30db..93993a7 100644 --- a/src/crypt-tyt.c +++ b/src/crypt-tyt.c @@ -306,4 +306,56 @@ void tyt_ep_aes_keystream_creation(dsd_state * state, char * input) fprintf (stderr,"DMR TYT EP (AES-128) Key %016llX%016llX with Forced Application\n", K1, K2); state->tyt_ep = 1; -} \ No newline at end of file +} + +//connect systems 72-bit (9-byte) Extended Encryption //TODO: Move this later +void csi72_ambe2_codeword_keystream(dsd_state * state, char ambe_fr[4][24]) +{ + + char interleaved[72]; + memset (interleaved, 0, sizeof(interleaved)); + + //interleave the frame + const int *w, *x, *y, *z; + w = rW; x = rX; y = rY; z = rZ; + + for (int8_t i = 0; i < 36; i++) + { + interleaved[(i*2)+0] = ambe_fr[*w][*x]; + interleaved[(i*2)+1] = ambe_fr[*y][*z]; + + w++; + x++; + y++; + z++; + } + + uint8_t ks_bytes[9]; memset(ks_bytes, 0, sizeof(ks_bytes)); + uint8_t ks[72]; memset(ks, 0, sizeof(ks)); + + //keys are loaded in reverse byte order, stored in state->static_ks_bits[0] + for (int i = 0; i < 9; i++) + ks_bytes[i] = state->static_ks_bits[0][8-i]; + + //convert byte array into a bit array + unpack_byte_array_into_bit_array(ks_bytes, ks, 9); + + //apply keystream to interleave + for (int8_t i = 0; i < 72; i++) + interleaved[i] ^= ks[71-i]; + + //deinterleave back into ambe_fr frame + w = rW; x = rX; y = rY; z = rZ; + int k = 0; + for (int8_t i = 0; i < 36; i++) + { + ambe_fr[*w][*x] = interleaved[k++]; + ambe_fr[*y][*z] = interleaved[k++]; + + w++; + x++; + y++; + z++; + } + +} diff --git a/src/dmr_bs.c b/src/dmr_bs.c index 1bf90f5..b22c5b0 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -502,6 +502,13 @@ void dmrBS (dsd_opts * opts, dsd_state * state) tyt16_ambe2_codeword_keystream(state, ambe_fr3, 0); } + if (state->csi_ee == 1) + { + csi72_ambe2_codeword_keystream(state, ambe_fr); + csi72_ambe2_codeword_keystream(state, ambe_fr2); + csi72_ambe2_codeword_keystream(state, ambe_fr3); + } + #ifdef PRINT_AMBE72 ambe2_codeword_print_i(opts, ambe_fr); ambe2_codeword_print_i(opts, ambe_fr2); @@ -954,6 +961,13 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state) tyt16_ambe2_codeword_keystream(state, ambe_fr3, 0); } + if (state->csi_ee == 1) + { + csi72_ambe2_codeword_keystream(state, ambe_fr); + csi72_ambe2_codeword_keystream(state, ambe_fr2); + csi72_ambe2_codeword_keystream(state, ambe_fr3); + } + #ifdef PRINT_AMBE72 ambe2_codeword_print_i(opts, ambe_fr); ambe2_codeword_print_i(opts, ambe_fr2); diff --git a/src/dmr_ms.c b/src/dmr_ms.c index 6de13ce..c4021cf 100644 --- a/src/dmr_ms.c +++ b/src/dmr_ms.c @@ -263,6 +263,13 @@ void dmrMS (dsd_opts * opts, dsd_state * state) tyt16_ambe2_codeword_keystream(state, ambe_fr3, 0); } + if (state->csi_ee == 1) + { + csi72_ambe2_codeword_keystream(state, ambe_fr); + csi72_ambe2_codeword_keystream(state, ambe_fr2); + csi72_ambe2_codeword_keystream(state, ambe_fr3); + } + #ifdef PRINT_AMBE72 ambe2_codeword_print_i(opts, ambe_fr); ambe2_codeword_print_i(opts, ambe_fr2); @@ -574,6 +581,13 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state) tyt16_ambe2_codeword_keystream(state, ambe_fr3, 0); } + if (state->csi_ee == 1) + { + csi72_ambe2_codeword_keystream(state, ambe_fr); + csi72_ambe2_codeword_keystream(state, ambe_fr2); + csi72_ambe2_codeword_keystream(state, ambe_fr3); + } + #ifdef PRINT_AMBE72 ambe2_codeword_print_i(opts, ambe_fr); ambe2_codeword_print_i(opts, ambe_fr2); diff --git a/src/dsd_main.c b/src/dsd_main.c index e993507..23d21af 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1066,6 +1066,7 @@ state->tyt_ep = 0; state->retevis_ap = 0; state->baofeng_ap = 0; + state->csi_ee = 0; state->ken_sc = 0; state->any_bp = 0; @@ -1585,6 +1586,9 @@ printf (" -+ 'ABCDABCDABCDABCD ABDCDABCDABCDABC' \n"); printf (" -+ 'ABCDABCDABCDABCD ABDCDABCDABCDABC EF01EF01EF01EF01 EF01EF01EF01EF01' \n"); printf (" \n"); + printf (" -^ Manually Enter and Enforce Connect Systems 72-bit (9-byte) Extended Encryption Hex Key (see example below)\n"); + printf (" -^ 3BBE782C0430008271\n"); + printf (" \n"); printf (" -9 Manually Enter and Enforce Kenwood 15-bit Scrambler Key Value (DMR) (Dec Value) \n"); printf (" \n"); printf (" -A Manually Enter and Enforce Anytone 16-bit BP Key Value (DMR) (Hex Value) \n"); @@ -1915,7 +1919,7 @@ exitflag = 0; - while ((c = getopt (argc, argv, "~yhaepPqs:t:v:z:i:o:d:c:g:n:w:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:YK:b:H:X:NQ:WrlZTF@:!:01:2:345:6:7:8*:9:Ek:I:J:O+:")) != -1) + while ((c = getopt (argc, argv, "~yhaepPqs:t:v:z:i:o:d:c:g:n:w:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:YK:b:H:X:NQ:WrlZTF@:!:01:2:345:6:^:7:8*:9:Ek:I:J:O+:")) != -1) { switch (c) @@ -2014,6 +2018,13 @@ tyt_ep_aes_keystream_creation(&state, optarg); break; + //get user CSI EE Key and Force Its application + case '^': + parse_raw_user_string(optarg, state.static_ks_bits[0]); + fprintf (stderr,"DMR CS Extended 72-bit Key with Forced Application\n"); + state.csi_ee = 1; + break; + //get user Kenwood DMR Scrambler Key and Force Its application case '9': ken_dmr_scrambler_keystream_creation(&state, optarg);