RC4 Support (DMR, P25p1, P25p2);

This commit is contained in:
lwvmobile
2023-06-11 00:11:55 -04:00
parent 20f0c852aa
commit 8186b62a91
14 changed files with 747 additions and 91 deletions

View File

@@ -521,13 +521,27 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
if (state->K1 != 0 && fid == 0x68 && so & 0x40)
{
fprintf (stderr, "\n");
if (state->K2 != 0) fprintf (stderr, "\n ");
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " Key %010llX ", state->K1);
fprintf (stderr, "Key %010llX ", state->K1);
if (state->K2 != 0) fprintf (stderr, "%016llX ", state->K2);
if (state->K4 != 0) fprintf (stderr, "%016llX %016llX", state->K3, state->K4);
fprintf (stderr, "%s ", KNRM);
}
}
if (slot == 0 && state->payload_algid == 0x21 && state->R != 0)
{
fprintf (stderr, "%s", KYEL);
fprintf (stderr, "Key %010llX ", state->R);
fprintf (stderr, "%s ", KNRM);
}
if (slot == 1 && state->payload_algidR == 0x21 && state->RR != 0)
{
fprintf (stderr, "%s", KYEL);
fprintf (stderr, "Key %010llX ", state->RR);
fprintf (stderr, "%s ", KNRM);
}
}

View File

@@ -13,6 +13,23 @@ void dmr_late_entry_mi_fragment (dsd_opts * opts, dsd_state * state, uint8_t vc,
{
uint8_t slot = state->currentslot;
//enforce RC4 due to missing PI header, but with valid SVC Opts
//ideally, this would be handled by VC-F single burst, but its not fully reliable compared to this
//due to multiple signalling occurring inside of it, depending on system type
if (state->M == 0x21)
{
if (slot == 0 && state->dmr_so & 0x40)
{
state->payload_algid = 0x21;
state->payload_keyid = 0xFF;
}
if (slot == 1 && state->dmr_soR & 0x40)
{
state->payload_algidR = 0x21;
state->payload_keyidR = 0xFF;
}
}
//collect our fragments and place them into storage
state->late_entry_mi_fragment[slot][vc][0] = (uint64_t)ConvertBitIntoBytes(&ambe_fr[3][0], 4);

View File

@@ -146,7 +146,8 @@ int csvChanImport(dsd_opts * opts, dsd_state * state) //channel map import
return 0;
}
int csvKeyImport(dsd_opts * opts, dsd_state * state) //multi-key support
//Decimal Variant of Key Import
int csvKeyImportDec(dsd_opts * opts, dsd_state * state) //multi-key support
{
char filename[1024] = "filename.csv";
sprintf (filename, "%s", opts->key_in_file);
@@ -210,3 +211,48 @@ int csvKeyImport(dsd_opts * opts, dsd_state * state) //multi-key support
fclose(fp);
return 0;
}
//Hex Variant of Key Import
int csvKeyImportHex(dsd_opts * opts, dsd_state * state) //key import for rc4 keys
{
char filename[1024] = "filename.csv";
sprintf (filename, "%s", opts->key_in_file);
char buffer[BSIZE];
FILE * fp;
fp = fopen(filename, "r");
if (fp == NULL) {
printf("Unable to open file '%s'\n", filename);
exit(1);
}
int row_count = 0;
int field_count = 0;
unsigned long long int keynumber;
while (fgets(buffer, BSIZE, fp)) {
field_count = 0;
row_count++;
if (row_count == 1)
continue; //don't want labels
char * field = strtok(buffer, ","); //seperate by comma
while (field) {
if (field_count == 0)
{
sscanf (field, "%llX", &keynumber);
}
if (field_count == 1)
{
sscanf (field, "%llX", &state->rkey_array[keynumber]);
}
field = strtok(NULL, ",");
field_count++;
}
fprintf (stderr, "Key [%04llX] [%016llX]", keynumber, state->rkey_array[keynumber]);
fprintf (stderr, "\n");
}
fclose(fp);
return 0;
}

View File

@@ -374,7 +374,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
//unload keys when using keylaoder
if (state->keyloader == 1)
{
state->R = 0; //NXDN
state->R = 0; //NXDN, or RC4 (slot 1)
state->RR = 0; //RC4 (slot 2)
state->K = 0; //BP
state->K1 = 0; //tera 10 char BP
state->H = 0; //shim for above
@@ -1090,7 +1091,6 @@ usage ()
printf (" -f1 Decode only P25 Phase 1\n");
printf (" -f2 Decode only P25 Phase 2 (6000 sps) **\n");
printf (" -fd Decode only D-STAR\n");
printf (" -fr Decode only DMR Mono - Single Slot Voice\n");
printf (" -fx Decode only X2-TDMA\n");
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
printf (" -fn Decode only NXDN96* (12.5 kHz)\n");
@@ -1130,9 +1130,10 @@ usage ()
printf (" -F Relax NXDN SACCH/FACCH/CAC/F2U CRC Pass/Fail\n");
printf (" Not recommended on NXDN, but can be bypassed if desired.\n");
printf ("\n");
printf (" -K <dec> Manually Enter Basic Privacy Key (Decimal Value of Key Number)\n");
printf (" -b <dec> Manually Enter Basic Privacy Key (Decimal Value of Key Number)\n");
printf (" (NOTE: This used to be the 'K' option! \n");
printf ("\n");
printf (" -H <hex> Manually Enter **tera 10/32/64 Char Privacy Hex Key (see example below)\n");
printf (" -H <hex> Manually Enter **tera 10/32/64 Char Basic Privacy Hex Key (see example below)\n");
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
printf (" -H 0B57935150 \n");
printf (" -H '736B9A9C5645288B 243AD5CB8701EF8A' \n");
@@ -1140,11 +1141,18 @@ usage ()
printf ("\n");
printf (" -R <dec> Manually Enter dPMR or NXDN EHR Scrambler Key Value (Decimal Value)\n");
printf (" \n");
printf (" -k <file> Import Key List from csv file.\n");
printf (" Only supports NXDN, DMR Basic Privacy and **tera 10-Char (decimal value). \n");
printf (" -1 Manually Enter RC4 Key Value (DMR, P25) (Hex 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 **tera 32/64 char not supported, DMR uses TG value as key id -- EXPERIMENTAL!!). \n");
printf (" \n");
printf (" -4 Force Privacy Key over FID and SVC bits \n");
printf (" -K <file> Import Key List from csv file (Hexidecimal Format) -- Capital 'K'.\n");
printf (" Use for Hex Value **tera 10-char BP keys and RC4 10-Char Hex Keys. \n");
printf (" \n");
printf (" -4 Force Privacy Key over Encryption Identifiers (DMR BP and NXDN Scrambler) \n");
printf (" \n");
printf (" -6 Force RC4 Key over Missing PI header/LE Encryption Identifiers (DMR) \n");
printf ("\n");
printf (" Trunking Options:\n");
printf (" -C <file> Import Channel to Frequency Map (channum, freq) from csv file. (Capital C) \n");
@@ -1158,7 +1166,6 @@ usage ()
printf (" -W Use Imported Group List as a Trunking Allow/White List -- Only Tune with Mode A\n");
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 (" (NOTE: NXDN and EDACS, simply disable trunking if desired) \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: P25 Data Channels Not Enabled (no handling) \n");
@@ -1371,7 +1378,7 @@ main (int argc, char **argv)
exitflag = 0;
while ((c = getopt (argc, argv, "haepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:YK:H:X:NQ:WrlZTF01:2:345:6:7:89:Ek:")) != -1)
while ((c = getopt (argc, argv, "haepPqs:t:v:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:VU:YK:b:H:X:NQ:WrlZTF01:2:345:6:7:89:Ek:")) != -1)
{
opterr = 0;
switch (c)
@@ -1384,21 +1391,46 @@ main (int argc, char **argv)
opts.call_alert = 1;
break;
//Free'd up switches include: I, b, J, j, n, O, v, y
//all numberals can be reclaimed, except for -4
//Free'd up switches include: I, J, j, n, O, v, y
//all numerals have reclaimed, except for 4 and 0,1 (rc4 enforcement and single key)
//make sure to put a colon : after each if they need an argument
//or remove colon if no argument required
//NOTE: The 'K' option for single BP key has been swapped to 'b'
//'K' is now used for hexidecimal key.csv imports
//rc4 enforcement on DMR (due to missing the PI header)
case '0':
state.M = 0x21;
fprintf (stderr,"Force RC4 Key over Missing PI header/LE Encryption Identifiers (DMR)\n");
break;
//load single rc4 key
case '1':
sscanf (optarg, "%llX", &state.R);
state.RR = state.R; //put key on both sides
fprintf (stderr, "RC4 Encryption Key Value set to 0x%llX \n", state.R);
opts.unmute_encrypted_p25 = 0;
state.keyloader = 0; //turn off keyloader
break;
case 'Y': //conventional scanner mode
opts.scanner_mode = 1; //enable scanner
opts.p25_trunk = 0; //turn off trunking mode if user enabled it
break;
case 'k': //multi-key loader
case 'k': //multi-key loader (dec)
strncpy(opts.key_in_file, optarg, 1023);
opts.key_in_file[1023] = '\0';
csvKeyImport(&opts, &state);
csvKeyImportDec(&opts, &state);
state.keyloader = 1;
break;
case 'K': //multi-key loader (hex)
strncpy(opts.key_in_file, optarg, 1023);
opts.key_in_file[1023] = '\0';
csvKeyImportHex(&opts, &state);
state.keyloader = 1;
break;
@@ -1465,28 +1497,23 @@ main (int argc, char **argv)
break;
case 'C': //new letter assignment for Channel import, flow down to allow temp numbers
case '1': //LCN to Frequency CSV Import <--> flow down to chanimport now, tell users to use a channel map for edacs
case '7': //Channel Map Frequency CSV Import
strncpy(opts.chan_in_file, optarg, 1023);
opts.chan_in_file[1023] = '\0';
csvChanImport (&opts, &state);
break;
case 'G': //new letter assignment for group import, flow down to allow temp numbers
case '2': //Group CSV Import
strncpy(opts.group_in_file, optarg, 1023);
opts.group_in_file[1023] = '\0';
csvGroupImport(&opts, &state);
break;
case 'T': //new letter assignment for trunking, flow down to allow temp numbers
case '3':
opts.p25_trunk = 1;
opts.scanner_mode = 0; //turn off scanner mode if user enabled it
break;
case 'U': //New letter assignment for RIGCTL TCP port, flow down to allow temp numbers
case '5': //RIGCTL TCP port
sscanf (optarg, "%d", &opts.rigctlportno);
if (opts.rigctlportno != 0) opts.use_rigctl = 1;
break;
@@ -1496,19 +1523,16 @@ main (int argc, char **argv)
//may change to a different return on sync times and this will matter!
case 't': //New letter assignment for Trunk Hangtime, flow down to allow temp numbers
case '6': //hangtime in seconds, default is 1;
sscanf (optarg, "%f", &opts.trunk_hangtime); //updated for float/decimal values
fprintf (stderr, "Trunking or Fast Scanner Hang Time set to: %.02f sec\n", opts.trunk_hangtime);
break;
case 'q': //New letter assignment for Reverse Mute, flow down to allow temp numbers
case '8':
opts.reverse_mute = 1;
fprintf (stderr, "Reverse Mute\n");
break;
case 'B': //New letter assignment for RIGCTL SetMod BW, flow down to allow temp numbers
case '9': //rigctl setmod bandwidth;
sscanf (optarg, "%d", &opts.setmod_bw);
if (opts.setmod_bw > 25000) opts.setmod_bw = 25000; //not too high
break;
@@ -1528,7 +1552,7 @@ main (int argc, char **argv)
// state.use_throttle = 1;
// break;
case 'K':
case 'b': //formerly Capital 'K'
sscanf (optarg, "%lld", &state.K);
if (state.K > 256)
{
@@ -1572,7 +1596,7 @@ main (int argc, char **argv)
case '4':
state.M = 1;
fprintf (stderr,"Force Privacy Key Priority over FID and SVC bits.\n");
fprintf (stderr,"Force Privacy Key over Encryption Identifiers (DMR BP and NXDN Scrambler) \n");
break;
//manually set Phase 2 TDMA WACN/SYSID/CC
@@ -1990,15 +2014,15 @@ main (int argc, char **argv)
opts.mod_qpsk = 0;
opts.mod_gfsk = 0; //
state.rf_mod = 0; //
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_out_channels = 1;
opts.dmr_mono = 1;
opts.dmr_stereo = 0;
opts.pulse_digi_rate_out = 24000;
opts.pulse_digi_out_channels = 2;
opts.dmr_mono = 0;
opts.dmr_stereo = 1;
state.dmr_stereo = 0; //0
// opts.setmod_bw = 7000;
sprintf (opts.output_name, "DMR Mono");
fprintf(stderr, "Notice: DMR cannot autodetect polarity. \n Use -xr option if Inverted Signal expected.\n");
fprintf (stderr,"Decoding only DMR Mono. \nUsing DMR Stereo '-fs' or XDMA '-ft' is highly encouraged.\n");
sprintf (opts.output_name, "DMR Stereo");
fprintf (stderr,"-fr / DMR Mono switch has been deprecated.\n");
fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n");
}
else if (optarg[0] == 'm')

View File

@@ -17,6 +17,56 @@
#include "dsd.h"
//test for potential clashing with other key loading mechanisms (bp key loading on tgid, nxdn key loading, etc)
void keyring(dsd_opts * opts, dsd_state * state)
{
//keys now loaded from csv files with the -K key.csv file (capital K)
if (state->currentslot == 0)
state->R = state->rkey_array[state->payload_keyid];
if (state->currentslot == 1)
state->RR = state->rkey_array[state->payload_keyidR];
}
void RC4(int drop, uint8_t keylength, uint8_t messagelength, uint8_t key[], uint8_t cipher[], uint8_t plain[])
{
int i, j, count;
uint8_t t, b;
//init Sbox
uint8_t S[256];
for(int i = 0; i < 256; i++) S[i] = i;
//Key Scheduling
j = 0;
for(i = 0; i < 256; i++)
{
j = (j + S[i] + key[i % keylength]) % 256;
t = S[i];
S[i] = S[j];
S[j] = t;
}
//Drop Bytes and Cipher Byte XOR
i = j = 0;
for(count = 0; count < (messagelength + drop); count++)
{
i = (i + 1) % 256;
j = (j + S[i]) % 256;
t = S[i];
S[i] = S[j];
S[j] = t;
b = S[(S[i] + S[j]) % 256];
//return mbe payload byte here
if (count >= drop)
plain[count - drop] = b^cipher[count - drop];
}
}
int Pr[256] = {
0x0000, 0x1F00, 0xE300, 0xFC00, 0x2503, 0x3A03, 0xC603, 0xD903,
0x4A05, 0x5505, 0xA905, 0xB605, 0x6F06, 0x7006, 0x8C06, 0x9306,
@@ -140,6 +190,13 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
unsigned long long int k;
int x;
//these conditions should ensure no clashing with the BP/HBP/Scrambler key loading machanisms already coded in
if (state->currentslot == 0 && state->payload_algid != 0 && state->payload_algid != 0x80 && state->payload_keyid != 0 && state->keyloader == 1)
keyring (opts, state);
if (state->currentslot == 1 && state->payload_algidR != 0 && state->payload_algidR != 0x80 && state->payload_keyidR != 0 && state->keyloader == 1)
keyring (opts, state);
//24-bit TG to 16-bit hash
uint32_t hash = 0;
uint8_t hash_bits[24];
@@ -192,7 +249,73 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
mbe_demodulateImbe7200x4400Data (imbe_fr);
state->errs2 = mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
//P25p1 RC4 Handling
if (state->payload_algid == 0xAA && state->R != 0)
{
uint8_t cipher[11] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[11] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
//easier to manually load up rather than make a loop
rckey[0] = ((state->R & 0xFF00000000) >> 32);
rckey[1] = ((state->R & 0xFF000000) >> 24);
rckey[2] = ((state->R & 0xFF0000) >> 16);
rckey[3] = ((state->R & 0xFF00) >> 8);
rckey[4] = ((state->R & 0xFF) >> 0);
// load valid MI from state->payload_miP
rckey[5] = ((state->payload_miP & 0xFF00000000000000) >> 56);
rckey[6] = ((state->payload_miP & 0xFF000000000000) >> 48);
rckey[7] = ((state->payload_miP & 0xFF0000000000) >> 40);
rckey[8] = ((state->payload_miP & 0xFF00000000) >> 32);
rckey[9] = ((state->payload_miP & 0xFF000000) >> 24);
rckey[10] = ((state->payload_miP & 0xFF0000) >> 16);
rckey[11] = ((state->payload_miP & 0xFF00) >> 8);
rckey[12] = ((state->payload_miP & 0xFF) >> 0);
// if (state->p25vc == 0)
// {
// fprintf (stderr, "%s", KYEL);
// fprintf (stderr, "\n RC4K ");
// for (short o = 0; o < 13; o++)
// {
// fprintf (stderr, "%02X", rckey[o]);
// }
// fprintf (stderr, "%s", KNRM);
// }
//load imbe_d into imbe_cipher octets
int z = 0;
for (i = 0; i < 11; i++)
{
cipher[i] = 0;
plain[i] = 0;
for (short int j = 0; j < 8; j++)
{
cipher[i] = cipher[i] << 1;
cipher[i] = cipher[i] + imbe_d[z];
imbe_d[z] = 0;
z++;
}
}
RC4(state->dropL, 13, 11, rckey, cipher, plain);
state->dropL += 11;
z = 0;
for (short p = 0; p < 11; p++)
{
for (short o = 0; o < 8; o++)
{
imbe_d[z] = (plain[p] & 0x80) >> 7;
plain[p] = plain[p] << 1;
z++;
}
}
}
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
@@ -299,8 +422,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
//EXPERIMENTAL!!
//load basic privacy key number from array by the tg value (if not forced)
//currently only Moto BP and Hytera 10 Char BP (converted to decimal)
if (state->M == 0)
//currently only Moto BP and Hytera 10 Char BP
if (state->M == 0 && state->payload_algid == 0)
{
//see if we need to hash a value larger than 16-bits
hash = state->lasttg & 0xFFFFFF;
@@ -400,6 +523,155 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
state->DMRvcL++;
}
//DMR RC4, Slot 1
if (state->currentslot == 0 && state->payload_algid == 0x21 && state->R != 0)
{
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00}; // <- MI
//easier to manually load up rather than make a loop
rckey[0] = ((state->R & 0xFF00000000) >> 32);
rckey[1] = ((state->R & 0xFF000000) >> 24);
rckey[2] = ((state->R & 0xFF0000) >> 16);
rckey[3] = ((state->R & 0xFF00) >> 8);
rckey[4] = ((state->R & 0xFF) >> 0);
rckey[5] = ((state->payload_mi & 0xFF000000) >> 24);
rckey[6] = ((state->payload_mi & 0xFF0000) >> 16);
rckey[7] = ((state->payload_mi & 0xFF00) >> 8);
rckey[8] = ((state->payload_mi & 0xFF) >> 0);
// if (opts->payload == 1)
// {
// fprintf (stderr, "%s", KYEL);
// fprintf (stderr, " RC4K ");
// for (short o = 0; o < 9; o++)
// {
// fprintf (stderr, "%02X", rckey[o]);
// }
// fprintf (stderr, "%s", KNRM);
// fprintf (stderr, "\n");
// }
short k = 0;
for (short o = 0; o < 7; o++)
{
short b = 0;
for (short p = 0; p < 8; p++)
{
b = b << 1;
b = b + ambe_d[k];
k++;
if (k == 49)
{
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
break;
}
}
cipher[o] = b;
}
RC4(state->dropL, 9, 7, rckey, cipher, plain);
state->dropL += 7;
short z = 0;
for (short p = 0; p < 6; p++)
{
//convert bytes back to bits and load into ambe_d array.
short b = 0; //reset b to use again
for (short o = 0; o < 8; o++)
{
b = (( (plain[p] << o) & 0x80) >> 7);
ambe_d[z] = b;
z++;
if (z == 49)
{
ambe_d[48] = ( (plain[p] << o) & 0x80);
break;
}
}
}
}
//P25p2 RC4 Handling, VCH 0
if (state->currentslot == 0 && state->payload_algid == 0xAA && state->R != 0 && ((state->synctype == 35) || (state->synctype == 36)))
{
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
//easier to manually load up rather than make a loop
rckey[0] = ((state->R & 0xFF00000000) >> 32);
rckey[1] = ((state->R & 0xFF000000) >> 24);
rckey[2] = ((state->R & 0xFF0000) >> 16);
rckey[3] = ((state->R & 0xFF00) >> 8);
rckey[4] = ((state->R & 0xFF) >> 0);
// load valid MI from state->payload_miP
rckey[5] = ((state->payload_miP & 0xFF00000000000000) >> 56);
rckey[6] = ((state->payload_miP & 0xFF000000000000) >> 48);
rckey[7] = ((state->payload_miP & 0xFF0000000000) >> 40);
rckey[8] = ((state->payload_miP & 0xFF00000000) >> 32);
rckey[9] = ((state->payload_miP & 0xFF000000) >> 24);
rckey[10] = ((state->payload_miP & 0xFF0000) >> 16);
rckey[11] = ((state->payload_miP & 0xFF00) >> 8);
rckey[12] = ((state->payload_miP & 0xFF) >> 0);
// if (opts->payload == 1)
// {
// fprintf (stderr, "%s", KYEL);
// fprintf (stderr, " RC4K ");
// for (short o = 0; o < 13; o++)
// {
// fprintf (stderr, "%02X", rckey[o]);
// }
// fprintf (stderr, "%s", KNRM);
// fprintf (stderr, "\n");
// }
short k = 0;
for (short o = 0; o < 7; o++)
{
short b = 0;
for (short p = 0; p < 8; p++)
{
b = b << 1;
b = b + ambe_d[k];
k++;
if (k == 49)
{
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
break;
}
}
cipher[o] = b;
}
RC4(state->dropL, 13, 7, rckey, cipher, plain);
state->dropL += 7;
short z = 0;
for (short p = 0; p < 6; p++)
{
//convert bytes back to bits and load into ambe_d array.
short b = 0; //reset b to use again
for (short o = 0; o < 8; o++)
{
b = (( (plain[p] << o) & 0x80) >> 7);
ambe_d[z] = b;
z++;
if (z == 49)
{
ambe_d[48] = ( (plain[p] << o) & 0x80);
break;
}
}
}
}
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);
@@ -429,8 +701,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
//EXPERIMENTAL!!
//load basic privacy key number from array by the tg value (if not forced)
//currently only Moto BP and Hytera 10 Char BP (converted to decimal)
if (state->M == 0)
//currently only Moto BP and Hytera 10 Char BP
if (state->M == 0 && state->payload_algidR == 0)
{
//see if we need to hash a value larger than 16-bits
hash = state->lasttgR & 0xFFFFFF;
@@ -530,6 +802,155 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
state->DMRvcR++;
}
//DMR RC4, Slot 2
if (state->currentslot == 1 && state->payload_algidR == 0x21 && state->RR != 0)
{
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[9] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00}; // <- MI
//easier to manually load up rather than make a loop
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
rckey[1] = ((state->RR & 0xFF000000) >> 24);
rckey[2] = ((state->RR & 0xFF0000) >> 16);
rckey[3] = ((state->RR & 0xFF00) >> 8);
rckey[4] = ((state->RR & 0xFF) >> 0);
rckey[5] = ((state->payload_miR & 0xFF000000) >> 24);
rckey[6] = ((state->payload_miR & 0xFF0000) >> 16);
rckey[7] = ((state->payload_miR & 0xFF00) >> 8);
rckey[8] = ((state->payload_miR & 0xFF) >> 0);
// if (opts->payload == 1)
// {
// fprintf (stderr, "%s", KYEL);
// fprintf (stderr, " RC4K ");
// for (short o = 0; o < 9; o++)
// {
// fprintf (stderr, "%02X", rckey[o]);
// }
// fprintf (stderr, "%s", KNRM);
// fprintf (stderr, "\n");
// }
short k = 0;
for (short o = 0; o < 7; o++)
{
short b = 0;
for (short p = 0; p < 8; p++)
{
b = b << 1;
b = b + ambe_d[k];
k++;
if (k == 49)
{
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
break;
}
}
cipher[o] = b;
}
RC4(state->dropR, 9, 7, rckey, cipher, plain);
state->dropR += 7;
short z = 0;
for (short p = 0; p < 6; p++)
{
//convert bytes back to bits and load into ambe_d array.
short b = 0; //reset b to use again
for (short o = 0; o < 8; o++)
{
b = (( (plain[p] << o) & 0x80) >> 7);
ambe_d[z] = b;
z++;
if (z == 49)
{
ambe_d[48] = ( (plain[p] << o) & 0x80);
break;
}
}
}
}
//P25p2 RC4 Handling, VCH 1
if (state->currentslot == 1 && state->payload_algidR == 0xAA && state->RR != 0 && ((state->synctype == 35) || (state->synctype == 36)))
{
uint8_t cipher[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t plain[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t rckey[13] = {0x00, 0x00, 0x00, 0x00, 0x00, // <- RC4 Key
0x00, 0x00, 0x00, 0x00, 0x00, // <- MI
0x00, 0x00, 0x00}; // <- MI cont.
//easier to manually load up rather than make a loop
rckey[0] = ((state->RR & 0xFF00000000) >> 32);
rckey[1] = ((state->RR & 0xFF000000) >> 24);
rckey[2] = ((state->RR & 0xFF0000) >> 16);
rckey[3] = ((state->RR & 0xFF00) >> 8);
rckey[4] = ((state->RR & 0xFF) >> 0);
//state->payload_miN for VCH1/slot 2
rckey[5] = ((state->payload_miN & 0xFF00000000000000) >> 56);
rckey[6] = ((state->payload_miN & 0xFF000000000000) >> 48);
rckey[7] = ((state->payload_miN & 0xFF0000000000) >> 40);
rckey[8] = ((state->payload_miN & 0xFF00000000) >> 32);
rckey[9] = ((state->payload_miN & 0xFF000000) >> 24);
rckey[10] = ((state->payload_miN & 0xFF0000) >> 16);
rckey[11] = ((state->payload_miN & 0xFF00) >> 8);
rckey[12] = ((state->payload_miN & 0xFF) >> 0);
// if (opts->payload == 1)
// {
// fprintf (stderr, "%s", KYEL);
// fprintf (stderr, " RC4K ");
// for (short o = 0; o < 13; o++)
// {
// fprintf (stderr, "%02X", rckey[o]);
// }
// fprintf (stderr, "%s", KNRM);
// fprintf (stderr, "\n");
// }
short k = 0;
for (short o = 0; o < 7; o++)
{
short b = 0;
for (short p = 0; p < 8; p++)
{
b = b << 1;
b = b + ambe_d[k];
k++;
if (k == 49)
{
cipher[6] = ((b << 3) & 0x80); //set 7th octet/bit 49 accordingly
break;
}
}
cipher[o] = b;
}
RC4(state->dropR, 13, 7, rckey, cipher, plain);
state->dropR += 7;
short z = 0;
for (short p = 0; p < 6; p++)
{
//convert bytes back to bits and load into ambe_d array.
short b = 0; //reset b to use again
for (short o = 0; o < 8; o++)
{
b = (( (plain[p] << o) & 0x80) >> 7);
ambe_d[z] = b;
z++;
if (z == 49)
{
ambe_d[48] = ( (plain[p] << o) & 0x80);
break;
}
}
}
}
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);
@@ -584,7 +1005,10 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
else state->dmr_encL = 0;
//second checkdown for P25-2 WACN, SYSID, and CC set
//check for available R key
if (state->R != 0) state->dmr_encL = 0;
//second checkdown for P25p2 WACN, SYSID, and CC set
if (state->synctype == 35 || state->synctype == 36)
{
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)
@@ -651,7 +1075,10 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
else state->dmr_encR = 0;
//second checkdown for P25-2 WACN, SYSID, and CC set
//check for available RR key
if (state->RR != 0) state->dmr_encR = 0;
//second checkdown for P25p2 WACN, SYSID, and CC set
if (state->synctype == 35 || state->synctype == 36)
{
if (state->p2_wacn == 0 || state->p2_sysid == 0 || state->p2_cc == 0)

View File

@@ -332,15 +332,15 @@ char *choices[] = {
"Decode Legacy Auto**",
"Decode XDMA (P25 and DMR BS/MS)",
"Decode D-STAR*",
"Decode P25-P1*",
"Decode P25p1*",
"Decode EDACS/PV",
"Decode DMR Mono*",
"Decode P25p2 ",
"Decode dPMR",
"Decode NXDN48",
"Decode NXDN96",
"Decode DMR Stereo", //was X2-TDMA*
"Toggle Signal Inversion",
"Privacy Key Entry",
"Key Entry",
"Reset Call History",
"Toggle Payloads to Console",
"Manually Set P2 Parameters", //16
@@ -1091,15 +1091,18 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
state->payload_keyid = 0;
state->payload_keyidR = 0;
short int option = 0;
entry_win = newwin(11, WIDTH+6, starty+10, startx+10);
entry_win = newwin(14, WIDTH+6, starty+10, startx+10);
box (entry_win, 0, 0);
mvwprintw(entry_win, 2, 2, "Key Type Selection");
mvwprintw(entry_win, 3, 2, " ");
mvwprintw(entry_win, 4, 2, "1 - Basic Privacy ");
mvwprintw(entry_win, 5, 2, "2 - **tera Privacy ");
mvwprintw(entry_win, 6, 2, "3 - NXDN/dPMR Scrambler ");
mvwprintw(entry_win, 7, 2, "4 - Force Key Priority ");
mvwprintw(entry_win, 8, 3, " ");
mvwprintw(entry_win, 7, 2, "4 - Force BP/Scr Key Priority ");
mvwprintw(entry_win, 8, 3, "-------------------------------- ");
mvwprintw(entry_win, 9, 2, "5 - RC4 Key ");
mvwprintw(entry_win, 10, 2, "6 - Force DMR RC4 Priority/LE ");
mvwprintw(entry_win, 11, 3, " ");
echo();
refresh();
wscanw(entry_win, "%hd", &option); //%d
@@ -1111,16 +1114,15 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
state->K = 0;
entry_win = newwin(6, WIDTH+6, starty+10, startx+10);
box (entry_win, 0, 0);
mvwprintw(entry_win, 2, 2, "DMRA Privacy Key Number (DEC):");
mvwprintw(entry_win, 2, 2, "Basic Privacy Key Number (DEC):");
mvwprintw(entry_win, 3, 3, " ");
echo();
refresh();
wscanw(entry_win, "%lld", &state->K);
noecho();
if (state->K > 255)
{
state->K = 255;
}
if (state->K > 255) state->K = 255;
state->keyloader = 0; //turn off keyloader
}
if (option == 2)
{
@@ -1171,6 +1173,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
wscanw(entry_win, "%llX", &state->K4);
noecho();
state->keyloader = 0; //turn off keyloader
}
if (option == 3)
{
@@ -1183,20 +1186,49 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
refresh();
wscanw(entry_win, "%lld", &state->R);
noecho();
if (state->K > 0x7FFF)
{
state->K = 0x7FFF;
}
if (state->R > 0x7FFF) state->R = 0x7FFF;
state->keyloader = 0; //turn off keyloader
}
//toggle enforcement of privacy key over enc bit set on traffic
//toggle enforcement of basic privacy key over enc bit set on traffic
if (option == 4)
{
if (state->M == 0)
if (state->M == 1 || state->M == 0x21)
{
state->M = 1;
state->M = 0;
}
else state->M = 0;
else state->M = 1;
}
if (option == 5)
{
state->R = 0;
entry_win = newwin(6, WIDTH+6, starty+10, startx+10);
box (entry_win, 0, 0);
mvwprintw(entry_win, 2, 2, "RC4 Key Value (HEX):");
mvwprintw(entry_win, 3, 3, " ");
echo();
refresh();
wscanw(entry_win, "%llX", &state->R);
noecho();
if (state->R > 0xFFFFFFFFFF)
{
state->R = 0xFFFFFFFFFF;
}
state->RR = state->R; //assign for both slots
state->keyloader = 0; //turn off keyloader
}
//toggle enforcement of rc4 key over missing pi header/le on DMR
if (option == 6)
{
if (state->M == 1 || state->M == 0x21)
{
state->M = 0;
}
else state->M = 0x21;
}
if (state->K == 0 && state->K1 == 0 && state->K2 == 0 && state->K3 == 0 && state->K4 == 0)
{
opts->dmr_mute_encL = 1;
@@ -1309,7 +1341,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
state->samplesPerSymbol = 10;
state->symbolCenter = 4;
state->rf_mod = 0;
sprintf (opts->output_name, "P25P1");
sprintf (opts->output_name, "P25p1");
opts->dmr_mono = 0;
opts->dmr_stereo = 0; //this value is the end user option
state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling
@@ -1369,24 +1401,22 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
}
if (choice == 7)
{
//set legacy DMR settings
// resetState (state); //use sparingly, seems to cause issue when switching back to other formats
opts->frame_dmr = 1;
state->samplesPerSymbol = 10;
state->symbolCenter = 4;
state->rf_mod = 0;
sprintf (opts->output_name, "DMR Mono");
opts->dmr_mono = 1;
opts->dmr_stereo = 0; //this value is the end user option
state->samplesPerSymbol = 8;
state->symbolCenter = 3;
sprintf (opts->output_name, "P25p2");
opts->dmr_mono = 0;
opts->dmr_stereo = 1; //this value is the end user option
state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling
opts->pulse_digi_rate_out = 48000;
opts->pulse_digi_out_channels = 1;
opts->pulse_digi_rate_out = 24000;
opts->pulse_digi_out_channels = 2;
opts->frame_dmr = 0;
opts->frame_dstar = 0;
opts->frame_x2tdma = 0;
opts->frame_p25p1 = 0;
opts->frame_p25p2 = 1;
opts->frame_nxdn48 = 0;
opts->frame_nxdn96 = 0;
//opts->frame_dmr = 0;
opts->frame_dpmr = 0;
opts->frame_provoice = 0;
opts->frame_ysf = 0;
@@ -2163,13 +2193,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (i == 2) printw (" 'q' to Quit ");
if (i == 4) printw (" MBElib %s", versionstr);
#ifdef AERO_BUILD
if (i == 5) printw (" %s ", "Aero Win32");
if (i == 5) printw (" %s ", "Aero Build");
if (i == 6) printw (" v2.1 Win32 \n");
#elif ZDEV_BUILD
if (i == 5) printw (" %s ", "zDEV BUILD");
if (i == 5) printw (" %s ", "zDEV Build");
if (i == 6) printw (" %s \n", GIT_TAG);
#else
if (i == 5) printw (" %s ", "MAIN BUILD");
if (i == 5) printw (" %s ", "Main Build");
if (i == 6) printw (" %s \n", GIT_TAG);
#endif
else printw ("\n");
@@ -2314,6 +2344,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (state->K1 != 0) printw ("| Forcing Key Priority -- tera BP Key: %016llX \n", state->K1);
if (state->K != 0 && state->K1 != 0) printw ("| Warning! Multiple DMR Key Types Loaded! \n"); //warning may not be required
}
if (state->M == 0x21)
{
if (state->R != 0) printw ("| Forcing Key Priority -- RC4 Key: %010llX \n", state->R);
}
if (opts->scanner_mode == 1)
{
printw ("| Fast Scan Mode Enabled ");
@@ -2653,7 +2687,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if(state->dmrburstL == 16 && state->payload_algid > 0 && (state->dmr_so & 0xCF) == 0x40)
{
attron(COLOR_PAIR(1));
printw ("ALG: [0x%02X] KEY: [0x%02X] MI: [0x%08X] ", state->payload_algid, state->payload_keyid, state->payload_mi);
printw ("ALG: 0x%02X KEY: 0x%02X MI: 0x%08X ", state->payload_algid, state->payload_keyid, state->payload_mi);
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(3));
}
@@ -2662,7 +2696,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if(state->dmrburstL > 19 && state->payload_algid > 0 && state->payload_algid != 0x80)
{
attron(COLOR_PAIR(1));
printw ("ALG: [0x%02X] KEY: [0x%04X] MI: [0x%016llX] ", state->payload_algid, state->payload_keyid, state->payload_miP);
printw ("ALG: 0x%02X KEY: 0x%04X MI: 0x%016llX ", state->payload_algid, state->payload_keyid, state->payload_miP);
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(3));
}
@@ -2670,7 +2704,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (state->payload_algid == 0xAA || state->payload_algid == 0x21)
{
attron(COLOR_PAIR(1));
printw("ADP-RC4");
printw("RC4 ");
if (state->R != 0) { printw("Key: %010llX ", state->R); }
attron(COLOR_PAIR(3));
}
if (state->payload_algid == 0x81 || state->payload_algid == 0x22)
@@ -2851,7 +2886,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if(state->dmrburstR == 16 && state->payload_algidR > 0 && (state->dmr_soR & 0xCF) == 0x40)
{
attron(COLOR_PAIR(1));
printw ("ALG: [0x%02X] KEY: [0x%02X] MI: [0x%08X] ", state->payload_algidR, state->payload_keyidR, state->payload_miR);
printw ("ALG: 0x%02X KEY: 0x%02X MI: 0x%08X ", state->payload_algidR, state->payload_keyidR, state->payload_miR);
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(3));
}
@@ -2859,14 +2894,15 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if(state->dmrburstR > 19 && state->payload_algidR > 0 && state->payload_algidR != 0x80)
{
attron(COLOR_PAIR(1));
printw ("ALG: [0x%02X] KEY: [0x%04X] MI: [0x%016llX] ", state->payload_algidR, state->payload_keyidR, state->payload_miN);
printw ("ALG: 0x%02X KEY: 0x%04X MI: 0x%016llX ", state->payload_algidR, state->payload_keyidR, state->payload_miN);
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0xAA || state->payload_algidR == 0x21)
{
attron(COLOR_PAIR(1));
printw("ADP-RC4");
printw("RC4 ");
if (state->RR != 0) { printw("Key: %010llX ", state->RR); }
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0x81 || state->payload_algidR == 0x22)
@@ -3305,10 +3341,16 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (c == 52) // '4' key, toggle force privacy key over fid and svc (dmr)
{
if (state->M == 1) state->M = 0;
if (state->M == 1 || state->M == 0x21) state->M = 0;
else state->M = 1;
}
if (c == 54) // '6' key, toggle force rc4 key over missing pi header/late entry
{
if (state->M == 1 || state->M == 0x21) state->M = 0;
else state->M = 0x21;
}
if (c == 105) //'i' key, toggle signal inversion on inverted types
{
//Set all signal for inversion or uninversion

View File

@@ -459,6 +459,9 @@ processHDU(dsd_opts* opts, dsd_state* state)
mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32);
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
//reset dropbytes - skip first 11 for LCW
state->dropL = 267;
//set vc counter to 0
state->p25vc = 0;
@@ -466,10 +469,11 @@ processHDU(dsd_opts* opts, dsd_state* state)
{
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
fprintf (stderr, "%s", KNRM);
fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%04X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
state->payload_algid = algidhex;
state->payload_keyid = kidhex;
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key: %010llX", state->R);
fprintf (stderr, "%s", KNRM);
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
state->payload_miP = (mihex1 << 32) | (mihex2);

View File

@@ -171,6 +171,8 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
// TODO: error correction of the LSD bytes...
// TODO: do something useful with the LSD bytes...
state->dropL += 2; //need to skip 2 here for the LSD bytes
}
// IMBE 9

View File

@@ -172,6 +172,8 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
// TODO: error correction of the LSD bytes...
// TODO: do something useful with the LSD bytes...
state->dropL += 2; //need to skip 2 here for the LSD bytes
}
// IMBE 9
@@ -183,6 +185,9 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
//set vc counter to 0
state->p25vc = 0;
//reset dropbytes -- skip first 11 for next LCW
state->dropL = 267;
if (opts->errorbars == 1)
{
fprintf (stderr, "\n");
@@ -366,11 +371,11 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
if (irrecoverable_errors == 0)
{
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
fprintf (stderr, "%s", KNRM);
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%04X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
state->payload_algid = algidhex;
state->payload_keyid = kidhex;
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key: %010llX", state->R);
fprintf (stderr, "%s", KNRM);
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
state->payload_miP = (mihex1 << 32) | (mihex2);
@@ -390,4 +395,45 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
fprintf (stderr, "%s", KNRM);
}
//run LFSR on the MI if we have irrecoverable errors here
if (irrecoverable_errors && state->payload_algid != 0x80 && state->payload_keyid != 0 && state->payload_miP != 0)
{
LFSRP(state);
fprintf (stderr, "\n");
}
}
//LFSR code courtesy of https://github.com/mattames/LFSR/
void LFSRP(dsd_state * state)
{
//rework for P2 TDMA support
unsigned long long int lfsr = 0;
if (state->currentslot == 0)
lfsr = state->payload_miP;
if (state->currentslot == 1)
lfsr = state->payload_miN;
int cnt = 0;
for(cnt=0;cnt<64;cnt++)
{
// Polynomial is C(x) = x^64 + x^62 + x^46 + x^38 + x^27 + x^15 + 1
unsigned long long int bit = ((lfsr >> 63) ^ (lfsr >> 61) ^ (lfsr >> 45) ^ (lfsr >> 37) ^ (lfsr >> 26) ^ (lfsr >> 14)) & 0x1;
lfsr = (lfsr << 1) | (bit);
}
if (state->currentslot == 0)
state->payload_miP = lfsr;
if (state->currentslot == 1)
state->payload_miN = lfsr;
//print current ENC identifiers already known and new calculated MI
fprintf (stderr, "%s", KYEL);
if (state->currentslot == 0)
fprintf (stderr, " LDU2/ESS_B FEC ERR - ALG: 0x%02X KEY ID: 0x%04X LFSR MI: 0x%016llX", state->payload_algid, state->payload_keyid, state->payload_miP);
if (state->currentslot == 1)
fprintf (stderr, " LDU2/ESS_B FEC ERR - ALG: 0x%02X KEY ID: 0x%04X LFSR MI: 0x%016llX", state->payload_algidR, state->payload_keyidR, state->payload_miN);
fprintf (stderr, "%s", KNRM);
}

View File

@@ -552,6 +552,7 @@ void process_ESS (dsd_opts * opts, dsd_state * state)
fprintf (stderr, " ALG ID 0x%02X", state->payload_algid);
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key 0x%010llX", state->R);
fprintf (stderr, " ESSB");
}
@@ -567,6 +568,7 @@ void process_ESS (dsd_opts * opts, dsd_state * state)
fprintf (stderr, " ALG ID 0x%02X", state->payload_algidR);
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
if (state->RR != 0 && state->payload_algidR == 0xAA) fprintf (stderr, " Key 0x%010llX", state->RR);
fprintf (stderr, " ESSB");
}
@@ -574,7 +576,11 @@ void process_ESS (dsd_opts * opts, dsd_state * state)
}
if (ec == -1 || ec >= 15)
{
//ESS R-S Failure
//ESS R-S Failure -- run LFSR on current MI if applicable
if (state->currentslot == 0 && state->payload_algid != 0x80 && state->payload_keyid != 0 && state->payload_miP != 0)
LFSRP(state);
if (state->currentslot == 1 && state->payload_algidR != 0x80 && state->payload_keyidR != 0 && state->payload_miN != 0)
LFSRP(state);
}
fprintf (stderr, "%s", KNRM);
@@ -651,6 +657,13 @@ void process_2V (dsd_opts * opts, dsd_state * state)
process_ESS(opts, state);
//reset drop bytes after a 2V
if (state->currentslot == 0 && state->payload_algid == 0xAA)
state->dropL = 256;
if (state->currentslot == 1 && state->payload_algidR == 0xAA)
state->dropR = 256;
}
//P2 Data Unit ID

View File

@@ -120,6 +120,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
{
//reset fourv_counter and dropbyte on PTT
state->fourv_counter[0] = 0;
state->dropL = 256;
state->dmrburstL = 20;
fprintf (stderr, "\n VCH 0 - ");
@@ -142,6 +143,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algid);
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key 0x%010llX", state->R);
fprintf(stderr, " MPTT");
// fprintf (stderr, " %s", KRED);
// fprintf (stderr, "ENC");
@@ -153,6 +155,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
{
//reset fourv_counter and dropbyte on PTT
state->fourv_counter[1] = 0;
state->dropR = 256;
state->payload_algidR = 0; //zero this out as well
state->dmrburstR = 20;
@@ -176,6 +179,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algidR);
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
if (state->RR != 0 && state->payload_algidR == 0xAA) fprintf (stderr, " Key 0x%010llX", state->RR);
fprintf(stderr, " MPTT");
// fprintf (stderr, " %s", KRED);
// fprintf (stderr, "ENC");
@@ -194,6 +198,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
{
state->fourv_counter[0] = 0;
state->dropL = 256;
state->dmrburstL = 23;
state->payload_algid = 0;
state->payload_keyid = 0;
@@ -217,6 +222,7 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
{
state->fourv_counter[1] = 0;
state->dropR = 256;
state->dmrburstR = 23;
state->payload_algidR = 0;
state->payload_keyidR = 0;
@@ -369,6 +375,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
{
//reset fourv_counter and dropbyte on PTT
state->fourv_counter[0] = 0;
state->dropL = 256;
state->dmrburstL = 20;
fprintf (stderr, "\n VCH 0 - ");
@@ -391,6 +398,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algid);
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyid);
fprintf (stderr, " MI 0x%016llX", state->payload_miP);
if (state->R != 0 && state->payload_algid == 0xAA) fprintf (stderr, " Key 0x%010llX", state->R);
fprintf(stderr, " MPTT");
// fprintf (stderr, " %s", KRED);
// fprintf (stderr, "ENC");
@@ -402,6 +410,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
{
//reset fourv_counter and dropbyte on PTT
state->fourv_counter[1] = 0;
state->dropR = 256;
state->dmrburstR = 20;
fprintf (stderr, "\n VCH 1 - ");
@@ -424,6 +433,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
fprintf (stderr, "\n ALG ID 0x%02X", state->payload_algidR);
fprintf (stderr, " KEY ID 0x%04X", state->payload_keyidR);
fprintf (stderr, " MI 0x%016llX", state->payload_miN);
if (state->RR != 0 && state->payload_algidR == 0xAA) fprintf (stderr, " Key 0x%010llX", state->RR);
fprintf(stderr, " MPTT");
// fprintf (stderr, " %s", KRED);
// fprintf (stderr, "ENC");
@@ -441,6 +451,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
{
state->fourv_counter[0] = 0;
state->dropL = 256;
state->dmrburstL = 23;
state->payload_algid = 0; //zero this out as well
state->payload_keyid = 0;
@@ -464,6 +475,7 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
{
state->fourv_counter[1] = 0;
state->dropR = 256;
state->dmrburstR = 23;
state->payload_algidR = 0; //zero this out as well
state->payload_keyidR = 0;