From 4005c9b313bde984ec410c7690c4c9b83fb9735e Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 16 Oct 2026 11:04:42 -0400 Subject: [PATCH] DMR: Add More Kirisun Encryption Support; #319 Ciphers added include "Enhanced" "Reinforced" and "Strengthened"; Placeholders for remaining ciphers; --- .../cygwin_bat/complete_usage_options.txt | 2 +- include/dsd.h | 5 +- src/crypt-des.c | 99 +++- src/crypt-kir.c | 527 +++++++++++++++++- src/dmr_le.c | 107 +++- src/dmr_pi.c | 46 +- src/dsd_audio2.c | 57 +- src/dsd_main.c | 2 +- src/dsd_mbe.c | 32 +- src/dsd_ncurses_printer.c | 32 +- 10 files changed, 803 insertions(+), 106 deletions(-) diff --git a/examples/cygwin_bat/complete_usage_options.txt b/examples/cygwin_bat/complete_usage_options.txt index e2ec779..da4e73d 100644 --- a/examples/cygwin_bat/complete_usage_options.txt +++ b/examples/cygwin_bat/complete_usage_options.txt @@ -136,7 +136,7 @@ Advanced Decoder options: -H '736B9A9C5645288B 243AD5CB8701EF8A' -H '20029736A5D91042 C923EB0697484433 005EFC58A1905195 E28E9C7836AA2DB8' - -H Manually Enter AES-128, AES-256, or Kirisun-256 Hex Key (see example below) + -H Manually Enter AES-128, AES-256, or Kirisun 128 or 256 Hex Key (see example below) Encapulate in Single Quotation Marks; Space every 16 chars. -H '736B9A9C5645288B 243AD5CB8701EF8A' -H '20029736A5D91042 C923EB0697484433 005EFC58A1905195 E28E9C7836AA2DB8' diff --git a/include/dsd.h b/include/dsd.h index 3831488..70d0638 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -1672,10 +1672,9 @@ void vertex_40_keystream_creation(dsd_state * state, unsigned long long int key_ void vertex_256_keystream_creation(dsd_state * state, char * key_string); void vtx256_ambe2_interleave_inversion(char ambe_fr[4][24]); -//Kirisun +//Kirisun LFSR and General Keystream Creator uint32_t kirisun_lfsr(unsigned long long int mi); -void kirisun_adv_keystream_creation(dsd_state *state); -void kirisun_uni_keystream_creation(dsd_state *state); +void kirisun_keystream_creation(dsd_state * state); //Hytera Enhanced void hytera_enhanced_rc4_setup(dsd_opts * opts, dsd_state * state, unsigned long long int key_value, unsigned long long int mi_value); diff --git a/src/crypt-des.c b/src/crypt-des.c index 09b4ada..3ec36cd 100644 --- a/src/crypt-des.c +++ b/src/crypt-des.c @@ -287,7 +287,7 @@ void des_cipher (uint8_t * main_key, uint8_t * input_register, uint8_t * output_ memcpy (left, initial_permutation+0, sizeof(left)); memcpy (right, initial_permutation+4, sizeof(right)); - //16 fiestel rounds + //16 feistel rounds for (uint8_t f = 0; f < 16; f++) { @@ -339,7 +339,102 @@ void des_cipher (uint8_t * main_key, uint8_t * input_register, uint8_t * output_ memcpy (left, right, sizeof(left)); memcpy (right, rperm, sizeof(right)); - } //end fiestel rounds f + } //end feistel rounds f + + //combine right and left into the pre_end_permutation array + memcpy (pre_end_permutation+0, right, sizeof(right)); + memcpy (pre_end_permutation+4, left, sizeof(left)); + + //carry out the final permuation to get the completed output_register for this cipher iteration + permute (pre_end_permutation, output_register, final_register_permutation, 0, 64); + +} + +//kirisun variation on this cipher w/ preconfigured unique key schedule +void ksun_des_cipher (uint8_t * key, uint8_t * input_register, uint8_t * output_register, uint8_t de) +{ + + //starting and ending permutations + uint8_t initial_permutation[8]; memset(initial_permutation, 0, sizeof(initial_permutation)); + uint8_t pre_end_permutation[8]; memset(pre_end_permutation, 0, sizeof(pre_end_permutation)); + + //intermediate left, right, and expansion/selection arrays + uint8_t left[4]; memset(left, 0, sizeof(left)); + uint8_t right[4]; memset(right, 0, sizeof(right)); + uint8_t rperm[4]; memset(rperm, 0, sizeof(rperm)); + uint8_t exp[6]; memset(exp, 0, sizeof(exp)); + uint8_t sel[4]; memset(sel, 0, sizeof(sel)); + + //key sets + uint8_t Ks[16][6]; memset(Ks, 0, sizeof(Ks)); + + //file the key into the keysets + for (int i = 0; i < 16; i++) + { + for (int j = 0; j < 6; j++) + Ks[i][j] = key[(i*6) + j]; + } + + //permute the input_register with the ip (initial_register_permutation) table + permute (input_register, initial_permutation, initial_register_permutation, 0, 64); + + //copy the initial permutation to left and right half arrays + memcpy (left, initial_permutation+0, sizeof(left)); + memcpy (right, initial_permutation+4, sizeof(right)); + + //16 feistel rounds + for (uint8_t f = 0; f < 16; f++) + { + + //reset rperm and exp arrays + memset(rperm, 0, sizeof(rperm)); + memset(exp, 0, sizeof(exp)); + + //expand right half from 32-bit to 48-bit + permute (right, exp, message_expansion, 0, 48); + + //apply current iteration keyset to the expanded array (encryption cycles Ks forward, decryption goes in reverse) + if (de == 1) + { + for (uint8_t i = 0; i < 6; i++) + exp[i] ^= Ks[f][i]; + } + else + { + for (uint8_t i = 0; i < 6; i++) + exp[i] ^= Ks[15-f][i]; + } + + //extract 6 bits for each sbox swap from the expanded array + uint8_t e1 = exp[0] >> 2; + uint8_t e2 = ((exp[0] & 0x3) << 4) | (exp[1] >> 4); + uint8_t e3 = ((exp[1] & 0xF) << 2) | (exp[2] >> 6); + uint8_t e4 = exp[2] & 0x3F; + + uint8_t e5 = exp[3] >> 2; + uint8_t e6 = ((exp[3] & 0x3) << 4) | (exp[4] >> 4); + uint8_t e7 = ((exp[4] & 0xF) << 2) | (exp[5] >> 6); + uint8_t e8 = exp[5] & 0x3F; + + //select 32-bits of each 48-bit expansion via modified S Box Look Up Tables + //swap the 6 bits for 4 bits via SLUT tables and OR them together into a selection array + sel[0] = SLUT1[e1] | SLUT2[e2]; + sel[1] = SLUT3[e3] | SLUT4[e4]; + sel[2] = SLUT5[e5] | SLUT6[e6]; + sel[3] = SLUT7[e7] | SLUT8[e8]; + + //permute the selected 32-bits into a new right half + permute (sel, rperm, right_half_permutation, 0, 32); + + //xor new right half against left half + for (uint8_t i = 0; i < 4; i++) + rperm[i] ^= left[i]; + + //swap old right half to left, set new right half to rperm + memcpy (left, right, sizeof(left)); + memcpy (right, rperm, sizeof(right)); + + } //end feistel rounds f //combine right and left into the pre_end_permutation array memcpy (pre_end_permutation+0, right, sizeof(right)); diff --git a/src/crypt-kir.c b/src/crypt-kir.c index b86d082..c982b26 100644 --- a/src/crypt-kir.c +++ b/src/crypt-kir.c @@ -1,6 +1,9 @@ #include "dsd.h" #include "pc4.h" +//function prototype linked in crypt-des.c +void ksun_des_cipher (uint8_t * key, uint8_t * input_register, uint8_t * output_register, uint8_t de); + /* === Global MD2II buffers === */ int x1, x2, i, n1global; unsigned char h2[n1]; @@ -174,7 +177,68 @@ void keystream37(unsigned char *key, uint64_t frame, unsigned char *output) } -//dsd-fme -fs -Z -i '/SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/cap-clear.wav/cap-33.wav' -H '3333333333333333 3333333333333333 3333333333333333 3333333333333333' +#define ROTATE_LEFT(VALUE, SHIFT) \ + (((VALUE) << ((SHIFT) & 63)) | ((VALUE) >> (64 - ((SHIFT) & 63)))) + +#define ROTATE_RIGHT(VALUE, SHIFT) \ + (((VALUE) >> ((SHIFT) & 63)) | ((VALUE) << (64 - ((SHIFT) & 63)))) + +void keystream35(uint8_t * input_register, unsigned char * key) +{ + + uint64_t round = 0x9E3779B97F4A7C15; + uint64_t round_key[2]; memset(round_key, 0, sizeof(round_key)); + + uint64_t state[2]; memset(state, 0, sizeof(state)); + + //load input_register into state as two 64-bit chunks + for (int i = 0; i < 8; i++) + { + state[0] <<= 8; + state[0] |= input_register[i+0]; + + state[1] <<= 8; + state[1] |= input_register[i+8]; + } + + //load key into round_key as two 64-bit chunks + for (int i = 0; i < 8; i++) + { + round_key[0] <<= 8; + round_key[0] |= key[i+0]; + + round_key[1] <<= 8; + round_key[1] |= key[i+8]; + } + + for (int i = 0; i < 64; i++) + { + round_key[0] += round; + round_key[1] -= round; + + state[0] ^= round_key[0]; + state[0] += state[1]; + state[0] = ROTATE_LEFT(state[0], state[1]); + + state[1] = ROTATE_RIGHT(state[1], state[0]); + state[1] -= state[0]; + state[1] ^= round_key[1]; + } + + uint64_t temp = state[0]; + state[0] = state[1]; + state[1] = temp; + + //reload input_register with current state values + for (int i = 0; i < 8; i++) + input_register[i+0] = (state[0] >> (56 - (i * 8))) & 0xFF; + + for (int i = 0; i < 8; i++) + input_register[i+8] = (state[1] >> (56 - (i * 8))) & 0xFF; + +} + +//dsd-fme -fs -Z -i 'SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/cap-clear.wav/cap-33.wav' -H '3333333333333333 3333333333333333 3333333333333333 3333333333333333' void kirisun_uni_keystream_creation(dsd_state *state) { uint8_t slot = 0; @@ -292,7 +356,7 @@ void kirisun_uni_keystream_creation(dsd_state *state) } -//dsd-fme -fs -Z -i '/SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/better_samples_tg1/kirisun_advanced_tg1.wav' -H 'DC1A7E9F9BF312DB F45010CEC5F7A53A C407D0BFA803617B E426A7254DA9390D' +//dsd-fme -fs -Z -i 'SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/better_samples_tg1/kirisun_advanced_tg1.wav' -H 'DC1A7E9F9BF312DB F45010CEC5F7A53A C407D0BFA803617B E426A7254DA9390D' void kirisun_adv_keystream_creation(dsd_state *state) { @@ -415,3 +479,462 @@ void kirisun_adv_keystream_creation(dsd_state *state) } } + +//dsd-fme -fs -Z -i 'SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/enhanced-key-12.wav/enhanced-key-12.wav' -H 'C607727B8BECC3CB 7DD174F5526BB546' +void kirisun_enh_keystream_creation(dsd_state *state) +{ + uint8_t slot = 0; + if (state->currentslot == 0) + slot = 0; + else slot = 1; + + uint32_t lfsr = 0; + if (state->currentslot == 0) + lfsr = (uint32_t)state->payload_mi; + else lfsr = (uint32_t)state->payload_miR; + + unsigned char userkeyhexa[32]; memset(userkeyhexa, 0, sizeof(userkeyhexa)); + unsigned char realkey[32]; memset(realkey, 0, sizeof(realkey)); + unsigned char lfsrhexa[4]; memset(lfsrhexa, 0, sizeof(lfsrhexa)); + uint8_t ks_bytes[128]; memset(ks_bytes, 0, sizeof(ks_bytes)); + + lfsrhexa[0] = (lfsr >> 24) & 0xFF; + lfsrhexa[1] = (lfsr >> 16) & 0xFF; + lfsrhexa[2] = (lfsr >> 8) & 0xFF; + lfsrhexa[3] = (lfsr >> 0) & 0xFF; + + uint64_t K1 = state->A1[slot]; + uint64_t K2 = state->A2[slot]; + + if (K1 != 0 && K2 != 0) + state->aes_key_loaded[slot] = 1; + else state->aes_key_loaded[slot] = 0; + + if (state->aes_key_loaded[slot] == 1) + { + + u64_to_bytes_be(K1, &userkeyhexa[0]); + u64_to_bytes_be(K2, &userkeyhexa[8]); + + // printf("=== userkey input (16 bytes) ===\n"); + // print_hex(userkeyhexa,16); + + /* --- MD2II first pass --- */ + n1global=16; + unsigned char h4[n1]; memset(h4, 0, sizeof(h4)); + MD2II_init(); + MD2II_hashing(userkeyhexa,16); + MD2II_end(h4); + for(int i=0;i<16;i++) realkey[i]=h4[i]; + + // printf("=== realkey final (16 bytes) ===\n"); + // print_hex(realkey,16); + + n1global=16; + MD2II_init(); + MD2II_hashing(lfsrhexa,4); + MD2II_hashing(realkey,16); + MD2II_end(h4); + + uint8_t input_register[16]; memset(input_register, 0, sizeof(input_register)); + + //copy h4 to the input_register for the cipher + memcpy(input_register, h4, 16); + + /* --- MD2II with n1global=32 --- */ + n1global=32; + MD2II_init(); + MD2II_hashing(lfsrhexa,4); + MD2II_hashing(realkey,16); + MD2II_end(h4); + + //copy h4 to the tab for the cipher + uint8_t tab[16]; memset(tab, 0, sizeof(tab)); + memcpy(tab, h4, 16); + + // printf("=== Input Register (16 bytes) ===\n"); + // print_hex(input_register,16); + + // printf("=== Tab (16 bytes) ===\n"); + // print_hex(tab,16); + + /* --- keystream output --- */ + uint8_t output[128]; memset(output, 0, sizeof(output)); + + //discard round + keystream35(input_register, tab); + + for (int i = 0; i < 8; i++) + { + keystream35(input_register, tab); + memcpy(output+(i*16), input_register, 16); + } + + //store ks_bytes to storage + for (int i = 0; i < 128; i++) + ks_bytes[i] = output[i]; + + if (slot == 0) + memcpy(state->ks_octetL, ks_bytes, sizeof(ks_bytes)); + else memcpy(state->ks_octetR, ks_bytes, sizeof(ks_bytes)); + + //debug ks_bytes + // fprintf (stderr, "KS: "); + // for (int i = 0; i < 128; i++) + // { + // if ((i != 0) && ((i%16)==0)) + // fprintf (stderr, "\n "); + // fprintf (stderr, "%02X ", ks_bytes[i]); + // } + // fprintf (stderr, "\n"); + + } + +} + +//dsd-fme -fs -Z -i 'SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/kirisun_files/reinforced-key-9.wav' -H 'C607727B8BECC3CB 7DD174F5526BB546 B3DEA1C111DC1994 69243120CDB6F99A' +void kirisun_rei_keystream_creation(dsd_state *state) +{ + uint8_t slot = 0; + if (state->currentslot == 0) + slot = 0; + else slot = 1; + + uint32_t lfsr = 0; + if (state->currentslot == 0) + lfsr = (uint32_t)state->payload_mi; + else lfsr = (uint32_t)state->payload_miR; + + unsigned char userkeyhexa[32]; memset(userkeyhexa, 0, sizeof(userkeyhexa)); + unsigned char realkey[32]; memset(realkey, 0, sizeof(realkey)); + unsigned char lfsrhexa[4]; memset(lfsrhexa, 0, sizeof(lfsrhexa)); + uint8_t ks_bytes[128]; memset(ks_bytes, 0, sizeof(ks_bytes)); + + lfsrhexa[0] = (lfsr >> 24) & 0xFF; + lfsrhexa[1] = (lfsr >> 16) & 0xFF; + lfsrhexa[2] = (lfsr >> 8) & 0xFF; + lfsrhexa[3] = (lfsr >> 0) & 0xFF; + + uint64_t K1 = state->A1[slot]; + uint64_t K2 = state->A2[slot]; + uint64_t K3 = state->A3[slot]; + uint64_t K4 = state->A4[slot]; + + if (K1 != 0 && K2 != 0 && K3 != 0 && K4 != 0) + state->aes_key_loaded[slot] = 1; + else state->aes_key_loaded[slot] = 0; + + if (state->aes_key_loaded[slot] == 1) + { + + u64_to_bytes_be(K1, &userkeyhexa[0]); + u64_to_bytes_be(K2, &userkeyhexa[8]); + u64_to_bytes_be(K3, &userkeyhexa[16]); + u64_to_bytes_be(K4, &userkeyhexa[24]); + + for(int i=0;i<32;i++) realkey[i]=userkeyhexa[i]; + + // printf("=== userkey input (32 bytes) ===\n"); + // print_hex(userkeyhexa,32); + + /* --- MD2II first pass --- */ + n1global=32; + unsigned char h4[n1]; memset(h4, 0, sizeof(h4)); + MD2II_init(); + MD2II_hashing(realkey,32); + MD2II_end(h4); + for(int i=0;i<32;i++) realkey[i]=h4[i]; + + // printf("=== realkey final (32 bytes) ===\n"); + // print_hex(realkey,32); + + n1global=8; + MD2II_init(); + MD2II_hashing(lfsrhexa,4); + MD2II_hashing(realkey,32); + MD2II_end(h4); + + // printf("h4[0..7]: "); + // print_hex(h4,8); + + uint64_t internal_state=0; + for(int i=0;i<8;i++) + internal_state=(internal_state<<8)+(h4[i]); + + // printf("internal_state=%016llX\n",(unsigned long long)internal_state); + + uint8_t input_register[8]; memset(input_register, 0, sizeof(input_register)); + uint8_t output_register[8]; memset(output_register, 0, sizeof(output_register)); + + //copy internal state value to the input_register for the modified DES cipher + memcpy(input_register, h4, 8); + + /* --- MD2II with n1global=96 --- */ + n1global=96; + MD2II_init(); + MD2II_hashing(lfsrhexa,4); + MD2II_hashing(realkey,32); + MD2II_end(h4); + + // printf("realkey (96 bytes):\n"); + // print_hex(h4,96); + + /* --- keystream output --- */ + uint8_t output[128]; memset(output, 0, sizeof(output)); + + //run discard round first + ksun_des_cipher(h4, input_register, output_register, 1); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + memset(output_register, 0, sizeof(output_register)); + + //begin creation of actual keystream now + for (int i = 0; i < 16; i++) + { + //the internal state is the output feedback mode + ksun_des_cipher(h4, input_register, output_register, 1); + memcpy(output+(i*8), output_register, 8); + memcpy(input_register, output_register, 8); + memset(output_register, 0, sizeof(output_register)); + } + + // printf("keystream output (128 bytes):\n"); + // print_hex(output,128); + + //store ks_bytes to storage + for (int i = 0; i < 128; i++) + ks_bytes[i] = output[i]; + + if (slot == 0) + memcpy(state->ks_octetL, ks_bytes, sizeof(ks_bytes)); + else memcpy(state->ks_octetR, ks_bytes, sizeof(ks_bytes)); + + //debug ks_bytes + // fprintf (stderr, "KS: "); + // for (int i = 0; i < 128; i++) + // { + // if ((i != 0) && ((i%16)==0)) + // fprintf (stderr, "\n "); + // fprintf (stderr, "%02X ", ks_bytes[i]); + // } + // fprintf (stderr, "\n"); + + } + +} + +//dsd-fme -fs -Z -i 'SSD_STORAGE/2025_DEV/Tytera BP EP AP Master Folder/kirisun/kirisun_files/strengthened-key-7.wav' -H 'C607727B8BECC3CB 7DD174F5526BB546 B3DEA1C111DC1994 69243120CDB6F99A' +void kirisun_str_keystream_creation(dsd_state *state) +{ + uint8_t slot = 0; + if (state->currentslot == 0) + slot = 0; + else slot = 1; + + uint32_t lfsr = 0; + if (state->currentslot == 0) + lfsr = (uint32_t)state->payload_mi; + else lfsr = (uint32_t)state->payload_miR; + + unsigned char userkeyhexa[32]; memset(userkeyhexa, 0, sizeof(userkeyhexa)); + unsigned char realkey[32]; memset(realkey, 0, sizeof(realkey)); + unsigned char lfsrhexa[4]; memset(lfsrhexa, 0, sizeof(lfsrhexa)); + uint8_t ks_bytes[128]; memset(ks_bytes, 0, sizeof(ks_bytes)); + uint8_t global_key[288]; memset (global_key, 0, sizeof(global_key)); + + lfsrhexa[0] = (lfsr >> 24) & 0xFF; + lfsrhexa[1] = (lfsr >> 16) & 0xFF; + lfsrhexa[2] = (lfsr >> 8) & 0xFF; + lfsrhexa[3] = (lfsr >> 0) & 0xFF; + + uint64_t K1 = state->A1[slot]; + uint64_t K2 = state->A2[slot]; + uint64_t K3 = state->A3[slot]; + uint64_t K4 = state->A4[slot]; + + if (K1 != 0 && K2 != 0 && K3 != 0 && K4 != 0) + state->aes_key_loaded[slot] = 1; + else state->aes_key_loaded[slot] = 0; + + if (state->aes_key_loaded[slot] == 1) + { + + u64_to_bytes_be(K1, &userkeyhexa[0]); + u64_to_bytes_be(K2, &userkeyhexa[8]); + u64_to_bytes_be(K3, &userkeyhexa[16]); + u64_to_bytes_be(K4, &userkeyhexa[24]); + + for(int i=0;i<32;i++) realkey[i]=userkeyhexa[i]; + + // printf("=== userkey input (32 bytes) ===\n"); + // print_hex(userkeyhexa,32); + + /* --- MD2II first pass --- */ + n1global=32; + unsigned char h4[288]; memset(h4, 0, sizeof(h4)); + MD2II_init(); + MD2II_hashing(realkey,32); + MD2II_end(h4); + for(int i=0;i<32;i++) realkey[i]=h4[i]; + + // printf("=== realkey final (32 bytes) ===\n"); + // print_hex(realkey,32); + + n1global=288; + MD2II_init(); + MD2II_hashing(realkey, 32); + MD2II_end(h4); + for (int i=0;i<288;i++) global_key[i]=h4[i]; + + // printf("=== global key (288 bytes) ===\n"); + // print_hex(realkey,288); + + n1global=8; + MD2II_init(); + MD2II_hashing(lfsrhexa,4); + MD2II_hashing(realkey,32); + MD2II_end(h4); + + // printf("h4[0..7]: "); + // print_hex(h4,8); + + uint64_t internal_state=0; + for(int i=0;i<8;i++) + internal_state=(internal_state<<8)+(h4[i]); + + // printf("internal_state=%016llX\n",(unsigned long long)internal_state); + + uint8_t input_register[8]; memset(input_register, 0, sizeof(input_register)); + uint8_t output_register[8]; memset(output_register, 0, sizeof(output_register)); + + //copy internal state value to the input_register for the modified DES cipher + memcpy(input_register, h4, 8); + + /* --- MD2II with n1global=96 --- */ + n1global=96; + MD2II_init(); + MD2II_hashing(lfsrhexa,4); + MD2II_hashing(realkey,32); + MD2II_end(h4); + + // printf("realkey (96 bytes):\n"); + // print_hex(h4,96); + + /* --- keystream output --- */ + uint8_t output[128]; memset(output, 0, sizeof(output)); + + //run discard round first + ksun_des_cipher(global_key+0, input_register, output_register, 1); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + memset(output_register, 0, sizeof(output_register)); + + ksun_des_cipher(global_key+96, input_register, output_register, 0); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + memset(output_register, 0, sizeof(output_register)); + + ksun_des_cipher(global_key+192, input_register, output_register, 1); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + memset(output_register, 0, sizeof(output_register)); + + //begin creation of actual keystream now + for (int i = 0; i < 16; i++) + { + //the internal state is the output feedback mode + ksun_des_cipher(global_key+0, input_register, output_register, 1); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + memset(output_register, 0, sizeof(output_register)); + + ksun_des_cipher(global_key+96, input_register, output_register, 0); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + memset(output_register, 0, sizeof(output_register)); + + ksun_des_cipher(global_key+192, input_register, output_register, 1); + memcpy(input_register, output_register, 8); //internal_state = des_reinforced(internal_state, encrypt); + + //copy out last output_register to output + memcpy(output+(i*8), output_register, 8); + memset(output_register, 0, sizeof(output_register)); + } + + // printf("keystream output (128 bytes):\n"); + // print_hex(output,128); + + //store ks_bytes to storage + for (int i = 0; i < 128; i++) + ks_bytes[i] = output[i]; + + if (slot == 0) + memcpy(state->ks_octetL, ks_bytes, sizeof(ks_bytes)); + else memcpy(state->ks_octetR, ks_bytes, sizeof(ks_bytes)); + + //debug ks_bytes + // fprintf (stderr, "KS: "); + // for (int i = 0; i < 128; i++) + // { + // if ((i != 0) && ((i%16)==0)) + // fprintf (stderr, "\n "); + // fprintf (stderr, "%02X ", ks_bytes[i]); + // } + // fprintf (stderr, "\n"); + + } +} + +void kirisun_low_keystream_creation(dsd_state *state) +{ + UNUSED(state); +} + +void kirisun_mid_keystream_creation(dsd_state *state) +{ + UNUSED(state); +} + +void kirisun_hi_keystream_creation(dsd_state *state) +{ + UNUSED(state); +} + +void kirisun_top_keystream_creation(dsd_state *state) +{ + UNUSED(state); +} + +void kirisun_ult_keystream_creation(dsd_state *state) +{ + UNUSED(state); +} + +//General Keystream Creator for any known Kirisun cipher +void kirisun_keystream_creation(dsd_state * state) +{ + if (state->payload_algid == 0x31) + kirisun_rei_keystream_creation(state); + + else if (state->payload_algid == 0x32) + kirisun_low_keystream_creation(state); + + else if (state->payload_algid == 0x33) + kirisun_mid_keystream_creation(state); + + else if (state->payload_algid == 0x34) + kirisun_hi_keystream_creation(state); + + else if (state->payload_algid == 0x35) + kirisun_enh_keystream_creation(state); + + else if (state->payload_algid == 0x36) + kirisun_adv_keystream_creation(state); + + else if (state->payload_algid == 0x37) + kirisun_uni_keystream_creation(state); + + else if (state->payload_algid == 0x38) + kirisun_str_keystream_creation(state); + + else if (state->payload_algid == 0x39) + kirisun_top_keystream_creation(state); + + else if (state->payload_algid == 0x3A) + kirisun_ult_keystream_creation(state); + +} diff --git a/src/dmr_le.c b/src/dmr_le.c index cf617a8..8427751 100644 --- a/src/dmr_le.c +++ b/src/dmr_le.c @@ -219,20 +219,37 @@ void dmr_alg_refresh (dsd_opts * opts, dsd_state * state) fprintf (stderr, "%s\n", KNRM); } - if (state->payload_algid == 0x35 || state->payload_algid == 0x36 || state->payload_algid == 0x37) + if ((state->payload_algid & 0xF0) == 0x30) //any kirisun 0x3X alg { + uint8_t alg = state->payload_algid; state->DMRvcL = 0; state->payload_mi = kirisun_lfsr(state->payload_mi); fprintf (stderr, "%s", KYEL); fprintf (stderr, " Slot 1"); - fprintf (stderr, " DMR PI C- ALG ID: %02X; KEY ID: %02X;", state->payload_algid, state->payload_keyid); + fprintf (stderr, " DMR PI C- ALG ID: %02X; KEY ID: %02X;", alg, state->payload_keyid); fprintf (stderr, " MI(32): %08llX;", state->payload_mi); - fprintf (stderr, " Kirisun"); - if (state->payload_algid == 0x36) - fprintf (stderr, " Advanced;"); - else if (state->payload_algid == 0x37) - fprintf (stderr, " Universal;"); - else fprintf (stderr, " Encryption;"); + fprintf (stderr, " Kirisun "); + if (alg == 0x31) + fprintf (stderr, "Reinforced "); + else if (alg == 0x32) + fprintf (stderr, "Low "); + else if (alg == 0x33) + fprintf (stderr, "Middle "); + else if (alg == 0x34) + fprintf (stderr, "High "); + else if (alg == 0x35) + fprintf (stderr, "Enhanced "); + else if (alg == 0x36) + fprintf (stderr, "Advanced "); + else if (alg == 0x37) + fprintf (stderr, "Universal "); + else if (alg == 0x38) + fprintf (stderr, "Strengthened "); + else if (alg == 0x39) + fprintf (stderr, "Top "); + else if (alg == 0x3A) + fprintf (stderr, "Ultra "); + fprintf (stderr, "Encryption;"); fprintf (stderr, "%s\n", KNRM); } @@ -266,20 +283,37 @@ void dmr_alg_refresh (dsd_opts * opts, dsd_state * state) fprintf (stderr, "%s\n", KNRM); } - if (state->payload_algidR == 0x35 || state->payload_algidR == 0x36 || state->payload_algidR == 0x37) + if ((state->payload_algidR & 0xF0) == 0x30) //any 0x3X alg { + uint8_t alg = state->payload_algidR; state->DMRvcR = 0; state->payload_miR = kirisun_lfsr(state->payload_miR); fprintf (stderr, "%s", KYEL); fprintf (stderr, " Slot 2"); - fprintf (stderr, " DMR PI C- ALG ID: %02X; KEY ID: %02X;", state->payload_algidR, state->payload_keyidR); + fprintf (stderr, " DMR PI C- ALG ID: %02X; KEY ID: %02X;", alg, state->payload_keyidR); fprintf (stderr, " MI(32): %08llX;", state->payload_miR); - fprintf (stderr, " Kirisun"); - if (state->payload_algidR == 0x36) - fprintf (stderr, " Advanced;"); - else if (state->payload_algidR == 0x37) - fprintf (stderr, " Universal;"); - else fprintf (stderr, " Encryption;"); + fprintf (stderr, " Kirisun "); + if (alg == 0x31) + fprintf (stderr, "Reinforced "); + else if (alg == 0x32) + fprintf (stderr, "Low "); + else if (alg == 0x33) + fprintf (stderr, "Middle "); + else if (alg == 0x34) + fprintf (stderr, "High "); + else if (alg == 0x35) + fprintf (stderr, "Enhanced "); + else if (alg == 0x36) + fprintf (stderr, "Advanced "); + else if (alg == 0x37) + fprintf (stderr, "Universal "); + else if (alg == 0x38) + fprintf (stderr, "Strengthened "); + else if (alg == 0x39) + fprintf (stderr, "Top "); + else if (alg == 0x3A) + fprintf (stderr, "Ultra "); + fprintf (stderr, "Encryption;"); fprintf (stderr, "%s\n", KNRM); } @@ -407,7 +441,7 @@ 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?) - //Kirisun Placeholder + //Kirisun if (opts->dmr_le == 3) { if (irr_err != 0) @@ -422,23 +456,38 @@ void dmr_sbrc (dsd_opts * opts, dsd_state * state, uint8_t power) fprintf (stderr, "%s SLOT %d SB/RC (FEC ERR) E:%d; I:%08X D:%03X; %s ", KRED, slot+1, irr_err, sbrcpl, sbrc_hex, KNRM); if (opts->payload == 1) fprintf (stderr, "\n"); } - else if (irr_err == 0 && sbrc_hex != 0) //first batch had sbrc_hex 0x5F1, second batch had 0x5E1 instead, what changed? + else if (irr_err == 0 && sbrc_hex != 0) //older firmware had sbrc_hex 0x5F1, and 0x5E1 instead { fprintf (stderr, "\n"); fprintf (stderr, "%s", KCYN); fprintf (stderr, " Slot %d", state->currentslot+1); - fprintf (stderr, " DMR LE SB Kirisun Encryption Identifier;"); + fprintf (stderr, " DMR LE SB Kirisun"); + + //Newer Samples and/or updated firmware seem to do this with actual key values + uint8_t alg = sbrc_hex >> 7; + + if (alg != 0xB) + { + fprintf (stderr, " ALG: %02X;", alg+0x30); + uint8_t kid = (sbrc_hex >> 3) & 0xF; + fprintf (stderr, " KID: %02X;", kid); + uint8_t unk = sbrc_hex & 0x7; + fprintf (stderr, " LOW3: %X;", unk); + + if (state->currentslot == 0) + { + if (state->payload_algid == 0 && state->dmr_so & 0x40) + state->payload_algid = alg+0x30; + } + else + { + if (state->payload_algidR == 0 && state->dmr_soR & 0x40) + state->payload_algidR = alg+0x30; + } + } + fprintf (stderr, "%s ", KNRM); - if (state->currentslot == 0) - { - if (state->payload_algid == 0 && state->dmr_so & 0x40) - state->payload_algid = 0x35; //placeholder value - } - else - { - if (state->payload_algidR == 0 && state->dmr_soR & 0x40) - state->payload_algidR = 0x35; //placeholder value - } + } } diff --git a/src/dmr_pi.c b/src/dmr_pi.c index 6772e8a..547af1b 100644 --- a/src/dmr_pi.c +++ b/src/dmr_pi.c @@ -27,43 +27,65 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC 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 + //NOTE: Some Kirisun Radios seem to use byte 2 as the SVC_OPT, others seem to use it like a KID value + // 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 + //NOTE: Original samples had this as 0x40 no matter which "key" was selected, new samples from different radio show a KID value + 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 on older FW 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 ALG and TGT value here to produce a key id via hashing it uint8_t hash = alg * target % 256; //more complex hash later (honestly, probably not) + //Only set real KID if the byte value isn't 0x40 + if (kid == 0x40) + kid = hash; + //MI only appears to be 32-bit uint32_t mi = ((uint32_t)PI_BYTE[3] << 24) | ((uint32_t)PI_BYTE[4] << 16) | ((uint32_t)PI_BYTE[5] << 8) | ((uint32_t)PI_BYTE[6] << 0); if (state->currentslot == 0) { - state->dmr_so = so; - state->payload_algid = alg; - state->payload_keyid = hash; + state->dmr_so = 0x40; + state->payload_algid = alg; + state->payload_keyid = kid; state->payload_mi = mi; } else { - state->dmr_soR = so; + state->dmr_soR = 0x40; state->payload_algidR = alg; - state->payload_keyidR = hash; + state->payload_keyidR = kid; 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): %08X;", alg, hash, mi); + fprintf (stderr, " DMR PI H- ALG ID: %02X; TGT: %d; KEY ID: %02X; MI(32): %08X;", alg, target, kid, mi); fprintf (stderr, " Kirisun "); - if (alg == 0x36) - fprintf (stderr, "Advanced;"); + if (alg == 0x31) + fprintf (stderr, "Reinforced "); + else if (alg == 0x32) + fprintf (stderr, "Low "); + else if (alg == 0x33) + fprintf (stderr, "Middle "); + else if (alg == 0x34) + fprintf (stderr, "High "); + else if (alg == 0x35) + fprintf (stderr, "Enhanced "); + else if (alg == 0x36) + fprintf (stderr, "Advanced "); else if (alg == 0x37) - fprintf (stderr, "Universal;"); - else fprintf (stderr, "Encryption;"); + fprintf (stderr, "Universal "); + else if (alg == 0x38) + fprintf (stderr, "Strengthened "); + else if (alg == 0x39) + fprintf (stderr, "Top "); + else if (alg == 0x3A) + fprintf (stderr, "Ultra "); + fprintf (stderr, "Encryption;"); 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 diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c index a1429fa..64d8f41 100644 --- a/src/dsd_audio2.c +++ b/src/dsd_audio2.c @@ -104,7 +104,15 @@ void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state) encL = 0; } } - else if (state->payload_algid == 0x24 || state->payload_algid == 0x25 || state->payload_algid == 0x36 || state->payload_algid == 0x37) + else if (state->payload_algid == 0x24 || state->payload_algid == 0x25) + { + //going to need a better check for this later on, or seperated keys or something + if (state->aes_key_loaded[0] == 1) + { + encL = 0; + } + } + else if (state->payload_algid >= 0x31 && state->payload_algid <= 0x3A) { //going to need a better check for this later on, or seperated keys or something if (state->aes_key_loaded[0] == 1) @@ -141,7 +149,15 @@ void playSynthesizedVoiceFS3 (dsd_opts * opts, dsd_state * state) encR = 0; } } - else if (state->payload_algidR == 0x24 || state->payload_algidR == 0x25 || state->payload_algidR == 0x36 || state->payload_algidR == 0x37) + else if (state->payload_algidR == 0x24 || state->payload_algidR == 0x25) + { + //going to need a better check for this later on, or seperated keys or something + if (state->aes_key_loaded[1] == 1) + { + encR = 0; + } + } + else if (state->payload_algidR >= 0x31 && state->payload_algidR <= 0x3A) { //going to need a better check for this later on, or seperated keys or something if (state->aes_key_loaded[1] == 1) @@ -738,13 +754,28 @@ void playSynthesizedVoiceFM (dsd_opts * opts, dsd_state * state) encL = 0; } } - else if (state->payload_algid == 0x84 || state->payload_algid == 0x89 || state->nxdn_cipher_type == 0x3 || state->payload_algid == 0x36 || state->payload_algid == 0x37) + else if (state->payload_algid == 0x84 || state->payload_algid == 0x89 || state->nxdn_cipher_type == 0x3) { if (state->aes_key_loaded[0] == 1) { encL = 0; } } + else if (state->payload_algid >= 0x31 && state->payload_algid <= 0x3A) + { + //going to need a better check for this later on, or seperated keys or something + if (state->aes_key_loaded[0] == 1) + { + encL = 0; + } + } + else if (state->payload_algidR == 0x26) + { + if (state->straight_ks == 0x26) + { + encL = 0; + } + } } //WIP: Mute if on B list (or not W list) @@ -1157,7 +1188,15 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) encL = 0; } } - else if (state->payload_algid == 0x24 || state->payload_algid == 0x25 || state->payload_algid == 0x36 || state->payload_algid == 0x37) + else if (state->payload_algid == 0x24 || state->payload_algid == 0x25) + { + //going to need a better check for this later on, or seperated keys or something + if (state->aes_key_loaded[0] == 1) + { + encL = 0; + } + } + else if (state->payload_algid >= 0x31 && state->payload_algid <= 0x3A) { //going to need a better check for this later on, or seperated keys or something if (state->aes_key_loaded[0] == 1) @@ -1194,7 +1233,15 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) encR = 0; } } - else if (state->payload_algidR == 0x24 || state->payload_algidR == 0x25 || state->payload_algidR == 0x36 || state->payload_algidR == 0x37) + else if (state->payload_algidR == 0x24 || state->payload_algidR == 0x25) + { + //going to need a better check for this later on, or seperated keys or something + if (state->aes_key_loaded[1] == 1) + { + encR = 0; + } + } + else if (state->payload_algidR >= 0x31 && state->payload_algidR <= 0x3A) { //going to need a better check for this later on, or seperated keys or something if (state->aes_key_loaded[1] == 1) diff --git a/src/dsd_main.c b/src/dsd_main.c index d50a70a..6b050b1 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1542,7 +1542,7 @@ printf (" -H '736B9A9C5645288B 243AD5CB8701EF8A' \n"); printf (" -H '20029736A5D91042 C923EB0697484433 005EFC58A1905195 E28E9C7836AA2DB8' \n"); printf ("\n"); - printf (" -H Manually Enter AES-128, AES-256, or Kirisun-256 Hex Key (see example below)\n"); + printf (" -H Manually Enter AES-128, AES-256, or Kirisun 128 or 256 Hex Key (see example below)\n"); printf (" Encapulate in Single Quotation Marks; Space every 16 chars.\n"); printf (" -H '736B9A9C5645288B 243AD5CB8701EF8A' \n"); printf (" -H '20029736A5D91042 C923EB0697484433 005EFC58A1905195 E28E9C7836AA2DB8' \n"); diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c index 3f925a3..d65cb9e 100644 --- a/src/dsd_mbe.c +++ b/src/dsd_mbe.c @@ -304,9 +304,9 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a if (state->payload_algid == 0x9F) //DES-XL des_multi_keystream_output (state->payload_miP, state->R, state->ks_octetL, 2, state->xl_is_hdu); //hard coded bit count value, xl_is_hdu determines lfsr run values if (state->payload_algid == 0x84) //AES256 - aes_ofb_keystream_output (state->aes_iv, aes_key, state->ks_octetL, 2, 14); //14 + 1 discard round + aes_ofb_keystream_output (state->aes_iv, aes_key, state->ks_octetL, 2, 16); //15 + 1 discard round if (state->payload_algid == 0x89) //AES128 - aes_ofb_keystream_output (state->aes_iv, aes_key, state->ks_octetL, 0, 14); //14 + 1 discard round + aes_ofb_keystream_output (state->aes_iv, aes_key, state->ks_octetL, 0, 16); //15 + 1 discard round } @@ -779,8 +779,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a (state->currentslot == 0 && state->payload_algid == 0x25 && state->aes_key_loaded[0] == 1 ) || //DMR AES256 (state->currentslot == 0 && state->payload_algid == 0x89 && state->aes_key_loaded[0] == 1 ) || //P25 AES128 (state->currentslot == 0 && state->payload_algid == 0x84 && state->aes_key_loaded[0] == 1 ) || //P25 AES256 - (state->currentslot == 0 && state->payload_algid == 0x36 && state->aes_key_loaded[0] == 1 ) || //KIRI ADV - (state->currentslot == 0 && state->payload_algid == 0x37 && state->aes_key_loaded[0] == 1 ) || //KIRI UNI + (state->currentslot == 0 && state->payload_algid >= 0x31 && \ + state->payload_algid <= 0x3A && state->aes_key_loaded[0] == 1 ) || //KIRI Any (state->currentslot == 0 && state->payload_algid == 0x02 && state->R != 0 ) ) //HYT ENHANCED { @@ -815,17 +815,11 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a n = 0; hytera_enhanced_rc4_setup(opts, state, state->R, state->payload_mi); } - if (state->payload_algid == 0x36) + if (state->payload_algid >= 0x31 && state->payload_algid <= 0x3A) { n = 0; - kirisun_adv_keystream_creation(state); + kirisun_keystream_creation(state); } - if (state->payload_algid == 0x37) - { - n = 0; - kirisun_uni_keystream_creation(state); - } - //Load Keystream Octet Bytes directly into keystream array //TODO: Convert to unpack function for (i = 0; i < 9 * 16; i++) //9 rounds at 16 octets { @@ -1285,8 +1279,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a (state->currentslot == 1 && state->payload_algidR == 0x25 && state->aes_key_loaded[1] == 1 ) || //DMR AES256 (state->currentslot == 1 && state->payload_algidR == 0x89 && state->aes_key_loaded[1] == 1 ) || //P25 AES128 (state->currentslot == 1 && state->payload_algidR == 0x84 && state->aes_key_loaded[1] == 1 ) || //P25 AES256 - (state->currentslot == 1 && state->payload_algidR == 0x36 && state->aes_key_loaded[1] == 1 ) || //KIRI ADV - (state->currentslot == 1 && state->payload_algidR == 0x37 && state->aes_key_loaded[1] == 1 ) || //KIRI UNI + (state->currentslot == 1 && state->payload_algidR >= 0x31 && \ + state->payload_algidR <= 0x3A && state->aes_key_loaded[1] == 1 ) || //KIRI Any (state->currentslot == 1 && state->payload_algidR == 0x02 && state->RR != 0 ) ) //HYT ENHANCED { @@ -1321,17 +1315,11 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a n = 0; hytera_enhanced_rc4_setup(opts, state, state->RR, state->payload_miR); } - if (state->payload_algidR == 0x36) + if (state->payload_algidR >= 0x31 && state->payload_algidR <= 0x3A) { n = 0; - kirisun_adv_keystream_creation(state); + kirisun_keystream_creation(state); } - if (state->payload_algidR == 0x37) - { - n = 0; - kirisun_uni_keystream_creation(state); - } - //Load Keystream Octet Bytes directly into keystream array for (i = 0; i < 9 * 16; i++) //9 rounds at 16 octets //TODO: Convert to unpack function { diff --git a/src/dsd_ncurses_printer.c b/src/dsd_ncurses_printer.c index 57f4447..783ef72 100644 --- a/src/dsd_ncurses_printer.c +++ b/src/dsd_ncurses_printer.c @@ -1125,26 +1125,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw(" Key: %010llX", state->R); attron(COLOR_PAIR(3)); } - if (state->payload_algid == 0x36) + if (state->payload_algid >= 0x31 && state->payload_algid <= 0x3A) { attron(COLOR_PAIR(1)); - printw("Kirisun Advanced "); + printw("Kirisun Encryption "); 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"); @@ -1327,26 +1314,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw(" Key: %010llX", state->RR); attron(COLOR_PAIR(3)); } - if (state->payload_algidR == 0x36) + if (state->payload_algidR >= 0x31 && state->payload_algidR <= 0x3A) { 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");