DMR: Retevis AP (RC2) Encryption Support Update to Allow 128-bit or 256-bit keys;

This commit is contained in:
lwvmobile
2025-09-19 22:44:50 -04:00
parent 99b1fd2fe2
commit f8ca0a8e08
3 changed files with 92 additions and 20 deletions

View File

@@ -176,9 +176,10 @@ Advanced Decoder options:
Encapulate in Single Quotation Marks; Space every 16 chars.
-! '736B9A9C5645288B 243AD5CB8701EF8A'
-@ <hex> Manually Enter and Enforce Retevis Advanced Privacy (RC2) AP Hex Key (see example below)
Encapulate in Single Quotation Marks; Space every 16 chars.
-@ '736B9A9C5645288B 243AD5CB8701EF8A'
-@ <hex> Manually Enter and Enforce Retevis Advanced Privacy (RC2) 128 or 256 bit AP Hex Key (see example below)
Encapulate in Single Quotation Marks; Space every 16 chars.
-@ '736B9A9C5645288B 243AD5CB8701EF8A'
-@ '1122334455667788 99AABBCCDDEEFF11 1122334455667788 99AABBCCDDEEFF11'
-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.

View File

@@ -304,8 +304,8 @@ void decrypt_rc2(CryptoContext* ctx, uint8_t bits[49]) {
/* Key creation for Retevis AP */
void retevis_rc2_keystream_creation(dsd_state *state, char *input) {
unsigned char key1[16] = {0};
unsigned char key2[16] = {0};
unsigned char key1[64]; memset(key1, 0, sizeof(key1));
unsigned char key2[64]; memset(key2, 0, sizeof(key2));
char buf[1024];
strncpy(buf, input, sizeof(buf) - 1);
@@ -314,21 +314,91 @@ void retevis_rc2_keystream_creation(dsd_state *state, char *input) {
char *pEnd;
uint64_t K1 = strtoull(buf, &pEnd, 16);
uint64_t K2 = strtoull(pEnd, &pEnd, 16);
uint64_t K3 = strtoull(pEnd, &pEnd, 16);
uint64_t K4 = strtoull(pEnd, &pEnd, 16);
u64_to_bytes_be(K1, &key1[0]);
u64_to_bytes_be(K2, &key1[8]);
if (K3 != 0 || K4 != 0) //256-bit keys loaded as ASCII characters
{
//start loading K1, K2, K3, and K4 as ASCII to fill 64 bytes of key1
int k = 0; uint8_t x = 0;
for (int i=0;i<16;i++) key2[i] = key1[15-i];
// Initialize RC2 context
static CryptoContext rc2_ctx;
create_keys_rc2(&rc2_ctx, key2, sizeof(key2));
// Store context in DSD state
state->rc2_context = malloc(sizeof(CryptoContext));
memcpy(state->rc2_context, &rc2_ctx, sizeof(CryptoContext));
fprintf(stderr, "DMR RETEVIS AP (RC2) 128-bit Key %016llX%016llX with Forced Application\n",
for (int i = 0; i < 16; i++)
{
x = ((K1 >> (60-(i*4))) & 0xF);
if (x >= 0 && x <= 9) //numbers 0-9
x += 0x30; //ASCII representation of numbers is 0x30, 0x31....0x39
else x += 0x37; //Upper ASCII A,B,C,D,E,F is 0x41, 0x42...0x46
key1[k++] = x;
}
for (int i = 0; i < 16; i++)
{
x = ((K2 >> (60-(i*4))) & 0xF);
if (x >= 0 && x <= 9) //numbers 0-9
x += 0x30; //ASCII representation of numbers is 0x30, 0x31....0x39
else x += 0x37; //Upper ASCII A,B,C,D,E,F is 0x41, 0x42...0x46
key1[k++] = x;
}
for (int i = 0; i < 16; i++)
{
x = ((K3 >> (60-(i*4))) & 0xF);
if (x >= 0 && x <= 9) //numbers 0-9
x += 0x30; //ASCII representation of numbers is 0x30, 0x31....0x39
else x += 0x37; //Upper ASCII A,B,C,D,E,F is 0x41, 0x42...0x46
key1[k++] = x;
}
for (int i = 0; i < 16; i++)
{
x = ((K4 >> (60-(i*4))) & 0xF);
if (x >= 0 && x <= 9) //numbers 0-9
x += 0x30; //ASCII representation of numbers is 0x30, 0x31....0x39
else x += 0x37; //Upper ASCII A,B,C,D,E,F is 0x41, 0x42...0x46
key1[k++] = x;
}
//debug
// fprintf (stderr, "ASCII: ");
// for (int i = 0; i < 64; i++)
// fprintf (stderr, " %02X", key1[i]);
// fprintf (stderr, "\n");
// Initialize RC2 context
static CryptoContext rc2_ctx;
create_keys_rc2(&rc2_ctx, key1, 64);
// Store context in DSD state
state->rc2_context = malloc(sizeof(CryptoContext));
memcpy(state->rc2_context, &rc2_ctx, sizeof(CryptoContext));
fprintf(stderr, "DMR RETEVIS AP (RC2) 256-bit Key %016llX%016llX%016llX%016llX with Forced Application\n",
(unsigned long long)K1, (unsigned long long)K2, (unsigned long long)K3, (unsigned long long)K4);
state->retevis_ap = 1;
}
else //128-bit loaded as reverse bytes
{
u64_to_bytes_be(K1, &key1[0]);
u64_to_bytes_be(K2, &key1[8]);
// reverse load the key bytes into key2
for (int i=0;i<16;i++)
key2[i] = key1[15-i];
// Initialize RC2 context
static CryptoContext rc2_ctx;
create_keys_rc2(&rc2_ctx, key2, 16);
// Store context in DSD state
state->rc2_context = malloc(sizeof(CryptoContext));
memcpy(state->rc2_context, &rc2_ctx, sizeof(CryptoContext));
fprintf(stderr, "DMR RETEVIS AP (RC2) 128-bit Key %016llX%016llX with Forced Application\n",
(unsigned long long)K1, (unsigned long long)K2);
state->retevis_ap = 1;
state->retevis_ap = 1;
}
}

View File

@@ -1566,9 +1566,10 @@
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
printf (" -! '736B9A9C5645288B 243AD5CB8701EF8A' \n");
printf (" \n");
printf (" -@ <hex> Manually Enter and Enforce Retevis Advanced Privacy (RC2) AP Hex Key (see example below)\n");
printf (" -@ <hex> Manually Enter and Enforce Retevis Advanced Privacy (RC2) 128 or 256 bit AP Hex Key (see example below)\n");
printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n");
printf (" -@ '736B9A9C5645288B 243AD5CB8701EF8A' \n");
printf (" -@ '1122334455667788 99AABBCCDDEEFF11 1122334455667788 99AABBCCDDEEFF11' \n");
printf (" \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");