DMR: Initial Support for Kirisun "Advanced" and "Universal" Encryption Identifiers and Link Control; #319

This commit is contained in:
lwvmobile
2025-10-10 05:53:36 -04:00
parent cf032ab955
commit ac1c658870
5 changed files with 133 additions and 3 deletions

View File

@@ -72,6 +72,13 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
so ^= 0x40;
}
//Kirisun
if (*IrrecoverableErrors == 0 && CRCCorrect == 1 && fid == 0x0A) //&& (so & 0x40) == 0x40
{
//disable late entry for DMRA, Flag 3 for future checks
opts->dmr_le = 3;
}
//read ahead a little to get this for the xpt flag
if (*IrrecoverableErrors == 0 && flco == 0x09 && fid == 0x68)
{
@@ -310,8 +317,8 @@ 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 && is_kenwood_sc == 0)
//removed tait from the list, added hytera 0x08, added Kirisun and KW Scrambler LC
if (fid != 0 && fid != 0x68 && fid != 0x10 && fid != 0x08 && fid != 0x0A && is_kenwood_sc == 0)
{
if (type == 1) fprintf (stderr, "%s \n", KYEL);
if (type == 2) fprintf (stderr, "%s \n", KYEL);
@@ -654,6 +661,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C
}
//should rework this back into the upper portion
if (fid == 0x0A) fprintf (stderr, "Kirisun ");
if (fid == 0x68) fprintf (stderr, "Hytera ");
if (is_xpt) fprintf (stderr, "XPT ");
if (fid == 0x68 && flco == 0x00)

View File

@@ -390,6 +390,28 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power)
//NOTE: on above, I belive that we need to check by opcode as well, as a CRC3 can have multiple collisions
//so we need to exclude op/alg 0 and 3 from the check (does algID 0x03/0x23 even exist?)
if (opts->dmr_le == 3)
{
if (sbrc_hex != 0) //Kirisun Placeholder, first had 0x5F1, second batch had 0x5E1 instead
{
fprintf (stderr, "\n");
fprintf (stderr, "%s", KCYN);
fprintf (stderr, " Slot %d", state->currentslot+1);
fprintf (stderr, " DMR LE SB Kirisun Encryption;");
fprintf (stderr, "%s ", KNRM);
if (state->currentslot == 0)
{
if (state->payload_algid == 0)
state->payload_algid = 0x35;
}
else
{
if (state->payload_algidR == 0)
state->payload_algidR = 0x35;
}
}
}
if (opts->dmr_le == 1)
{
if (irr_err != 0)

View File

@@ -167,6 +167,16 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
}
//Kirisun Check VC-F for Enc Identifiers -- has bad fec, unless its loaded differently
//SEE: https://patents.google.com/patent/CN102307075A/en?q=(kirisun)&q=(dmr)&oq=kirisun
// if (opts->dmr_le == 3 && vc == 6)
// {
// bool kokay = 0;
// // kokay = Golay_24_12_decode(syncdata);
// unsigned long long int kirisun = (unsigned long long int)ConvertBitIntoBytes(&syncdata[0], 48);
// fprintf (stderr, "Kiri: %012llX; Golay Okay: %d; \n", kirisun, kokay);
// }
for(i = 0; i < 8; i++) emb_pdu[i + 0] = syncdata[i];
for(i = 0; i < 8; i++) emb_pdu[i + 8] = syncdata[i + 40];

View File

@@ -12,7 +12,6 @@
void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRCCorrect, uint32_t IrrecoverableErrors)
{
UNUSED2(opts, CRCCorrect);
uint8_t MFID = PI_BYTE[1];
@@ -26,6 +25,57 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC
state->last_cc_sync_time = time(NULL);
}
if (MFID == 0x0A && CRCCorrect == 1) //Kirisun
{
uint8_t so = PI_BYTE[2]; //in VLC and PI, this byte is 0x40, so thinking this could be SVC_OPT
uint8_t alg = PI_BYTE[0]; //observed 0x36 and 0x37 for Kirisun Advanced and Universal Privacy
// uint8_t kid = PI_BYTE[2]; //user info conveyed there is only 16 allotments for Key, and keys are channel specific, so no key id value
uint32_t target = ((unsigned long long int)PI_BYTE[7] << 16) | ((unsigned long long int)PI_BYTE[8] << 8) | ((unsigned long long int)PI_BYTE[9] << 0);
//TODO: Use TGT value here to produce a key id via hashing it
uint8_t hash = target % 256; //more complex hash later
//MI only appears to be 32-bit
unsigned long long int mi = ((unsigned long long int)PI_BYTE[3] << 24) | ((unsigned long long int)PI_BYTE[4] << 16) |
((unsigned long long int)PI_BYTE[5] << 8) | ((unsigned long long int)PI_BYTE[6] << 0);
if (state->currentslot == 0)
{
state->dmr_so = so;
state->payload_algid = alg;
state->payload_keyid = hash;
state->payload_mi = mi;
}
else
{
state->dmr_soR = so;
state->payload_algidR = alg;
state->payload_keyidR = hash;
state->payload_miR = mi;
}
fprintf (stderr, "%s ", KYEL);
fprintf (stderr, "\n Slot %d", state->currentslot+1);
fprintf (stderr, " DMR PI H- ALG ID: %02X; KEY ID: %02X; MI(32): %08llX;", alg, hash, mi);
fprintf (stderr, " Kirisun ");
if (alg == 0x36)
fprintf (stderr, "Advanced;");
else if (alg == 0x37)
fprintf (stderr, "Universal;");
else fprintf (stderr, "Unknown;");
fprintf (stderr, "%s", KNRM);
//disable late entry for DMRA, Flag 3 for future check of VC-F 48-bit region with Golay 24,12 Encoding
//SEE: https://patents.google.com/patent/CN102307075A/en?q=(kirisun)&q=(dmr)&oq=kirisun
//tested patent above with information provided, VC-F had a SB, but the 48-bit
//full value yielded bad Golay results, and user submitted info contradicts this patent for samples provided
//Late Entry MI does appear to work, however, and reports a good CRC for that as well,
//but the LFSR or method to get to the next MI or len of it is unknown as of yet.
opts->dmr_le = 3;
}
if (MFID == 0x68) //Hytera Enhanced
{
if (state->currentslot == 0)

View File

@@ -1109,6 +1109,26 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw(" Key: %010llX", state->R);
attron(COLOR_PAIR(3));
}
if (state->payload_algid == 0x36)
{
attron(COLOR_PAIR(1));
printw("Kirisun Advanced");
if (state->aes_key_loaded[0] != 0) { printw("KS: %016llX ", state->A4[0]); }
attron(COLOR_PAIR(3));
}
if (state->payload_algid == 0x37)
{
attron(COLOR_PAIR(1));
printw("Kirisun Universal");
if (state->aes_key_loaded[0] != 0) { printw("KS: %016llX ", state->A4[0]); }
attron(COLOR_PAIR(3));
}
if (state->payload_algid == 0x35)
{
attron(COLOR_PAIR(1));
printw("Kirisun Encryption"); //0x35 is a placeholder if gained through late-entry method and alg is not known
attron(COLOR_PAIR(3));
}
printw ("\n");
@@ -1284,6 +1304,26 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw(" Key: %010llX", state->RR);
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0x36)
{
attron(COLOR_PAIR(1));
printw("Kirisun Advanced");
if (state->aes_key_loaded[1] != 0) { printw("KS: %016llX ", state->A4[1]); }
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0x37)
{
attron(COLOR_PAIR(1));
printw("Kirisun Universal");
if (state->aes_key_loaded[1] != 0) { printw("KS: %016llX ", state->A4[1]); }
attron(COLOR_PAIR(3));
}
if (state->payload_algidR == 0x35)
{
attron(COLOR_PAIR(1));
printw("Kirisun Encryption"); //0x35 is a placeholder if gained through late-entry method and alg is not known
attron(COLOR_PAIR(3));
}
printw ("\n");