Merge branch 'crypto' into 'auth' (WIP); TODO: Manually Copy Crypto Code in Auto coder-sym.c file;

pull/33/head
lwvmobile 2024-06-22 10:08:50 -04:00
commit bb94f37ae8
8 zmienionych plików z 210 dodań i 64 usunięć

3
.gitignore vendored
Wyświetl plik

@ -9,4 +9,5 @@
*.wav
*.bin
*.sym
*.patch
*.patch
*.txt

3
.gitmodules vendored
Wyświetl plik

@ -4,3 +4,6 @@
[submodule "micro-ecc"]
path = micro-ecc
url = https://github.com/kmackay/micro-ecc
[submodule "tinier-aes"]
path = tinier-aes
url = https://github.com/lwvmobile/tinier-aes

101
README.md
Wyświetl plik

@ -77,7 +77,9 @@ Packet encoding is available with `m17-packet-encoder`. Its input parameters are
-S - source callsign (uppercase alphanumeric string) max. 9 characters
-D - destination callsign (uppercase alphanumeric string) or ALL for broadcast
-C - Channel Access Number (0..15, default - 0)
-n - number of bytes (1 to 798)
-T - SMS Text Message (example: -T 'Hello World! This is a text message')
-R - Raw Hex Octets (example: -R 010203040506070809)
-n - number of bytes, only when pre-encoded data passed over stdin (1 to 798)
-o - output file path/name
-x - binary output (M17 baseband as a packed bitstream)
-r - raw audio output - default (single channel, signed 16-bit LE, +7168 for the +1.0 symbol, 10 samples per symbol)
@ -87,7 +89,7 @@ Packet encoding is available with `m17-packet-encoder`. Its input parameters are
-w - libsndfile wav audio output - default (single channel, signed 16-bit LE, +7168 for the +1.0 symbol, 10 samples per symbol)
```
Input data is passed over stdin. Example command:
Input data can be pre-encoded and passed over stdin. Example command:
`echo -en "\x05Testing M17 packet mode.\x00" | ./m17-packet-encode -S N0CALL -D ALL -C 0 -n 26 -f -o baseband.sym`
@ -97,16 +99,16 @@ Input data is passed over stdin. Example command:
Output:
```
DST: ALL FFFFFFFFFFFF
SRC: N0CALL 00004B13D106
Data CRC: BFEC
LSF CRC: 432A
SMS: Testing M17 packet mode.
DST: ALL FFFFFFFFFFFF
SRC: N0CALL 00004B13D106
CAN: 00
Data CRC: BFEC
LSF CRC: 432A
FN:00 (full frame)
0554657374696E67204D3137207061636B6574206D6F64652E00
FN:-- (ending frame)
00BFEC0000000000000000000000000000000000000000000084
FULL: 0554657374696E67204D3137207061636B6574206D6F64652E00BFEC
SMS: Testing M17 packet mode.
PKT: 05 54 65 73 74 69 6E 67 20 4D 31 37 20 70 61 63 6B 65 74 20 6D 6F 64 65 2E
00 BF EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
```
Decode packet created with above sample:
@ -117,26 +119,28 @@ Output:
```
DST: FFFFFFFFFFFF SRC: 00004B13D106 TYPE: 0002 META: 0000000000000000000000000000 LSF_CRC_OK
Testing M17 packet mode.
SMS: Testing M17 packet mode.
```
Encode directly as wav format (skip sox):
Encode User Text String as wav format:
`echo -en "\x05Testing M17 packet mode.\x00" | ./m17-packet-encode -S N0CALL -D AB1CDE -C 7 -n 26 -w -o baseband.wav`
`./m17-packet-encode -S N0CALL -D AB1CDE -T 'This is an SMS Text Message Generated by m17-packet-encode' -C 7 -w -o baseband.wav`
Output:
```
DST: AB1CDE 00001F245D51
SRC: N0CALL 00004B13D106
Data CRC: BFEC
LSF CRC: F754
SMS: This is an SMS Text Message Generated by m17-packet-encode
DST: AB1CDE 00001F245D51
SRC: N0CALL 00004B13D106
CAN: 07
Data CRC: FD81
LSF CRC: F754
FN:00 (full frame)
0554657374696E67204D3137207061636B6574206D6F64652E00
FN:01 (full frame)
FN:-- (ending frame)
00BFEC0000000000000000000000000000000000000000000084
FULL: 0554657374696E67204D3137207061636B6574206D6F64652E00BFEC
SMS: Testing M17 packet mode.
PKT: 05 54 68 69 73 20 69 73 20 61 6E 20 53 4D 53 20 54 65 78 74 20 4D 65 73 73
61 67 65 20 47 65 6E 65 72 61 74 65 64 20 62 79 20 6D 31 37 2D 70 61 63 6B
65 74 2D 65 6E 63 6F 64 65 00 FD 81 00 00 00 00 00 00 00 00 00 00 00 00 00
```
Decode with M17-FME:
@ -147,26 +151,55 @@ Output:
```
M17 Project - Florida Man Edition
Build Version: 2024-1-g4f2c15c
Session Number: A4F5
Build Version: 2024-10-g060dd21
Session Number: A751
M17 Project RF Audio Frame Demodulator.
SNDFile (.wav, .rrc) Input File: baseband.wav
Payload Verbosity: 1;
M17 LSF Frame Sync (08:57:09):
DST: AB1CDE SRC: N0CALL CAN: 7; Data Packet
M17 LSF Frame Sync (16:12:34):
DST: AB1CDE SRC: N0CALL CAN: 7; Data Packet FT: 0382; ET: 0; ES: 0;
LSF: 00 00 1F 24 5D 51 00 00 4B 13 D1 06 03 82 00
00 00 00 00 00 00 00 00 00 00 00 00 00 F7 54
(CRC CHK) E: F754; C: F754;
M17 PKT Frame Sync (08:57:09): CNT: 00; PBC: 00; EOT: 0;
pkt: 0554657374696E67204D3137207061636B6574206D6F64652E00
M17 PKT Frame Sync (08:57:09): CNT: 01; LST: 01; EOT: 1;
pkt: 00BFEC0000000000000000000000000000000000000000000084 Protocol: SMS;
SMS: Testing M17 packet mode.
PKT: 05 54 65 73 74 69 6E 67 20 4D 31 37 20 70 61 63 6B 65 74 20 6D 6F 64 65 2E
00 BF EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(CRC CHK) E: BFEC; C: BFEC;
M17 No Frame Sync (08:57:09):
M17 PKT Frame Sync (16:12:34): CNT: 00; PBC: 00; EOT: 0;
pkt: 055468697320697320616E20534D532054657874204D65737300
M17 PKT Frame Sync (16:12:34): CNT: 01; PBC: 01; EOT: 0;
pkt: 6167652047656E657261746564206279206D31372D7061636B04
M17 PKT Frame Sync (16:12:34): CNT: 02; LST: 12; EOT: 1;
pkt: 65742D656E636F646500FD8100000000000000000000000000B0 Protocol: SMS;
SMS: This is an SMS Text Message Generated by m17-packet-encode
PKT: 05 54 68 69 73 20 69 73 20 61 6E 20 53 4D 53 20 54 65 78 74 20 4D 65 73 73
61 67 65 20 47 65 6E 65 72 61 74 65 64 20 62 79 20 6D 31 37 2D 70 61 63 6B
65 74 2D 65 6E 63 6F 64 65 00 FD 81 00 00 00 00 00 00 00 00 00 00 00 00 00
(CRC CHK) E: FD81; C: FD81;
```
Encode Raw Hex Octet String as float symbol format:
`./m17-packet-encode -S N0CALL -D AB1CDE -R 010203040506070809 -C 7 -f -o float.sym`
Output:
```
Raw Len: 9; Raw Octets: 01 02 03 04 05 06 07 08 09
DST: AB1CDE 00001F245D51
SRC: N0CALL 00004B13D106
CAN: 07
Data CRC: D7CE
LSF CRC: F754
FN:-- (ending frame)
PKT: 01 02 03 04 05 06 07 08 09 D7 CE 00 00 00 00 00 00 00 00 00 00 00 00 00 00
```
Decode (rolling) packets created with above sample:
`tail -f float.sym | ./m17-packet-decode`
Output:
```
DST: 00001F245D51 SRC: 00004B13D106 TYPE: 0382 META: 0000000000000000000000000000 LSF_CRC_OK
PKT: 01 02 03 04 05 06 07 08 09 D7 CE
```

Wyświetl plik

@ -1,5 +1,5 @@
m17-coder-sym: m17-coder-sym.c
gcc -O2 -Wall -Wextra m17-coder-sym.c ../../micro-ecc/uECC.c -o m17-coder-sym -lm -lm17
gcc -O2 -Wall -Wextra m17-coder-sym.c ../../micro-ecc/uECC.c ../../tinier-aes/aes.c -o m17-coder-sym -lm -lm17
clean:
rm -f m17-coder-sym

Wyświetl plik

@ -0,0 +1 @@
1234567890ABCDEF7777777777777777FEDCBA09876543218888888888888888

Wyświetl plik

@ -207,10 +207,10 @@ int main(int argc, char* argv[])
{
uint16_t p_len=strlen((const char*)packet_data);
uint16_t p_crc=CRC_M17(packet_data, p_len+1);
fprintf(stderr, "Data CRC: rx=%02X%02X calc=%04X\n ", packet_data[p_len+1], packet_data[p_len+2], p_crc);
fprintf(stderr, "Data CRC: rx=%02X%02X calc=%04X\n", packet_data[p_len+1], packet_data[p_len+2], p_crc);
if(p_crc==(uint16_t)packet_data[p_len+1]*256+(uint16_t)packet_data[p_len+2])
{
fprintf(stderr, "%s\n", &packet_data[1]);
fprintf(stderr, "SMS: %s\n", &packet_data[1]);
}
}
}
@ -218,10 +218,12 @@ int main(int argc, char* argv[])
{
if(!text_only)
{
fprintf(stderr, "PKT: ");
for(uint16_t i=0; i<last_fn*25+rx_fn; i++)
fprintf(stderr, "PKT:");
for(uint16_t i=0; i<(last_fn+1)*25+rx_fn; i++)
{
fprintf(stderr, "%02X", packet_data[i]);
if ( (i != 0) && ((i%25) == 0) )
fprintf(stderr, "\n ");
fprintf(stderr, " %02X", packet_data[i]);
}
fprintf(stderr, "\n");
}

Wyświetl plik

@ -40,6 +40,14 @@ uint8_t out_type=0; //output file type -
// 4 - S16-LE RRC filtered wav file
// 5 - float symbol output for m17-packet-decode
uint8_t std_encode = 1; //User Data is pre-encoded and read in over stdin, and not a switch string
uint8_t sms_encode = 0; //User Supplied Data is an SMS Text message, encode as such
uint8_t raw_encode = 0; //User Supplied Data is a string of hex octets, encode as such
char text[800] = "Default SMS Text message"; //SMS Text to Encode, default string.
uint8_t raw[800]; //raw data that is converted from a string comprised of hex octets
//type - 0 - preamble before LSF (standard)
//type - 1 - preamble before BERT transmission
void fill_preamble(float* out, const uint8_t type)
@ -87,12 +95,57 @@ void fill_data(float* out, uint16_t* cnt, const uint8_t* in)
}
}
//convert a user string (as hex octets) into a uint8_t array for raw packet encoding
void parse_raw_user_string (char * input)
{
//since we want this as octets, get strlen value, then divide by two
uint16_t len = strlen((const char*)input);
//if zero is returned, just do two
if (len == 0) len = 2;
//if odd number, then user didn't pass complete octets, but just add one to len value to make it even
if (len&1) len++;
//divide by two to get octet len
len /= 2;
//sanity check, maximum strlen should not exceed 798 for a full encode
if (len > 797) len = 797;
//set num_bytes to len + 1
num_bytes = len + 0; //doing 0 instead, let user pass an extra 00 on the end if they want it there
char octet_char[3];
octet_char[2] = 0;
uint16_t k = 0;
uint16_t i = 0;
//debug
fprintf (stderr, "\nRaw Len: %d; Raw Octets:", len);
for (i = 0; i < len; i++)
{
strncpy (octet_char, input+k, 2);
octet_char[2] = 0;
sscanf (octet_char, "%hhX", &raw[i]);
//debug
// fprintf (stderr, " (%s)", octet_char);
fprintf (stderr, " %02X", raw[i]);
k += 2;
}
fprintf (stderr, "\n");
}
//main routine
int main(int argc, char* argv[])
{
//scan command line options for input data
//TODO: support for strings with spaces, the code below is NOT foolproof!
//the user has to provide a minimum of 2 parameters: number of bytes and output filename
//WIP: support for text strings with spaces and raw hex octet strings (still NOT foolproof)
//the user has to provide a minimum of 2 parameters: input string or num_bytes, output type, and output filename
if(argc>=4)
{
for(uint8_t i=1; i<argc; i++)
@ -139,6 +192,28 @@ int main(int argc, char* argv[])
return -1;
}
}
else if(argv[i][1]=='T') //-T - User Text String
{
if(strlen(&argv[i+1][0])>0)
{
memset(text, 0, 800*sizeof(char));
memcpy(text, &argv[i+1][0], strlen(argv[i+1]));
std_encode = 0;
sms_encode = 1;
raw_encode = 0;
}
}
else if(argv[i][1]=='R') //-R - Raw Octets
{
if(strlen(&argv[i+1][0])>0)
{
memset (raw, 0, sizeof(raw));
parse_raw_user_string (argv[i+1]);
std_encode = 0;
sms_encode = 0;
raw_encode = 1;
}
}
else if(argv[i][1]=='o') //-o - output filename
{
if(strlen(&argv[i+1][0])>0)
@ -187,7 +262,9 @@ int main(int argc, char* argv[])
fprintf(stderr, "-S - source callsign (uppercase alphanumeric string) max. 9 characters,\n");
fprintf(stderr, "-D - destination callsign (uppercase alphanumeric string) or ALL for broadcast,\n");
fprintf(stderr, "-C - Channel Access Number (0..15, default - 0),\n");
fprintf(stderr, "-n - number of bytes (1 to 798),\n");
fprintf(stderr, "-T - SMS Text Message (example: -T 'Hello World! This is a text message'),\n");
fprintf(stderr, "-R - Raw Hex Octets (example: -R 010203040506070809),\n");
fprintf(stderr, "-n - number of bytes, only when pre-encoded data passed over stdin (1 to 798),\n");
fprintf(stderr, "-o - output file path/name,\n");
fprintf(stderr, "Output formats:\n");
//fprintf(stderr, "-x - binary output (M17 baseband as a packed bitstream),\n");
@ -199,13 +276,8 @@ int main(int argc, char* argv[])
return -1;
}
//assert number of bytes and filename
if(num_bytes==0)
{
fprintf(stderr, "Number of bytes not set. Exiting...\n");
return -1;
}
else if(strlen((const char*)fname)==0)
//assert filename and not binary output
if(strlen((const char*)fname)==0)
{
fprintf(stderr, "Filename not specified. Exiting...\n");
return -1;
@ -218,12 +290,43 @@ int main(int argc, char* argv[])
//obtain data and append with CRC
memset(full_packet_data, 0, 32*25);
if(fread(full_packet_data, num_bytes, 1, stdin)<1)
//SMS Encode (-T) ./m17-packet-encode -f -o float.sym -T 'This is a simple SMS text message sent over M17 Packet Data.'
if (sms_encode == 1)
{
fprintf(stderr, "Packet data too short. Exiting...\n");
return -1;
num_bytes = strlen((const char*)text); //No need to check for zero return, since the default text string is supplied
if (num_bytes > 796) num_bytes = 796; //not 798 because we have to manually add the 0x05 protocol byte and 0x00 terminator
full_packet_data[0] = 0x05; //SMS Protocol
memcpy (full_packet_data+1, text, num_bytes);
num_bytes+= 2; //add one for terminating byte and 1 for strlen fix
fprintf (stderr, "SMS: %s\n", full_packet_data+1);
}
//RAW Encode (-R) ./m17-packet-encode -f -o float.sym -R 5B69001E135152397C0A0000005A45
else if (raw_encode == 1)
{
memcpy (full_packet_data, raw, num_bytes);
}
//Old Method pre-encoded data over stdin // echo -en "\x05Testing M17 packet mode.\x00" | ./m17-packet-encode -S N0CALL -D AB1CDE -C 7 -n 26 -f -o float.sym
else if (std_encode == 1)
{
//assert number of bytes
if(num_bytes==0)
{
fprintf(stderr, "Number of bytes not set. Exiting...\n");
return -1;
}
if(fread(full_packet_data, num_bytes, 1, stdin)<1)
{
fprintf(stderr, "Packet data too short. Exiting...\n");
return -1;
}
fprintf(stderr, "SMS: %s\n", full_packet_data+1);
//
}
uint16_t packet_crc=CRC_M17(full_packet_data, num_bytes);
full_packet_data[num_bytes] =packet_crc>>8;
full_packet_data[num_bytes+1]=packet_crc&0xFF;
@ -244,8 +347,7 @@ int main(int argc, char* argv[])
#else
fprintf(stderr, "DST: %s\t%012lX\nSRC: %s\t%012lX\n", dst_raw, dst_encoded, src_raw, src_encoded);
#endif
//fprintf(stderr, "DST: %02X %02X %02X %02X %02X %02X\n", lsf.dst[0], lsf.dst[1], lsf.dst[2], lsf.dst[3], lsf.dst[4], lsf.dst[5]);
//fprintf(stderr, "SRC: %02X %02X %02X %02X %02X %02X\n", lsf.src[0], lsf.src[1], lsf.src[2], lsf.src[3], lsf.src[4], lsf.src[5]);
fprintf(stderr, "CAN: %02d\n", can);
fprintf(stderr, "Data CRC:\t%04hX\n", packet_crc);
type=((uint16_t)0x01<<1)|((uint16_t)can<<7); //packet mode, content: data
lsf.type[0]=(uint16_t)type>>8;
@ -296,7 +398,10 @@ int main(int argc, char* argv[])
//send packet frame syncword
fill_syncword(full_packet, &pkt_sym_cnt, SYNC_PKT);
if(num_bytes>=25)
//the following examples produce exactly 25 bytes, which exactly one frame, but >= meant this would never produce a final frame with EOT bit set
//echo -en "\x05Testing M17 packet mo\x00" | ./m17-packet-encode -S N0CALL -D ALL -C 10 -n 23 -o float.sym -f
//./m17-packet-encode -S N0CALL -D ALL -C 10 -o float.sym -f -T 'this is a simple text'
if(num_bytes>25) //fix for frames that, with terminating byte and crc, land exactly on 25 bytes (or %25==0)
{
memcpy(pkt_chunk, &full_packet_data[pkt_cnt*25], 25);
pkt_chunk[25]=pkt_cnt<<2;
@ -368,16 +473,16 @@ int main(int argc, char* argv[])
}
num_bytes=tmp; //bring back the num_bytes value
fprintf (stderr, "FULL: ");
for(uint8_t i=0; i<tmp; i++)
fprintf (stderr, "PKT:");
for(uint8_t i=0; i<pkt_cnt*25; i++)
{
fprintf (stderr, "%02X", full_packet_data[i]);
if ( (i != 0) && ((i%25) == 0) )
fprintf (stderr, "\n ");
fprintf (stderr, " %02X", full_packet_data[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, " SMS: %s\n", full_packet_data);
//send EOT
for(uint8_t i=0; i<SYM_PER_FRA/SYM_PER_SWD; i++) //192/8=24
fill_syncword(full_packet, &pkt_sym_cnt, EOT_MRKR);

1
tinier-aes 160000

@ -0,0 +1 @@
Subproject commit f602803fde808f8b22a1c724857a3928c91169d3