diff --git a/examples/cygwin_bat/complete_usage_options.txt b/examples/cygwin_bat/complete_usage_options.txt index 43144e6..60be8d1 100644 --- a/examples/cygwin_bat/complete_usage_options.txt +++ b/examples/cygwin_bat/complete_usage_options.txt @@ -1,4 +1,4 @@ -Build Version: AW 2026-39-gc97400a +Build Version: AW 2026-41-gfb3dc75 MBElib Version: 1.3.4 CODEC2 Support Enabled @@ -182,7 +182,7 @@ Advanced Decoder options: -, Manually Enter and Enforce Auctus A6 (GoComm) 8 Char Key Value (DMR) (String Value) -, Secure04 - -u Manually Enter and Enforce Vertex Standard 10 or 64 Char Hex Key + -u Manually Enter Vertex Standard 10 or 64 Char Hex Key -u 10:1234567891 or 64:AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD -u 0:0 no KS application, but apply the inversion to the interleave (clear errors on 256) diff --git a/src/bptc.c b/src/bptc.c index 5ab12fd..e96fbab 100644 --- a/src/bptc.c +++ b/src/bptc.c @@ -340,9 +340,8 @@ uint32_t BPTC_196x96_Extract_Data(uint8_t InputDeInteleavedData[196], uint8_t DM /* R(0) to R(2) may be used to transport some * Restricted Access System (RAS) information, * So save these three bits after hamming correction - * See patent US 2013/0288643 A1 */ - - //TODO: Get seperate validity for line 0 and column 0,1,2 + * See patent https://patents.google.com/patent/US20130288643A1 + */ if (HammingIrrecoverableErrorNb == 0) { R[0] = DataMatrix[0][2]; /* Save R(0) */ diff --git a/src/crypt-md5.c b/src/crypt-md5.c index 7eab1eb..aa28d6a 100644 --- a/src/crypt-md5.c +++ b/src/crypt-md5.c @@ -410,50 +410,48 @@ void ras_effective_key_creation(dsd_state * state, char * input) fprintf (stderr, "\n"); //The following rules are still not entirely clear, however, - //the first one executed (last byte) has been observed to be - //true, the SEED values are more speculative, values of - //0 and 0x1F do not change the 5-bit checksum mod 31 (0x1F) + //the last taken digest byte has been observed to be true //Furthermore, it is still unclear how any rollover is handled, //if adding 2 is byte inclusive (effectively resetting the byte) //or if the value is flat 56-bit value and rollover occurs - //to the next value over, using best guess on this - //until further informatin comes along + //against the flat value, using best guess on this + //until further information comes along //Below patent also suggest all bytes cannot equal zero //and if so, the next portion of MD5 may be used, //or some other method may be utilized to prevent fringe cases //https://patents.google.com/patent/US20130288643A1 - //Last Byte low5 not allowed to be 0x1F (reasons unclear, but observed true) + //Last Collected Byte 5-bit LSB not allowed to be 0x1F if ((ctx.digest[6] & 0x1F) == 0x1F) { - fprintf (stderr, " Byte %d: %02X -> %02X; ", 7, ctx.digest[6], ctx.digest[6]+2); + fprintf (stderr, " Byte %d: %02X -> %02X; ", 7, ctx.digest[6], (ctx.digest[6]+2) & 0xFF); ctx.digest[6] += 2; } - //UPDATE: I have now observed a system that has a 5-bit differential value of 0 - //so that means that the low5 effective key value can be either 0, or 0x1F + //collect 7 bytes of the MD5 Hash to create the flat key value + unsigned long long int flat_key = 0; + for (int i = 0; i < 7; i++) + { + flat_key <<= 8; + flat_key |= ctx.digest[i]; + } - // //SEED low5 non-zero value (no change to 5-bit EMB checksum mod 31) - // if ((ctx.digest[0] & 0x1F) == 0) + //May switch to this correction method instead if the + //observed rollover is on a flat value and not a byte value + // if ((flat_key & 0x1F) == 0x1F) // { - // fprintf (stderr, " Byte %d: %02X -> %02X; ", 1, ctx.digest[0], ctx.digest[0]+2); - // ctx.digest[0] += 2; - // } - - // //SEED low5 plus 1F (no change to 5-bit EMB checksum mod 31) - // else if ((ctx.digest[0] & 0x1F) == 0x1F) - // { - // fprintf (stderr, " Byte %d: %02X -> %02X; ", 1, ctx.digest[0], ctx.digest[0]+2); - // ctx.digest[0] += 2; + // fprintf (stderr, "Flat Correction: %014llX -> %014llX;\n", flat_key, flat_key+2); + // flat_key += 2; // } + //byte-reverse the flat_key into the effective_key unsigned long long int effective_key = 0; for (int i = 0; i < 7; i++) { effective_key <<= 8; - effective_key |= ctx.digest[6-i]; + effective_key |= (flat_key >> (i*8)) & 0xFF; } uint32_t ras_seed = effective_key & 0xFFFFFFFF; @@ -467,5 +465,4 @@ void ras_effective_key_creation(dsd_state * state, char * input) fprintf (stderr, "\n"); - } diff --git a/src/crypt-rc4.c b/src/crypt-rc4.c index 03cbf7e..6439731 100644 --- a/src/crypt-rc4.c +++ b/src/crypt-rc4.c @@ -271,11 +271,15 @@ void vertex_40_keystream_creation(dsd_state * state, unsigned long long int key_ vtx_key |= BPK[rc4_bytes[i]]; } + #ifdef VERTEX_KEY40_BY_TG + //skip constant verbosity on keyloading + #else fprintf (stderr,"Vertex RC4 Bytes: "); for (uint16_t i = 0; i < 8; i++) fprintf (stderr, "%02X ", rc4_bytes[i]); fprintf (stderr, "Vertex Keystream: %016llX;", (unsigned long long int)vtx_key); fprintf (stderr, "\n"); + #endif uint8_t vtx_bytes[8]; memset (vtx_bytes, 0, sizeof(vtx_bytes)); @@ -316,12 +320,17 @@ void vertex_keystream_setup(dsd_state * state, char * input) if (len == 10) { sscanf (curr, "%llx", &state->vtx40_key); + fprintf (stderr, "Vertex Standard 40-bit Key: %010llX \n", state->vtx40_key); vertex_40_keystream_creation(state, state->vtx40_key); } else if (len == 64) { memcpy(state->vtx256_key, curr, 64); + fprintf (stderr, "Vertex Standard 256-bit Key: "); + for (int i = 0; i < 64; i++) + fprintf (stderr, "%c", state->vtx256_key[i]); + fprintf (stderr, "\n"); vertex_256_keystream_creation(state, curr); } diff --git a/src/dmr_dburst.c b/src/dmr_dburst.c index 0e5bf8d..de2e8b1 100644 --- a/src/dmr_dburst.c +++ b/src/dmr_dburst.c @@ -260,9 +260,6 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 //make sure the system type isn't Hytera, but could just be bad decodes on bad sample if (IrrecoverableErrors == 0 && BPTCDmrDataByte[1] == 0x68) is_ras = 0; - //make sure if this is link control, the FID is set to 0x10 - if (IrrecoverableErrors == 0 && is_lc && BPTCDmrDataByte[1] != 0x10) is_ras = 0; - //make sure if this is a PI header, the FID is set to 0x10 if (IrrecoverableErrors == 0 && databurst == 0x00 && BPTCDmrDataByte[1] != 0x10) is_ras = 0; @@ -634,7 +631,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 } //might flicker the terminal on partially enabled systems, may need to find a better placement - if (IrrecoverableErrors == 0 && (is_bptc || is_emb) && databurst != 0x05 && databurst != 0x07) + if (IrrecoverableErrors == 0 && (is_bptc || is_emb) && databurst != 0x05 && databurst != 0x07 && databurst != 0x09) state->dmr_is_ras = is_ras; if (IrrecoverableErrors == 0 && CRCCorrect == 0 && is_ras == 0 && databurst != 0x09 && databurst != 0x05) diff --git a/src/dmr_flco.c b/src/dmr_flco.c index 919038e..cf138ba 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -512,15 +512,15 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C if (opts->payload == 1 && is_xpt == 1 && flco == 0x3) fprintf(stderr, "HASH=%d ", tg_hash); if (opts->payload == 1) fprintf(stderr, "FLCO=0x%02X FID=0x%02X SVC=0x%02X ", flco, fid, so); - //0x04 and 0x05 on a TLC seem to indicate a Cap + Private Call Terminator (perhaps one for each MS) - //0x07 on a VLC seems to indicate a Cap+ Private Call Header - //0x23 on the Embedded Voice Burst Sync seems to indicate a Cap+ or Cap+ TXI Private Call in progress (RAS) - //0x20 on the Embedded Voice Burst Sync seems to indicate a Moto (non-specific) Group Call in progress (RAS) - //its possible that both EMB FID 0x10 FLCO 0x20 and 0x23 are just Moto but non-specific (RAS) + //0x04 and 0x05 on a TLC seem to indicate a Cap + Private Call Terminator <--need to find this again and re-evaluate + //0x04 on a VLC seems to indicate a Cap+ Group Call Header <--single bit flip from normal group + //0x07 on a VLC seems to indicate a Cap+ Private Call Header <--single bit flip from normal private + //0x20 on the Embedded Voice Burst Sync seems to indicate a Moto w/ FID 0x10 Group Call in progress (RAS) + //0x23 on the Embedded Voice Burst Sync seems to indicate a Moto w/ FID 0x10 Private Call in progress (RAS) if (fid == 0x68) sprintf (state->call_string[slot], " Hytera "); - else if (flco == 0x4 || flco == 0x5 || flco == 0x7 || flco == 0x23) //Cap+ Things + else if (flco == 0x4 || flco == 0x5 || flco == 0x7) //Cap+ Things (double check 0x05) { // sprintf (state->call_string[slot], " Cap+"); sprintf (state->call_string[slot], "%s",""); @@ -540,13 +540,13 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C state->gi[slot] = 1; } } - else if (flco == 0x3) //UU_V_Ch_Usr + else if (flco == 0x3 || flco == 0x23) //UU_V_Ch_Usr { sprintf (state->call_string[slot], " Private "); fprintf (stderr, "Private "); state->gi[slot] = 1; } - else //Grp_V_Ch_Usr -- still valid on hytera VLC + else //Grp_V_Ch_Usr { sprintf (state->call_string[slot], " Group "); fprintf (stderr, "Group "); diff --git a/src/dsd_main.c b/src/dsd_main.c index e11d3d3..385eeef 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1596,7 +1596,7 @@ printf (" -, Manually Enter and Enforce Auctus A6 (GoComm) 8 Char Key Value (DMR) (String Value) \n"); printf (" -, Secure04\n"); printf (" \n"); - printf (" -u Manually Enter and Enforce Vertex Standard 10 or 64 Char Hex Key \n"); + printf (" -u Manually Enter Vertex Standard 10 or 64 Char Hex Key \n"); printf (" -u 10:1234567891 or 64:AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD\n"); printf (" -u 0:0 no KS application, but apply the inversion to the interleave (clear errors on 256)\n"); printf (" \n");