mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-09 15:27:22 -05:00
DMR: Add 15-bit scrambler method for Kenwood Radios; #303
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
Build Version: AW 2025-173-g21c02ac
|
||||
Build Version: AW 2025-175-ga5b9984
|
||||
MBElib Version: 1.3.4
|
||||
CODEC2 Support Enabled
|
||||
|
||||
@@ -173,16 +173,18 @@ Advanced Decoder options:
|
||||
|
||||
-1 <hex> Manually Enter RC4 or DES Key Value (DMR, P25, NXDN) (Hex Value)
|
||||
|
||||
-2 <hex> Manually Enter TYT and Enforce 16-bit BP Key Value (DMR) (Hex Value)
|
||||
-2 <hex> Manually Enter and TYT Enforce 16-bit BP Key Value (DMR) (Hex Value)
|
||||
|
||||
-! <hex> Manually Enter TYT and Enforce Advanced Privacy (PC4) AP Hex Key (see example below)
|
||||
-! <hex> Manually Enter and Enforce TYT Advanced Privacy (PC4) AP Hex Key (see example below)
|
||||
Encapulate in Single Quotation Marks; Space every 16 chars.
|
||||
-! '736B9A9C5645288B 243AD5CB8701EF8A'
|
||||
|
||||
-5 <hex> Manually Enter TYT and Enforce Enhanced Privacy (AES-128) EP Hex Key (see example below)
|
||||
-5 <hex> Manually Enter and Enforce TYT Enhanced Privacy (AES-128) EP Hex Key (see example below)
|
||||
Encapulate in Single Quotation Marks; Space every 16 chars.
|
||||
-5 '736B9A9C5645288B 243AD5CB8701EF8A'
|
||||
|
||||
-9 <dec> Manually Enter and Enforce Kenwood 15-bit Scrambler Key Value (DMR) (Dec Value)
|
||||
|
||||
-k <file> Import Key List from csv file (Decimal Format) -- Lower Case 'k'.
|
||||
Only supports NXDN, DMR Basic Privacy (decimal value).
|
||||
(dPMR and Hytera 32/64 char not supported, DMR uses TG value as key id -- EXPERIMENTAL!!).
|
||||
|
||||
@@ -992,6 +992,11 @@ typedef struct
|
||||
int tyt_bp;
|
||||
int tyt_ep;
|
||||
|
||||
//kenwood scrambler on DMR with forced application
|
||||
int ken_sc;
|
||||
uint8_t static_ks_bits[2][882];
|
||||
int static_ks_counter[2];
|
||||
|
||||
} dsd_state;
|
||||
|
||||
/*
|
||||
|
||||
@@ -56,6 +56,19 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
||||
target = (uint32_t)ConvertBitIntoBytes(&lc_bits[24], 24); //Target or Talk Group
|
||||
source = (uint32_t)ConvertBitIntoBytes(&lc_bits[48], 24);
|
||||
|
||||
//Kenwood w/ Scrambler Application on DMR (disable this if clash with other link control, its obscure)
|
||||
uint8_t is_kenwood_sc = 1;
|
||||
if (*IrrecoverableErrors == 0 && CRCCorrect == 1 && pf == 1 && fid == 0x20 && (so & 0x40) == 0x40)
|
||||
{
|
||||
pf = 0; //turn off PF flag
|
||||
fid = 0; //unclear if this signals FID (or is cipher type for scrambler)
|
||||
|
||||
//reset bit counter on static key bit counter (should do this after VC6 instead of relying on this, but meh, obscure cipher type)
|
||||
state->static_ks_counter[state->currentslot] = 0;
|
||||
|
||||
is_kenwood_sc = 1;
|
||||
}
|
||||
|
||||
//read ahead a little to get this for the xpt flag
|
||||
if (*IrrecoverableErrors == 0 && flco == 0x09 && fid == 0x68)
|
||||
{
|
||||
@@ -295,7 +308,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
||||
|
||||
//unknown other manufacturer or OTA ENC, etc.
|
||||
//removed tait from the list, added hytera 0x08
|
||||
if (fid != 0 && fid != 0x68 && fid != 0x10 && fid != 0x08)
|
||||
if (fid != 0 && fid != 0x68 && fid != 0x10 && fid != 0x08 && is_kenwood_sc == 0)
|
||||
{
|
||||
if (type == 1) fprintf (stderr, "%s \n", KYEL);
|
||||
if (type == 2) fprintf (stderr, "%s \n", KYEL);
|
||||
@@ -651,6 +664,9 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
|
||||
state->gi[slot] = 1;
|
||||
}
|
||||
|
||||
if (is_kenwood_sc)
|
||||
fprintf(stderr, "Kenwood Scrambler ");
|
||||
|
||||
fprintf(stderr, "Call ");
|
||||
|
||||
|
||||
|
||||
@@ -607,6 +607,9 @@
|
||||
memset (state->s_ru, 0, sizeof(state->s_ru));
|
||||
memset (state->s_l4u, 0, sizeof(state->s_l4u));
|
||||
memset (state->s_r4u, 0, sizeof(state->s_r4u));
|
||||
|
||||
//we do reset the counter, but not the static_ks_bits
|
||||
memset (state->static_ks_counter, 0, sizeof(state->static_ks_counter));
|
||||
|
||||
} //nocarrier
|
||||
|
||||
@@ -1086,6 +1089,8 @@
|
||||
state->tyt_ap = 0;
|
||||
state->tyt_bp = 0;
|
||||
state->tyt_ep = 0;
|
||||
|
||||
state->ken_sc = 0;
|
||||
|
||||
//ks array storage and counters
|
||||
memset (state->ks_octetL, 0, sizeof(state->ks_octetL));
|
||||
@@ -1095,6 +1100,9 @@
|
||||
state->octet_counter = 0;
|
||||
state->bit_counterL = 0;
|
||||
state->bit_counterR = 0;
|
||||
|
||||
memset (state->static_ks_bits, 0, sizeof(state->static_ks_bits));
|
||||
memset (state->static_ks_counter, 0, sizeof(state->static_ks_counter));
|
||||
|
||||
//AES Specific Variables
|
||||
memset (state->aes_key, 0, sizeof(state->aes_key));
|
||||
@@ -1579,16 +1587,18 @@
|
||||
printf (" \n");
|
||||
printf (" -1 <hex> Manually Enter RC4 or DES Key Value (DMR, P25, NXDN) (Hex Value) \n");
|
||||
printf (" \n");
|
||||
printf (" -2 <hex> Manually Enter TYT and Enforce 16-bit BP Key Value (DMR) (Hex Value) \n");
|
||||
printf (" -2 <hex> Manually Enter and TYT Enforce 16-bit BP Key Value (DMR) (Hex Value) \n");
|
||||
printf (" \n");
|
||||
printf (" -! <hex> Manually Enter TYT and Enforce Advanced Privacy (PC4) AP Hex Key (see example below)\n");
|
||||
printf (" -! <hex> Manually Enter and Enforce TYT Advanced Privacy (PC4) AP Hex Key (see example below)\n");
|
||||
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
|
||||
printf (" -! '736B9A9C5645288B 243AD5CB8701EF8A' \n");
|
||||
printf (" \n");
|
||||
printf (" -5 <hex> Manually Enter TYT and Enforce Enhanced Privacy (AES-128) EP Hex Key (see example below)\n");
|
||||
printf (" -5 <hex> Manually Enter and Enforce TYT Enhanced Privacy (AES-128) EP Hex Key (see example below)\n");
|
||||
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
|
||||
printf (" -5 '736B9A9C5645288B 243AD5CB8701EF8A' \n");
|
||||
printf (" \n");
|
||||
printf (" -9 <dec> Manually Enter and Enforce Kenwood 15-bit Scrambler Key Value (DMR) (Dec Value) \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");
|
||||
printf (" (dPMR and Hytera 32/64 char not supported, DMR uses TG value as key id -- EXPERIMENTAL!!). \n");
|
||||
@@ -1907,7 +1917,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:89Ek: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:89:Ek:I:J:O")) != -1)
|
||||
{
|
||||
|
||||
switch (c)
|
||||
@@ -1962,12 +1972,6 @@
|
||||
fprintf (stderr, "TG Hold set to %d \n", state.tg_hold);
|
||||
break;
|
||||
|
||||
case '9': //Leaving Enabled to maintain backwards compatability
|
||||
state.ea_mode = 0;
|
||||
state.esk_mask = 0;
|
||||
fprintf (stderr,"Force Enabling EDACS Standard/Networked Mode Mode without ESK.\n");
|
||||
break;
|
||||
|
||||
//experimental audio monitoring
|
||||
case '8':
|
||||
opts.monitor_input_audio = 1;
|
||||
@@ -2054,9 +2058,35 @@
|
||||
//load static keystream into ctx.bits since that isn't ever zeroed out
|
||||
for (int i = 0; i < 49; i++)
|
||||
ctx.bits[i] = ks_bits[i];
|
||||
fprintf (stderr,"DMR TYT EP (AES-128) Key %016llX %016llX with Forced Application\n", K1, K2);
|
||||
fprintf (stderr,"DMR TYT EP (AES-128) Key %016llX%016llX with Forced Application\n", K1, K2);
|
||||
state.tyt_ep = 1;
|
||||
break;
|
||||
|
||||
case '9':
|
||||
/*
|
||||
SLOT 1 Protected LC FLCO=0x00 FID=0x20 <--this link appears to indicate scrambler usage from Kenwood on DMR
|
||||
DMR PDU Payload [80][20][40][00][00][01][00][00][01] SB: 00000000000 - 000;
|
||||
|
||||
SLOT 1 TGT=1 SRC=1 FLCO=0x00 FID=0x00 SVC=0x00 Group Call <--same call, but no scrambler on same Kenwood Radio
|
||||
DMR PDU Payload [00][00][00][00][00][01][00][00][01]
|
||||
|
||||
For This, we could possible transition this to not be enforced
|
||||
since we may have a positive indicator in link control,
|
||||
but needs further samples and validation
|
||||
*/
|
||||
int lfsr = 0, bit = 0;
|
||||
sscanf (optarg, "%ld", &lfsr);
|
||||
fprintf (stderr,"DMR Kenwood 15-bit Scrambler Key %05d with Forced Application\n", lfsr);
|
||||
for (int i = 0; i < 882; i++)
|
||||
{
|
||||
state.static_ks_bits[0][i] = lfsr & 0x1;
|
||||
state.static_ks_bits[1][i] = lfsr & 0x1;
|
||||
bit = ( (lfsr >> 1) ^ (lfsr >> 0) ) & 1;
|
||||
lfsr = ( (lfsr >> 1 ) | (bit << 14) );
|
||||
}
|
||||
|
||||
state.ken_sc = 1;
|
||||
break;
|
||||
|
||||
case '3':
|
||||
opts.dmr_le = 0;
|
||||
|
||||
@@ -832,6 +832,13 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
ambe_d[i] ^= (uint8_t)(ctx.bits[i] & 1);
|
||||
}
|
||||
|
||||
//DMR Kenwood Scrambler, Either Slot (static single key'd enforced KS) //should probably break this up, but this is a test for now
|
||||
if (state->ken_sc == 1)
|
||||
{
|
||||
for (int i = 0; i < 49; i++)
|
||||
ambe_d[i] ^= (uint8_t)(state->static_ks_bits[state->currentslot][(state->static_ks_counter[state->currentslot]++)%882] & 1); //Yikes!
|
||||
}
|
||||
|
||||
//P25p2 RC4 Handling, VCH 0
|
||||
if (state->currentslot == 0 && state->payload_algid == 0xAA && state->R != 0 && ((state->synctype == 35) || (state->synctype == 36)))
|
||||
{
|
||||
@@ -1267,6 +1274,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
}
|
||||
}
|
||||
|
||||
if (state->ken_sc == 1)
|
||||
state->dmr_encL = 0;
|
||||
|
||||
//reverse mute testing, only mute unencrypted traffic (slave piggyback dsd+ method)
|
||||
if (opts->reverse_mute == 1)
|
||||
{
|
||||
@@ -1344,6 +1354,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
}
|
||||
}
|
||||
|
||||
if (state->ken_sc == 1)
|
||||
state->dmr_encR = 0;
|
||||
|
||||
//reverse mute testing, only mute unencrypted traffic (slave piggyback dsd+ method)
|
||||
if (opts->reverse_mute == 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user