From ad6425ca3a37d36e0be053b6246c95cf06c32d36 Mon Sep 17 00:00:00 2001 From: Jean-Michel Friedt Date: Sun, 22 Dec 2024 16:31:47 +0100 Subject: [PATCH] private key management --- grc/m17_m17_coder.block.yml | 8 +- include/gnuradio/m17/m17_coder.h | 3 +- lib/m17_coder_impl.cc | 471 ++++++++++++++++--------------- lib/m17_coder_impl.h | 5 +- 4 files changed, 256 insertions(+), 231 deletions(-) diff --git a/grc/m17_m17_coder.block.yml b/grc/m17_m17_coder.block.yml index 4527ae1..0653289 100644 --- a/grc/m17_m17_coder.block.yml +++ b/grc/m17_m17_coder.block.yml @@ -47,6 +47,10 @@ parameters: label: AES Key dtype: string default: '' +- id: priv_key + label: Private Key + dtype: string + default: '' - id: signed_str label: SignedStr dtype: bool @@ -61,11 +65,12 @@ parameters: asserts: - ${ can <= 15 } - ${ len(key) <= 32 } + - ${ len(priv_key) <= 32 } - ${ len(dst_id) < 10 } - ${ len(src_id) < 10 } templates: imports: from gnuradio import m17 - make: m17.m17_coder(${src_id},${dst_id},${mode},${type},${encr_type},${encr_subtype},${can},${meta},${key},${debug},${signed_str}) + make: m17.m17_coder(${src_id},${dst_id},${mode},${type},${encr_type},${encr_subtype},${can},${meta},${key},${priv_key},${debug},${signed_str}) callbacks: - set_meta(${meta}) - set_src_id(${src_id}) @@ -76,6 +81,7 @@ templates: - set_encr_subtype(${encr_subtype}) - set_can(${can}) - set_key(${key}) + - set_priv_key(${priv_key}) - set_debug(${debug}) - set_signed(${signed_str}) diff --git a/include/gnuradio/m17/m17_coder.h b/include/gnuradio/m17/m17_coder.h index d4e66e6..b8b81e6 100644 --- a/include/gnuradio/m17/m17_coder.h +++ b/include/gnuradio/m17/m17_coder.h @@ -39,8 +39,9 @@ public: * class. m17::m17_coder::make is the public interface for * creating new instances. */ - static sptr make(std::string src_id,std::string dst_id,int mode,int data,encr_t encr_type,int encr_subtype,int can,std::string meta, std::string key, bool debug, bool signed_str); + static sptr make(std::string src_id,std::string dst_id,int mode,int data,encr_t encr_type,int encr_subtype,int can,std::string meta, std::string key,std::string priv_key, bool debug, bool signed_str); virtual void set_key(std::string meta)=0; + virtual void set_priv_key(std::string meta)=0; virtual void set_meta(std::string meta)=0; virtual void set_src_id(std::string src_id)=0; virtual void set_dst_id(std::string dst_id)=0; diff --git a/lib/m17_coder_impl.cc b/lib/m17_coder_impl.cc index 48abe31..778c42f 100644 --- a/lib/m17_coder_impl.cc +++ b/lib/m17_coder_impl.cc @@ -48,16 +48,16 @@ namespace gr { namespace m17 { m17_coder::sptr - m17_coder::make(std::string src_id,std::string dst_id,int mode,int data,encr_t encr_type,int encr_subtype,int can,std::string meta, std::string key, bool debug, bool signed_str) + m17_coder::make(std::string src_id,std::string dst_id,int mode,int data,encr_t encr_type,int encr_subtype,int can,std::string meta, std::string key, std::string priv_key,bool debug, bool signed_str) { return gnuradio::get_initial_sptr - (new m17_coder_impl(src_id,dst_id,mode,data,encr_type,encr_subtype,can,meta,key,debug,signed_str)); + (new m17_coder_impl(src_id,dst_id,mode,data,encr_type,encr_subtype,can,meta,key,priv_key,debug,signed_str)); } /* * The private constructor */ - m17_coder_impl::m17_coder_impl(std::string src_id,std::string dst_id,int mode,int data,encr_t encr_type,int encr_subtype,int can,std::string meta, std::string key, bool debug,bool signed_str) + m17_coder_impl::m17_coder_impl(std::string src_id,std::string dst_id,int mode,int data,encr_t encr_type,int encr_subtype,int can,std::string meta, std::string key,std::string priv_key, bool debug,bool signed_str) : gr::block("m17_coder", gr::io_signature::make(1, 1, sizeof(char)), gr::io_signature::make(1, 1, sizeof(float))) @@ -121,6 +121,25 @@ namespace gr { _lsf.crc[1]=ccrc&0xFF; } + void m17_coder_impl::set_priv_key(std::string arg) // *UTF-8* encoded byte array + {int length; + printf("new private key: "); + length=arg.size(); + _priv_key_loaded=true; + int i=0,j=0; + while ((j<32) && (i> 8) & 0x7F; - _iv[15] = (_fn >> 0) & 0xFF; - - //re-calculate LSF CRC with IV insertion - uint16_t ccrc=LSF_CRC(&_lsf); - _lsf.crc[0]=ccrc>>8; - _lsf.crc[1]=ccrc&0xFF; - } - - while(_finished==false) - { - if(!_got_lsf) - { - //debug - //fprintf(stderr, "LSF\n"); - - //send LSF syncword - send_syncword(out, &countout, SYNC_LSF); - - //encode LSF data - conv_encode_LSF(enc_bits, &_lsf); - - //reorder bits - reorder_bits(rf_bits, enc_bits); - - //randomize - randomize_bits(rf_bits); - - //send LSF data - send_data(out, &countout, rf_bits); - - //check the SIGNED STREAM flag - _signed_str=(_lsf.type[0]>>3)&1; - - //set the flag - _got_lsf=1; - } - - if(_debug==true) - { - //destination set to "ALL" - memset(_next_lsf.dst, 0xFF, 6*sizeof(uint8_t)); - - //source set to "N0CALL" - _next_lsf.src[0] = 0x00; - _next_lsf.src[1] = 0x00; - _next_lsf.src[2] = 0x4B; - _next_lsf.src[3] = 0x13; - _next_lsf.src[4] = 0xD1; - _next_lsf.src[5] = 0x06; - - if(_encr_type==ENCR_AES) //AES ENC, 3200 voice - { - _next_lsf.type[0] = 0x03; - _next_lsf.type[1] = 0x95; - } - else if(_encr_type==ENCR_SCRAM) //Scrambler ENC, 3200 Voice - { - _next_lsf.type[0] = 0x00; - _next_lsf.type[1] = 0x00; - if (scrambler_subtype==0) - _next_lsf.type[1] = 0x0D; - else if (scrambler_subtype==1) - _next_lsf.type[1] = 0x2D; - else if (scrambler_subtype==2) - _next_lsf.type[1] = 0x4D; - } - else //no enc or subtype field, normal 3200 voice - { - _next_lsf.type[0] = 0x00; - _next_lsf.type[1] = 0x05; - } - - //a signature key is loaded, OR this bit - if(_priv_key_loaded) - _next_lsf.type[0] |= 0x8; - - _finished = false; - - memset(next_data, 0, sizeof(next_data)); - memcpy(data, next_data, sizeof(data)); - if(_fn == 60) - _finished = 1; - - //debug sig with random payloads (don't play the audio) - for(uint8_t i = 0; i < 16; i++) - data[i] = 0x69; //rand() & 0xFF; - - } - else - { -/* - //check if theres any more data - if(fread(&(next_lsf.dst), 6, 1, stdin)<1) finished=1; - if(fread(&(next_lsf.src), 6, 1, stdin)<1) finished=1; - if(fread(&(next_lsf.type), 2, 1, stdin)<1) finished=1; - if(fread(&(next_lsf.meta), 14, 1, stdin)<1) finished=1; -*/ - if(fread(next_data, 16, 1, stdin)<1) _finished=true; - } - - //AES if(_encr_type==ENCR_AES) - { - memcpy(&(_next_lsf.meta), _iv, 14); + { + memcpy(&(_lsf.meta), _iv, 14); _iv[14] = (_fn >> 8) & 0x7F; _iv[15] = (_fn >> 0) & 0xFF; - aes_ctr_bytewise_payload_crypt(_iv, _key, data, AES128); //hardcoded for now + + //re-calculate LSF CRC with IV insertion + uint16_t ccrc=LSF_CRC(&_lsf); + _lsf.crc[0]=ccrc>>8; + _lsf.crc[1]=ccrc&0xFF; } - - //Scrambler - else if(_encr_type==ENCR_SCRAM) + + while(_finished==false) { - scrambler_sequence_generator(); - for(uint8_t i=0; i<16; i++) - { - data[i] ^= scr_bytes[i]; + if(!_got_lsf) + {//debug + //fprintf(stderr, "LSF\n"); + + //send LSF syncword + send_syncword(out, &countout, SYNC_LSF); + + //encode LSF data + conv_encode_LSF(enc_bits, &_lsf); + + //reorder bits + reorder_bits(rf_bits, enc_bits); + + //randomize + randomize_bits(rf_bits); + + //send LSF data + send_data(out, &countout, rf_bits); + + //check the SIGNED STREAM flag + _signed_str=(_lsf.type[0]>>3)&1; + + //set the flag + _got_lsf=1; } - } - - if(_finished==false) - { - send_syncword(out, &countout, SYNC_STR); - extract_LICH(lich, _lich_cnt, &_lsf); - encode_LICH(lich_encoded, lich); - unpack_LICH(enc_bits, lich_encoded); - conv_encode_stream_frame(&enc_bits[96], data, _fn); - reorder_bits(rf_bits, enc_bits); - randomize_bits(rf_bits); - send_data(out, &countout, rf_bits); - _fn = (_fn + 1) % 0x8000; //increment FN - _lich_cnt = (_lich_cnt + 1) % 6; //continue with next LICH_CNT - - //update the stream digest if required - if(_signed_str) + + if(_debug==true) { - for(uint8_t i=0; i0 && _lich_cnt==0) - { - _lsf = _next_lsf; - - //calculate LSF CRC - uint16_t ccrc=LSF_CRC(&_lsf); - _lsf.crc[0]=ccrc>>8; - _lsf.crc[1]=ccrc&0xFF; - } - - memcpy(data, next_data, 16); - } - else //send last frame(s) - { - send_syncword(out, &countout, SYNC_STR); - extract_LICH(lich, _lich_cnt, &_lsf); - encode_LICH(lich_encoded, lich); - unpack_LICH(enc_bits, lich_encoded); - if(!_signed_str) - conv_encode_stream_frame(&enc_bits[96], data, (_fn | 0x8000)); - else - conv_encode_stream_frame(&enc_bits[96], data, _fn); - reorder_bits(rf_bits, enc_bits); - randomize_bits(rf_bits); - send_data(out, &countout, rf_bits); - _lich_cnt = (_lich_cnt + 1) % 6; //continue with next LICH_CNT - - //if we are done, and the stream is signed, so we need to transmit the signature (4 frames) - if(_signed_str) - { - //update digest - for(uint8_t i=0; i> 8) & 0x7F; + _iv[15] = (_fn >> 0) & 0xFF; + aes_ctr_bytewise_payload_crypt(_iv, _key, data, AES128); //hardcoded for now + } + + //Scrambler + else if(_encr_type==ENCR_SCRAM) + { + scrambler_sequence_generator(); + for(uint8_t i=0; i<16; i++) + { + data[i] ^= scr_bytes[i]; } } - - //send EOT frame - send_eot(out, &countout); - //fprintf(stderr, "Stream has ended. Exiting.\n"); - } + + if(_finished==false) + { + send_syncword(out, &countout, SYNC_STR); + extract_LICH(lich, _lich_cnt, &_lsf); + encode_LICH(lich_encoded, lich); + unpack_LICH(enc_bits, lich_encoded); + conv_encode_stream_frame(&enc_bits[96], data, _fn); + reorder_bits(rf_bits, enc_bits); + randomize_bits(rf_bits); + send_data(out, &countout, rf_bits); + _fn = (_fn + 1) % 0x8000; //increment FN + _lich_cnt = (_lich_cnt + 1) % 6; //continue with next LICH_CNT + + //update the stream digest if required + if(_signed_str) + { + for(uint8_t i=0; i0 && _lich_cnt==0) + { + _lsf = _next_lsf; + + //calculate LSF CRC + uint16_t ccrc=LSF_CRC(&_lsf); + _lsf.crc[0]=ccrc>>8; + _lsf.crc[1]=ccrc&0xFF; + } + + memcpy(data, next_data, 16); + } + else //send last frame(s) + { + send_syncword(out, &countout, SYNC_STR); + extract_LICH(lich, _lich_cnt, &_lsf); + encode_LICH(lich_encoded, lich); + unpack_LICH(enc_bits, lich_encoded); + if(!_signed_str) + conv_encode_stream_frame(&enc_bits[96], data, (_fn | 0x8000)); + else + conv_encode_stream_frame(&enc_bits[96], data, _fn); + reorder_bits(rf_bits, enc_bits); + randomize_bits(rf_bits); + send_data(out, &countout, rf_bits); + _lich_cnt = (_lich_cnt + 1) % 6; //continue with next LICH_CNT + + //if we are done, and the stream is signed, so we need to transmit the signature (4 frames) + if(_signed_str) + { + //update digest + for(uint8_t i=0; i