From a5151686eca1133276ffe9d7ef052af92c0d8d05 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 22 Aug 2025 14:02:09 -0400 Subject: [PATCH] Add Generic Static AMBE Keystream Support; #303 Adding a new method to allow a user to enter a generic keystream len and static keystream via a string that is loaded into a bit array to xor against ambe frames; This method is intended to be used to allow --- include/dsd.h | 5 +++++ src/crypt-etc.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ src/dsd_main.c | 31 +++++++++++++++++++++-------- src/dsd_mbe.c | 20 +++++++++++++++++++ 4 files changed, 101 insertions(+), 8 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index fae8e3b..c9e2c54 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -998,6 +998,10 @@ typedef struct //anytone bp int any_bp; + //generic ks + int straight_ks; + int straight_mod; + uint8_t static_ks_bits[2][882]; int static_ks_counter[2]; @@ -1632,6 +1636,7 @@ void tyt_ap_pc4_keystream_creation(dsd_state * state, char * input); //Misc Other Encryption Modes void ken_dmr_scrambler_keystream_creation(dsd_state * state, char * input); void anytone_bp_keystream_creation(dsd_state * state, char * input); +void straight_mod_xor_keystream_creation(dsd_state * state, char * input); //Hytera Enhanced void hytera_enhanced_rc4_setup(dsd_opts * opts, dsd_state * state, unsigned long long int key_value, unsigned long long int mi_value); diff --git a/src/crypt-etc.c b/src/crypt-etc.c index 5b635c3..e108c6b 100644 --- a/src/crypt-etc.c +++ b/src/crypt-etc.c @@ -70,4 +70,57 @@ void anytone_bp_keystream_creation(dsd_state * state, char * input) fprintf (stderr,"DMR Anytone Basic 16-bit Key 0x%04X with Forced Application\n", key); state->any_bp = 1; +} + +void straight_mod_xor_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 > 882) + len = 882; + + 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,"AMBE Straight XOR %d-bit Keystream: ", len); + for (uint16_t i = 0; i < unpack_len; i++) + fprintf (stderr, "%02X", ks_bytes[i]); + fprintf (stderr, " with Forced Application \n"); + + state->straight_ks = 1; + state->straight_mod = (int)len; + + END_KS: + + if (curr == NULL) + fprintf (stderr, "Straight KS String Malformed! No KS Created!\n"); + } \ No newline at end of file diff --git a/src/dsd_main.c b/src/dsd_main.c index 9f9b143..2377e5c 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1067,6 +1067,8 @@ state->ken_sc = 0; state->any_bp = 0; + state->straight_ks = 0; + state->straight_mod = 0; //ks array storage and counters memset (state->ks_octetL, 0, sizeof(state->ks_octetL)); @@ -1485,8 +1487,8 @@ printf (" Input Rate Default is 48000; Use Multiples of 8000 up to 48000.\n"); printf (" VOX Enabled on 1; (Default = 0)\n"); printf (" Values not entered into the M17: string are set to default values.\n"); - printf (" -S M17 Packet Encoder SMS String: No more than 772 chars, use single quotations (see example above).\n"); - printf (" -S M17 Stream Encoder SMS String: No more than 48 chars, activates 1600 voice (best if broken into six 8 char chunks).\n"); + // printf (" -S M17 Packet Encoder SMS String: No more than 772 chars, use single quotations (see example above).\n"); + // printf (" -S M17 Stream Encoder SMS String: No more than 48 chars, activates 1600 voice (best if broken into six 8 char chunks).\n"); printf ("Decoder options:\n"); printf (" -fa Auto Detection\n"); printf (" -fA Passive Analog Audio Monitor\n"); @@ -1571,6 +1573,14 @@ printf (" \n"); printf (" -A Manually Enter and Enforce Anytone 16-bit BP Key Value (DMR) (Hex Value) \n"); printf (" \n"); + printf (" -S Manually Enter and Enforce Generic Static Keystream -> Length and BYTE PACKED / ALIGNED String for AMBE (up to 882 bits)\n"); + printf (" For Example, enter 16-bit Keystream 0909 as:\n"); + printf (" -S 16:0909\n"); + printf (" For Example, enter 49-bit Keystream as:\n"); + printf (" -S 49:123456789ABC80\n"); + printf (" For Example, enter 49-bit Keystream (MBP 70) as:\n"); + printf (" -S 49:ED0AED4AED4AED4A\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"); printf (" (dPMR and Hytera 32/64 char not supported, DMR uses TG value as key id -- EXPERIMENTAL!!). \n"); @@ -1931,12 +1941,12 @@ state.m17dat[49] = '\0'; break; - //Specify M17 encoder SMS Message (truncates at 772) - case 'S': - strncpy(state.m17sms, optarg, 772); - state.m17sms[772] = '\0'; - state.m17_str_dt = 3; //flip this so that STR encoder knows to use 1600 voice + data - break; + // //Specify M17 encoder SMS Message (truncates at 772) + // case 'S': + // strncpy(state.m17sms, optarg, 772); + // state.m17sms[772] = '\0'; + // state.m17_str_dt = 3; //flip this so that STR encoder knows to use 1600 voice + data + // break; //specify TG Hold value case 'I': @@ -1992,6 +2002,11 @@ case 'A': anytone_bp_keystream_creation(&state, optarg); break; + + //Straight KS Generation + case 'S': + straight_mod_xor_keystream_creation(&state, optarg); + break; case '3': opts.dmr_le = 0; diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index c59c8c1..da24bd8 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -892,6 +892,16 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%16] & 1); //Yikes! } + //Generic Straight Static Keystream + if (state->straight_ks == 1) + { + //disable enc identifiers, if present + state->dmr_so = 0; + 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! + } + mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality); @@ -1257,6 +1267,16 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%16] & 1); //Yikes! } + //Generic Straight Static Keystream + if (state->straight_ks == 1) + { + //disable enc identifiers, if present + state->dmr_soR = 0; + 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! + } + mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR, ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);