kopia lustrzana https://github.com/M17-Project/M17_Implementations
bugfixes
-aes_t enum -fixed key load bug when loaded from file -removed some spaces for formatting consistencypull/35/head
rodzic
be13f76803
commit
8f73286422
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
//TODO: Load Signature Private and Public Keys from file
|
//TODO: Load Signature Private and Public Keys from file
|
||||||
//TODO: More Thorough Testing to make sure everything is good
|
//TODO: More Thorough Testing to make sure everything is good
|
||||||
//TODO: Round of Cleanup (and test after cleaning up!
|
//TODO: Round of Cleanup (and test after cleaning up!)
|
||||||
//TODO: OR Frametype Bits depending on encryption type, subtype, and signed sig
|
//TODO: OR Frametype Bits depending on encryption type, subtype, and signed sig
|
||||||
|
|
||||||
//Wishlist: Please Woj, can we use the subtype on AES to signal AES 128, AES 192, or AES 256?
|
//Wishlist: Please Woj, can we use the subtype on AES to signal AES 128, AES 192, or AES 256?
|
||||||
|
@ -52,7 +52,12 @@ int dummy=0; //dummy var to make compiler quieter
|
||||||
|
|
||||||
//AES
|
//AES
|
||||||
uint8_t encryption=0;
|
uint8_t encryption=0;
|
||||||
int aes_type = 1; //1=AES128, 2=AES192, 3=AES256
|
typedef enum
|
||||||
|
{
|
||||||
|
AES128=1,
|
||||||
|
AES192,
|
||||||
|
AES256
|
||||||
|
} aes_t;
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
time_t epoch = 1577836800L; //Jan 1, 2020, 00:00:00 UTC
|
time_t epoch = 1577836800L; //Jan 1, 2020, 00:00:00 UTC
|
||||||
|
@ -63,7 +68,7 @@ uint8_t scrambler_pn[128];
|
||||||
uint32_t scrambler_seed=0;
|
uint32_t scrambler_seed=0;
|
||||||
int8_t scrambler_subtype = -1;
|
int8_t scrambler_subtype = -1;
|
||||||
|
|
||||||
//debug mode (preset lsf, type, zero payload for enc testing, etc)
|
//debug mode (preset lsf, type, fixed dummy payload for enc testing, etc)
|
||||||
uint8_t debug_mode=0;
|
uint8_t debug_mode=0;
|
||||||
|
|
||||||
//scrambler pn sequence generation
|
//scrambler pn sequence generation
|
||||||
|
@ -75,7 +80,7 @@ void scrambler_sequence_generator()
|
||||||
|
|
||||||
//only set if not initially set (first run), it is possible (and observed) that the scrambler_subtype can
|
//only set if not initially set (first run), it is possible (and observed) that the scrambler_subtype can
|
||||||
//change on subsequent passes if the current SEED for the LFSR falls below one of these thresholds
|
//change on subsequent passes if the current SEED for the LFSR falls below one of these thresholds
|
||||||
if (scrambler_subtype == -1)
|
if(scrambler_subtype == -1)
|
||||||
{
|
{
|
||||||
if (lfsr > 0 && lfsr <= 0xFF) scrambler_subtype = 0; // 8-bit key
|
if (lfsr > 0 && lfsr <= 0xFF) scrambler_subtype = 0; // 8-bit key
|
||||||
else if (lfsr > 0xFF && lfsr <= 0xFFFF) scrambler_subtype = 1; //16-bit key
|
else if (lfsr > 0xFF && lfsr <= 0xFFFF) scrambler_subtype = 1; //16-bit key
|
||||||
|
@ -84,21 +89,21 @@ void scrambler_sequence_generator()
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Set Frame Type based on scrambler_subtype value
|
//TODO: Set Frame Type based on scrambler_subtype value
|
||||||
if (debug_mode > 1)
|
if(debug_mode>1)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "\nScrambler Key: 0x%06X; Seed: 0x%06X; Subtype: %02d;", scrambler_seed, lfsr, scrambler_subtype);
|
fprintf (stderr, "\nScrambler Key: 0x%06X; Seed: 0x%06X; Subtype: %02d;", scrambler_seed, lfsr, scrambler_subtype);
|
||||||
fprintf (stderr, "\n pN: ");
|
fprintf (stderr, "\n pN: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
//run pN sequence with taps specified
|
//run pN sequence with taps specified
|
||||||
for (i = 0; i < 128; i++)
|
for(i=0; i<128; i++)
|
||||||
{
|
{
|
||||||
//get feedback bit with specified taps, depending on the scrambler_subtype
|
//get feedback bit with specified taps, depending on the scrambler_subtype
|
||||||
if (scrambler_subtype == 0)
|
if(scrambler_subtype == 0)
|
||||||
bit = (lfsr >> 7) ^ (lfsr >> 5) ^ (lfsr >> 4) ^ (lfsr >> 3);
|
bit = (lfsr >> 7) ^ (lfsr >> 5) ^ (lfsr >> 4) ^ (lfsr >> 3);
|
||||||
else if (scrambler_subtype == 1)
|
else if(scrambler_subtype == 1)
|
||||||
bit = (lfsr >> 15) ^ (lfsr >> 14) ^ (lfsr >> 12) ^ (lfsr >> 3);
|
bit = (lfsr >> 15) ^ (lfsr >> 14) ^ (lfsr >> 12) ^ (lfsr >> 3);
|
||||||
else if (scrambler_subtype == 2)
|
else if(scrambler_subtype == 2)
|
||||||
bit = (lfsr >> 23) ^ (lfsr >> 22) ^ (lfsr >> 21) ^ (lfsr >> 16);
|
bit = (lfsr >> 23) ^ (lfsr >> 22) ^ (lfsr >> 21) ^ (lfsr >> 16);
|
||||||
else bit = 0; //should never get here, but just in case
|
else bit = 0; //should never get here, but just in case
|
||||||
|
|
||||||
|
@ -116,15 +121,15 @@ void scrambler_sequence_generator()
|
||||||
scrambler_seed = lfsr;
|
scrambler_seed = lfsr;
|
||||||
|
|
||||||
//truncate seed so subtype will continue to set properly on subsequent passes
|
//truncate seed so subtype will continue to set properly on subsequent passes
|
||||||
if (scrambler_subtype == 0) scrambler_seed &= 0xFF;
|
if(scrambler_subtype == 0) scrambler_seed &= 0xFF;
|
||||||
if (scrambler_subtype == 1) scrambler_seed &= 0xFFFF;
|
if(scrambler_subtype == 1) scrambler_seed &= 0xFFFF;
|
||||||
if (scrambler_subtype == 2) scrambler_seed &= 0xFFFFFF;
|
if(scrambler_subtype == 2) scrambler_seed &= 0xFFFFFF;
|
||||||
else scrambler_seed &= 0xFF;
|
else scrambler_seed &= 0xFF;
|
||||||
|
|
||||||
if (debug_mode > 1)
|
if(debug_mode>1)
|
||||||
{
|
{
|
||||||
//debug packed bytes
|
//debug packed bytes
|
||||||
for (i = 0; i < 16; i++)
|
for(i = 0; i < 16; i++)
|
||||||
fprintf (stderr, " %02X", scr_bytes[i]);
|
fprintf (stderr, " %02X", scr_bytes[i]);
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
@ -369,12 +374,12 @@ int main(int argc, char* argv[])
|
||||||
send_preamble(frame_buff, &frame_buff_cnt, 0); //0 - LSF preamble, as opposed to 1 - BERT preamble
|
send_preamble(frame_buff, &frame_buff_cnt, 0); //0 - LSF preamble, as opposed to 1 - BERT preamble
|
||||||
fwrite((uint8_t*)frame_buff, SYM_PER_FRA*sizeof(float), 1, stdout);
|
fwrite((uint8_t*)frame_buff, SYM_PER_FRA*sizeof(float), 1, stdout);
|
||||||
|
|
||||||
if (debug_mode == 1)
|
if(debug_mode == 1)
|
||||||
{
|
{
|
||||||
//broadcast
|
//destination set to "ALL"
|
||||||
memset(lsf.dst, 0xFF, 6*sizeof(uint8_t));
|
memset(lsf.dst, 0xFF, 6*sizeof(uint8_t));
|
||||||
|
|
||||||
//N0CALL
|
//source set to "N0CALL"
|
||||||
lsf.src[0] = 0x00;
|
lsf.src[0] = 0x00;
|
||||||
lsf.src[1] = 0x00;
|
lsf.src[1] = 0x00;
|
||||||
lsf.src[2] = 0x4B;
|
lsf.src[2] = 0x4B;
|
||||||
|
@ -382,12 +387,12 @@ int main(int argc, char* argv[])
|
||||||
lsf.src[4] = 0xD1;
|
lsf.src[4] = 0xD1;
|
||||||
lsf.src[5] = 0x06;
|
lsf.src[5] = 0x06;
|
||||||
|
|
||||||
if (encryption == 2) //AES ENC, 3200 voice
|
if(encryption == 2) //AES ENC, 3200 voice
|
||||||
{
|
{
|
||||||
lsf.type[0] = 0x03;
|
lsf.type[0] = 0x03;
|
||||||
lsf.type[1] = 0x95;
|
lsf.type[1] = 0x95;
|
||||||
}
|
}
|
||||||
else if (encryption == 1) //Scrambler ENC, 3200 Voice
|
else if(encryption == 1) //Scrambler ENC, 3200 Voice
|
||||||
{
|
{
|
||||||
lsf.type[0] = 0x03;
|
lsf.type[0] = 0x03;
|
||||||
lsf.type[1] = 0xCD;
|
lsf.type[1] = 0xCD;
|
||||||
|
@ -414,7 +419,7 @@ int main(int argc, char* argv[])
|
||||||
finished = 0;
|
finished = 0;
|
||||||
|
|
||||||
//debug sig with random payloads (don't play the audio)
|
//debug sig with random payloads (don't play the audio)
|
||||||
for (uint8_t i = 0; i < 16; i++)
|
for(uint8_t i = 0; i < 16; i++)
|
||||||
data[i] = 0x69; //rand() & 0xFF;
|
data[i] = 0x69; //rand() & 0xFF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -473,12 +478,12 @@ int main(int argc, char* argv[])
|
||||||
got_lsf=1;
|
got_lsf=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_mode == 1)
|
if(debug_mode==1)
|
||||||
{
|
{
|
||||||
//broadcast
|
//destination set to "ALL"
|
||||||
memset(next_lsf.dst, 0xFF, 6*sizeof(uint8_t));
|
memset(next_lsf.dst, 0xFF, 6*sizeof(uint8_t));
|
||||||
|
|
||||||
//N0CALL
|
//source set to "N0CALL"
|
||||||
next_lsf.src[0] = 0x00;
|
next_lsf.src[0] = 0x00;
|
||||||
next_lsf.src[1] = 0x00;
|
next_lsf.src[1] = 0x00;
|
||||||
next_lsf.src[2] = 0x4B;
|
next_lsf.src[2] = 0x4B;
|
||||||
|
@ -486,12 +491,12 @@ int main(int argc, char* argv[])
|
||||||
next_lsf.src[4] = 0xD1;
|
next_lsf.src[4] = 0xD1;
|
||||||
next_lsf.src[5] = 0x06;
|
next_lsf.src[5] = 0x06;
|
||||||
|
|
||||||
if (encryption == 2) //AES ENC, 3200 voice
|
if(encryption==2) //AES ENC, 3200 voice
|
||||||
{
|
{
|
||||||
next_lsf.type[0] = 0x03;
|
next_lsf.type[0] = 0x03;
|
||||||
next_lsf.type[1] = 0x95;
|
next_lsf.type[1] = 0x95;
|
||||||
}
|
}
|
||||||
else if (encryption == 1) //Scrambler ENC, 3200 Voice
|
else if(encryption==1) //Scrambler ENC, 3200 Voice
|
||||||
{
|
{
|
||||||
next_lsf.type[0] = 0x03;
|
next_lsf.type[0] = 0x03;
|
||||||
next_lsf.type[1] = 0xCD;
|
next_lsf.type[1] = 0xCD;
|
||||||
|
@ -510,11 +515,11 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
memset(next_data, 0, sizeof(next_data));
|
memset(next_data, 0, sizeof(next_data));
|
||||||
memcpy(data, next_data, sizeof(data));
|
memcpy(data, next_data, sizeof(data));
|
||||||
if (fn == 60)
|
if(fn == 60)
|
||||||
finished = 1;
|
finished = 1;
|
||||||
|
|
||||||
//debug sig with random payloads (don't play the audio)
|
//debug sig with random payloads (don't play the audio)
|
||||||
for (uint8_t i = 0; i < 16; i++)
|
for(uint8_t i = 0; i < 16; i++)
|
||||||
data[i] = 0x69; //rand() & 0xFF;
|
data[i] = 0x69; //rand() & 0xFF;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -534,11 +539,11 @@ int main(int argc, char* argv[])
|
||||||
memcpy(&(next_lsf.meta), iv, 14);
|
memcpy(&(next_lsf.meta), iv, 14);
|
||||||
iv[14] = (fn >> 8) & 0x7F;
|
iv[14] = (fn >> 8) & 0x7F;
|
||||||
iv[15] = (fn >> 0) & 0xFF;
|
iv[15] = (fn >> 0) & 0xFF;
|
||||||
aes_ctr_bytewise_payload_crypt(iv, key, data, aes_type);
|
aes_ctr_bytewise_payload_crypt(iv, key, data, AES128); //hardcoded for now
|
||||||
}
|
}
|
||||||
|
|
||||||
//Scrambler
|
//Scrambler
|
||||||
else if (encryption == 1)
|
else if(encryption == 1)
|
||||||
{
|
{
|
||||||
scrambler_sequence_generator();
|
scrambler_sequence_generator();
|
||||||
for(uint8_t i=0; i<16; i++)
|
for(uint8_t i=0; i<16; i++)
|
||||||
|
@ -670,12 +675,12 @@ int main(int argc, char* argv[])
|
||||||
fprintf(stderr, "%02X", sig[i]);
|
fprintf(stderr, "%02X", sig[i]);
|
||||||
fprintf(stderr, "\n");*/
|
fprintf(stderr, "\n");*/
|
||||||
|
|
||||||
if (debug_mode == 1)
|
if(debug_mode == 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Signature: ");
|
fprintf(stderr, "Signature: ");
|
||||||
for(uint8_t i=0; i<sizeof(sig); i++)
|
for(uint8_t i=0; i<sizeof(sig); i++)
|
||||||
{
|
{
|
||||||
if (i == 16 || i == 32 || i == 48)
|
if(i == 16 || i == 32 || i == 48)
|
||||||
fprintf(stderr, "\n ");
|
fprintf(stderr, "\n ");
|
||||||
fprintf(stderr, "%02X", sig[i]);
|
fprintf(stderr, "%02X", sig[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,12 @@ uint8_t sig[64]={0}; //ECDSA signature
|
||||||
|
|
||||||
//AES
|
//AES
|
||||||
uint8_t encryption=0;
|
uint8_t encryption=0;
|
||||||
int aes_type = 1; //1=AES128, 2=AES192, 3=AES256
|
typedef enum
|
||||||
|
{
|
||||||
|
AES128=1,
|
||||||
|
AES192,
|
||||||
|
AES256
|
||||||
|
} aes_t;
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
time_t epoch = 1577836800L; //Jan 1, 2020, 00:00:00 UTC
|
time_t epoch = 1577836800L; //Jan 1, 2020, 00:00:00 UTC
|
||||||
|
@ -296,10 +301,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(strstr(argv[i+1], ".")) //if the next arg contains a dot - read key from a text file
|
if(strstr(argv[i+1], ".")) //if the next arg contains a dot - read key from a text file
|
||||||
{
|
{
|
||||||
char fname[128]={'\0'}; //output file
|
if(strlen(argv[i+1])<3)
|
||||||
if(strlen(&argv[i+1][0])>0)
|
|
||||||
memcpy(fname, &argv[i+1][0], strlen(argv[i+1]));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Invalid filename. Exiting...\n");
|
fprintf(stderr, "Invalid filename. Exiting...\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -308,10 +310,10 @@ int main(int argc, char* argv[])
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
char source_str[64];
|
char source_str[64];
|
||||||
|
|
||||||
fp = fopen(fname, "r");
|
fp = fopen(argv[i+1], "r");
|
||||||
if(!fp)
|
if(!fp)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to load file %s.\n", fname);
|
fprintf(stderr, "Failed to load file %s.\n", argv[i+1]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +343,8 @@ int main(int argc, char* argv[])
|
||||||
fprintf(stderr, " %02X", key[i]);
|
fprintf(stderr, " %02X", key[i]);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -509,16 +513,16 @@ int main(int argc, char* argv[])
|
||||||
//The Signature is not encrypted
|
//The Signature is not encrypted
|
||||||
|
|
||||||
//AES
|
//AES
|
||||||
if (encryption == 2 && fn<0x7FFC)
|
if(encryption == 2 && fn<0x7FFC)
|
||||||
{
|
{
|
||||||
memcpy(iv, lsf+14, 14);
|
memcpy(iv, lsf+14, 14);
|
||||||
iv[14] = frame_data[1] & 0x7F;
|
iv[14] = frame_data[1] & 0x7F;
|
||||||
iv[15] = frame_data[2] & 0xFF;
|
iv[15] = frame_data[2] & 0xFF;
|
||||||
aes_ctr_bytewise_payload_crypt(iv, key, frame_data+3, aes_type);
|
aes_ctr_bytewise_payload_crypt(iv, key, frame_data+3, AES128); //hardcoded for now
|
||||||
}
|
}
|
||||||
|
|
||||||
//Scrambler
|
//Scrambler
|
||||||
if (encryption == 1 && fn<0x7FFC)
|
if(encryption == 1 && fn<0x7FFC)
|
||||||
{
|
{
|
||||||
if ((fn % 0x8000)!=expected_next_fn) //frame skip, etc
|
if ((fn % 0x8000)!=expected_next_fn) //frame skip, etc
|
||||||
scrambler_seed = scrambler_seed_calculation(scrambler_subtype, scrambler_key, fn&0x7FFF);
|
scrambler_seed = scrambler_seed_calculation(scrambler_subtype, scrambler_key, fn&0x7FFF);
|
||||||
|
|
Ładowanie…
Reference in New Issue