add AES key callback functions to decoder
parent
ad6425ca3a
commit
d88782d9f0
|
@ -18,6 +18,10 @@ parameters:
|
|||
dtype: bool
|
||||
default: 'False'
|
||||
options: ['True', 'False']
|
||||
- id: key
|
||||
label: AES Key
|
||||
dtype: string
|
||||
default: ''
|
||||
- id: signed_str
|
||||
label: SignedStr
|
||||
dtype: bool
|
||||
|
@ -28,13 +32,17 @@ parameters:
|
|||
dtype: float
|
||||
default: 2.0
|
||||
|
||||
asserts:
|
||||
- ${ len(key) <= 32 }
|
||||
|
||||
templates:
|
||||
imports: from gnuradio import m17
|
||||
make: m17.m17_decoder(${debug_data},${debug_ctrl},${threshold},${callsign},${signed_str})
|
||||
make: m17.m17_decoder(${debug_data},${debug_ctrl},${threshold},${callsign},${signed_str},${key})
|
||||
callbacks:
|
||||
- set_debug_data(${debug_data})
|
||||
- set_debug_ctrl(${debug_ctrl})
|
||||
- set_threshold(${threshold})
|
||||
- set_key(${key})
|
||||
- set_callsign(${callsign})
|
||||
- set_signed(${signed_str})
|
||||
|
||||
|
|
|
@ -32,12 +32,17 @@ public:
|
|||
* class. m17::m17_decoder::make is the public interface for
|
||||
* creating new instances.
|
||||
*/
|
||||
static sptr make(bool debug_data,bool debug_ctrl,float threshold,bool callsign, bool signed_str);
|
||||
static sptr make(bool debug_data,bool debug_ctrl,float threshold,bool callsign, bool signed_str, std::string key);
|
||||
virtual void set_debug_data(bool debug)=0;
|
||||
virtual void set_debug_ctrl(bool debug)=0;
|
||||
virtual void set_callsign(bool callsign)=0;
|
||||
virtual void set_threshold(float threshold)=0;
|
||||
virtual void set_signed(bool signed_str)=0;
|
||||
virtual void set_key(std::string key)=0;
|
||||
virtual void parse_raw_key_string(uint8_t* dest, const char* inp)=0;
|
||||
virtual void scrambler_sequence_generator()=0;
|
||||
virtual uint32_t scrambler_seed_calculation(int8_t subtype, uint32_t key, int fn)=0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace m17
|
||||
|
|
|
@ -40,17 +40,17 @@ namespace gr {
|
|||
namespace m17 {
|
||||
|
||||
m17_decoder::sptr
|
||||
m17_decoder::make(bool debug_data,bool debug_ctrl,float threshold,bool callsign,bool signed_str)
|
||||
m17_decoder::make(bool debug_data,bool debug_ctrl,float threshold,bool callsign,bool signed_str, std::string key)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new m17_decoder_impl(debug_data,debug_ctrl,threshold,callsign,signed_str));
|
||||
(new m17_decoder_impl(debug_data,debug_ctrl,threshold,callsign,signed_str,key));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
m17_decoder_impl::m17_decoder_impl(bool debug_data,bool debug_ctrl,float threshold,bool callsign,bool signed_str)
|
||||
m17_decoder_impl::m17_decoder_impl(bool debug_data,bool debug_ctrl,float threshold,bool callsign,bool signed_str,std::string key)
|
||||
: gr::block("m17_decoder",
|
||||
gr::io_signature::make(1, 1, sizeof(float)),
|
||||
gr::io_signature::make(1, 1, sizeof(char))),
|
||||
|
@ -60,6 +60,7 @@ namespace gr {
|
|||
set_threshold(threshold);
|
||||
set_callsign(callsign);
|
||||
set_signed(signed_str);
|
||||
set_key(key);
|
||||
_expected_next_fn=0;
|
||||
}
|
||||
|
||||
|
@ -95,12 +96,187 @@ namespace gr {
|
|||
if (_callsign==true) printf("Signed\n"); else printf("Unsigned\n");
|
||||
}
|
||||
|
||||
void m17_decoder_impl::set_key(std::string arg) // *UTF-8* encoded byte array
|
||||
{int length;
|
||||
printf("new key: ");
|
||||
length=arg.size();
|
||||
int i=0,j=0;
|
||||
while ((j<32) && (i<length))
|
||||
{if ((unsigned int)arg.data()[i]<0xc2) // https://www.utf8-chartable.de/
|
||||
{_key[j]=arg.data()[i];i++;j++;}
|
||||
else
|
||||
{_key[j]=(arg.data()[i]-0xc2)*0x40+arg.data()[i+1];i+=2;j++;}
|
||||
}
|
||||
length=j; // index from 0 to length-1
|
||||
printf("%d bytes: ",length);
|
||||
for (i=0;i<length;i++) printf("%02X ",_key[i]);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void
|
||||
m17_decoder_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
|
||||
{
|
||||
ninput_items_required[0] = 0; // noutput_items;
|
||||
}
|
||||
|
||||
//this is generating a correct seed value based on the fn value,
|
||||
//ideally, we would only want to run this under poor signal, frame skips, etc
|
||||
//Note: Running this every frame will lag if high fn values (observed with test file)
|
||||
uint32_t m17_decoder_impl::scrambler_seed_calculation(int8_t subtype, uint32_t key, int fn)
|
||||
{
|
||||
int i;
|
||||
uint32_t lfsr, bit;
|
||||
|
||||
lfsr = key; bit = 0;
|
||||
for (i = 0; i < 128*fn; i++)
|
||||
{
|
||||
//get feedback bit with specified taps, depending on the subtype
|
||||
if (subtype == 0)
|
||||
bit = (lfsr >> 7) ^ (lfsr >> 5) ^ (lfsr >> 4) ^ (lfsr >> 3);
|
||||
else if (subtype == 1)
|
||||
bit = (lfsr >> 15) ^ (lfsr >> 14) ^ (lfsr >> 12) ^ (lfsr >> 3);
|
||||
else if (subtype == 2)
|
||||
bit = (lfsr >> 23) ^ (lfsr >> 22) ^ (lfsr >> 21) ^ (lfsr >> 16);
|
||||
else bit = 0; //should never get here, but just in case
|
||||
|
||||
bit &= 1; //truncate bit to 1 bit
|
||||
lfsr = (lfsr << 1) | bit; //shift LFSR left once and OR bit onto LFSR's LSB
|
||||
lfsr &= 0xFFFFFF; //truncate lfsr to 24-bit
|
||||
|
||||
}
|
||||
|
||||
//truncate seed so subtype will continue to set properly on subsequent passes
|
||||
if (scrambler_subtype == 0) scrambler_seed &= 0xFF;
|
||||
else if (scrambler_subtype == 1) scrambler_seed &= 0xFFFF;
|
||||
else if (scrambler_subtype == 2) scrambler_seed &= 0xFFFFFF;
|
||||
|
||||
//debug
|
||||
//fprintf (stderr, "\nScrambler Key: 0x%06X; Seed: 0x%06X; Subtype: %02d; FN: %05d; ", key, lfsr, subtype, fn);
|
||||
|
||||
return lfsr;
|
||||
}
|
||||
|
||||
//scrambler pn sequence generation
|
||||
void m17_decoder_impl::scrambler_sequence_generator()
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t lfsr, bit;
|
||||
lfsr = scrambler_seed;
|
||||
|
||||
//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
|
||||
if (scrambler_subtype == -1)
|
||||
{
|
||||
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 > 0xFFFF && lfsr <= 0xFFFFFF) scrambler_subtype = 2; //24-bit key
|
||||
else scrambler_subtype = 0; // 8-bit key (default)
|
||||
}
|
||||
|
||||
//TODO: Set Frame Type based on scrambler_subtype value
|
||||
if (_debug_ctrl==true)
|
||||
{
|
||||
fprintf(stderr, "\nScrambler Key: 0x%06X; Seed: 0x%06X; Subtype: %02d;", scrambler_seed, lfsr, scrambler_subtype);
|
||||
fprintf(stderr, "\n pN: ");
|
||||
}
|
||||
|
||||
//run pN sequence with taps specified
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
//get feedback bit with specified taps, depending on the scrambler_subtype
|
||||
if (scrambler_subtype == 0)
|
||||
bit = (lfsr >> 7) ^ (lfsr >> 5) ^ (lfsr >> 4) ^ (lfsr >> 3);
|
||||
else if (scrambler_subtype == 1)
|
||||
bit = (lfsr >> 15) ^ (lfsr >> 14) ^ (lfsr >> 12) ^ (lfsr >> 3);
|
||||
else if (scrambler_subtype == 2)
|
||||
bit = (lfsr >> 23) ^ (lfsr >> 22) ^ (lfsr >> 21) ^ (lfsr >> 16);
|
||||
else bit = 0; //should never get here, but just in case
|
||||
|
||||
bit &= 1; //truncate bit to 1 bit (required since I didn't do it above)
|
||||
lfsr = (lfsr << 1) | bit; //shift LFSR left once and OR bit onto LFSR's LSB
|
||||
lfsr &= 0xFFFFFF; //truncate lfsr to 24-bit (really doesn't matter)
|
||||
scrambler_pn[i] = bit;
|
||||
|
||||
}
|
||||
|
||||
//pack bit array into byte array for easy data XOR
|
||||
pack_bit_array_into_byte_array(scrambler_pn, scr_bytes, 16);
|
||||
|
||||
//save scrambler seed for next round
|
||||
scrambler_seed = lfsr;
|
||||
|
||||
//truncate seed so subtype will continue to set properly on subsequent passes
|
||||
if (scrambler_subtype == 0) scrambler_seed &= 0xFF;
|
||||
else if (scrambler_subtype == 1) scrambler_seed &= 0xFFFF;
|
||||
else if (scrambler_subtype == 2) scrambler_seed &= 0xFFFFFF;
|
||||
|
||||
if (_debug_ctrl==true)
|
||||
{
|
||||
//debug packed bytes
|
||||
for (i = 0; i < 16; i++)
|
||||
fprintf (stderr, " %02X", scr_bytes[i]);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//convert a user string (as hex octets) into a uint8_t array for key
|
||||
void m17_decoder_impl::parse_raw_key_string(uint8_t* dest, const char* inp)
|
||||
{
|
||||
uint16_t len = strlen(inp);
|
||||
|
||||
if(len==0) return; //return silently and pretend nothing happened
|
||||
|
||||
memset(dest, 0, len/2); //one character represents half of a byte
|
||||
|
||||
if(!(len%2)) //length even?
|
||||
{
|
||||
for(uint8_t i=0; i<len; i+=2)
|
||||
{
|
||||
if(inp[i]>='a')
|
||||
dest[i/2]|=(inp[i]-'a'+10)*0x10;
|
||||
else if(inp[i]>='A')
|
||||
dest[i/2]|=(inp[i]-'A'+10)*0x10;
|
||||
else if(inp[i]>='0')
|
||||
dest[i/2]|=(inp[i]-'0')*0x10;
|
||||
|
||||
if(inp[i+1]>='a')
|
||||
dest[i/2]|=inp[i+1]-'a'+10;
|
||||
else if(inp[i+1]>='A')
|
||||
dest[i/2]|=inp[i+1]-'A'+10;
|
||||
else if(inp[i+1]>='0')
|
||||
dest[i/2]|=inp[i+1]-'0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(inp[0]>='a')
|
||||
dest[0]|=inp[0]-'a'+10;
|
||||
else if(inp[0]>='A')
|
||||
dest[0]|=inp[0]-'A'+10;
|
||||
else if(inp[0]>='0')
|
||||
dest[0]|=inp[0]-'0';
|
||||
|
||||
for(uint8_t i=1; i<len-1; i+=2)
|
||||
{
|
||||
if(inp[i]>='a')
|
||||
dest[i/2+1]|=(inp[i]-'a'+10)*0x10;
|
||||
else if(inp[i]>='A')
|
||||
dest[i/2+1]|=(inp[i]-'A'+10)*0x10;
|
||||
else if(inp[i]>='0')
|
||||
dest[i/2+1]|=(inp[i]-'0')*0x10;
|
||||
|
||||
if(inp[i+1]>='a')
|
||||
dest[i/2+1]|=inp[i+1]-'a'+10;
|
||||
else if(inp[i+1]>='A')
|
||||
dest[i/2+1]|=inp[i+1]-'A'+10;
|
||||
else if(inp[i+1]>='0')
|
||||
dest[i/2+1]|=inp[i+1]-'0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
m17_decoder_impl::general_work (int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
|
|
|
@ -11,6 +11,17 @@
|
|||
#include <gnuradio/m17/m17_decoder.h>
|
||||
#include "m17.h"
|
||||
|
||||
#define AES
|
||||
#define ECC
|
||||
|
||||
#ifdef AES
|
||||
#include "aes.h"
|
||||
#endif
|
||||
|
||||
#ifdef ECC
|
||||
#include "uECC.h"
|
||||
#endif
|
||||
|
||||
namespace gr {
|
||||
namespace m17 {
|
||||
|
||||
|
@ -22,6 +33,7 @@ private:
|
|||
float _threshold=0.9;
|
||||
bool _callsign=false;
|
||||
bool _signed_str=false;
|
||||
uint8_t _key[32];
|
||||
|
||||
float last[8] = {0}; //look-back buffer for finding syncwords
|
||||
float pld[SYM_PER_PLD]; //raw frame symbols
|
||||
|
@ -44,15 +56,27 @@ private:
|
|||
uint8_t pushed; //counter for pushed symbols
|
||||
|
||||
uint8_t d_dst[12], d_src[12]; //decoded strings
|
||||
#ifdef ECC
|
||||
//Scrambler
|
||||
uint8_t scr_bytes[16];
|
||||
uint8_t scrambler_pn[128];
|
||||
uint32_t scrambler_seed=0;
|
||||
int8_t scrambler_subtype = -1;
|
||||
#endif
|
||||
|
||||
public:
|
||||
m17_decoder_impl(bool debug_data,bool debug_ctrl,float threshold,bool callsign, bool signed_str);
|
||||
m17_decoder_impl(bool debug_data,bool debug_ctrl,float threshold,bool callsign, bool signed_str, std::string key);
|
||||
~m17_decoder_impl();
|
||||
void set_debug_data(bool debug);
|
||||
void set_key(std::string arg);
|
||||
|
||||
void set_debug_ctrl(bool debug);
|
||||
void set_callsign(bool callsign);
|
||||
void set_threshold(float threshold);
|
||||
void set_signed(bool signed_str);
|
||||
void parse_raw_key_string(uint8_t* dest, const char* inp);
|
||||
void scrambler_sequence_generator();
|
||||
uint32_t scrambler_seed_calculation(int8_t subtype, uint32_t key, int fn);
|
||||
|
||||
// Where all the action really happens
|
||||
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
|
||||
|
|
Loading…
Reference in New Issue