From e85d1d16a0543e06211527f4787c441e9b77648b Mon Sep 17 00:00:00 2001 From: Pawel Jalocha Date: Fri, 11 Feb 2022 14:38:06 +0000 Subject: [PATCH] Key pair for IGC log signing --- main/ctrl.cpp | 9 ++++-- main/igc-key.h | 81 +++++++++++++++++++++++++++++++++++++++++++++++--- main/sdlog.cpp | 42 +++++++++++--------------- 3 files changed, 101 insertions(+), 31 deletions(-) diff --git a/main/ctrl.cpp b/main/ctrl.cpp index 3b62087..c50237b 100644 --- a/main/ctrl.cpp +++ b/main/ctrl.cpp @@ -15,6 +15,7 @@ #include "ctrl.h" #include "proc.h" #include "log.h" +#include "sdlog.h" #include "gps.h" #include "ubx.h" @@ -166,8 +167,10 @@ static void ProcessCtrlV(void) } static void ProcessCtrlK(void) // print public key to the console -{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY); - +{ uint8_t Out[512]; + xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + if(IGC_SignKey.Pub_Write(Out, 512)==0) + Format_String(CONS_UART_Write, (const char *)Out); xSemaphoreGive(CONS_Mutex); } static void ProcessCtrlF(void) // list log files to the console @@ -396,7 +399,7 @@ static void ProcessInput(void) if(Byte==0x06) ProcessCtrlF(); // if Ctrl-F received: list files if(Byte==0x0B) ProcessCtrlK(); // if Ctrl-K received: print public key if(Byte==0x0C) ProcessCtrlL(); // if Ctrl-L received: list log files - if(Byte==0x16) ProcessCtrlV(); // if Ctrl-L received: suspend (verbose) printout + if(Byte==0x16) ProcessCtrlV(); // if Ctrl-V received: suspend (verbose) printout if(Byte==0x18) { #ifdef WITH_SPIFFS diff --git a/main/igc-key.h b/main/igc-key.h index 1d87978..0fc9895 100644 --- a/main/igc-key.h +++ b/main/igc-key.h @@ -1,7 +1,10 @@ #ifndef __IGC_KEY_H__ #define __IGC_KEY_H__ -#include "mbedtls/md5.h" +// #define MBEDTLS_ECDSA_DETERMINISTIC + +// #include "mbedtls/md5.h" +#include "mbedtls/sha256.h" #include "mbedtls/rsa.h" #include "mbedtls/platform.h" #include "mbedtls/x509_csr.h" @@ -11,9 +14,36 @@ #include "mbedtls/sha256.h" #include "mbedtls/ecp.h" #include "mbedtls/pk.h" +#include "mbedtls/version.h" + +class SHA256 +{ public: + mbedtls_sha256_context Context; + + public: + void Init(void) { mbedtls_sha256_init(&Context); } + void Free(void) { mbedtls_sha256_free(&Context); } + int Start(void) { return mbedtls_sha256_starts_ret(&Context, 0); } + int Update(const uint8_t *Input, size_t Len) { return mbedtls_sha256_update_ret(&Context, Input, Len); } + int Finish(uint8_t CheckSum[32]) { return mbedtls_sha256_finish_ret(&Context, CheckSum); } + +} ; + +class SHA512 +{ public: + mbedtls_sha512_context Context; + + public: + void Init(void) { mbedtls_sha512_init(&Context); } + void Free(void) { mbedtls_sha512_free(&Context); } + int Start(void) { return mbedtls_sha512_starts_ret(&Context, 0); } + int Update(const uint8_t *Input, size_t Len) { return mbedtls_sha512_update_ret(&Context, Input, Len); } + int Finish(uint8_t CheckSum[64]) { return mbedtls_sha512_finish_ret(&Context, CheckSum); } + +} ; // Uncomment to force use of a specific curve -// #define ECPARAMS MBEDTLS_ECP_DP_SECP192R1 +#define ECPARAMS MBEDTLS_ECP_DP_SECP256K1 #if !defined(ECPARAMS) #define ECPARAMS mbedtls_ecp_curve_list()->grp_id @@ -29,7 +59,7 @@ class IGC_Key mbedtls_x509write_csr Req; mbedtls_entropy_context Entropy; - static const uint8_t PrivBinSize = 72; // [bytes] max. size for the private key in binary form + static const uint8_t PrivBinSize = 36; // 72; // [bytes] max. size for the private key in binary form public: // IGC_Key() { Init(); } @@ -68,12 +98,22 @@ class IGC_Key Key.pk_ctx = &SignCtx; // ? return Len; } // return number of bytes read - int SignMD5(uint8_t *Sign, const uint8_t *Hash, int HashLen) // sign an MD5 Hash + int Sign_MD5_SHA256(uint8_t *Sign, const uint8_t *Hash, int HashLen) // sign an MD5/SHA256 Hash { size_t SignLen=0; int Ret=mbedtls_ecdsa_write_signature(&SignCtx, MBEDTLS_MD_SHA256, Hash, HashLen, Sign, &SignLen, mbedtls_ctr_drbg_random, &CtrDrbgCtx); if(Ret!=0) return 0; // return zero if failure return SignLen; } // return the size of the signature + int Sign_MD5_SHA512(uint8_t *Sign, const uint8_t *Hash, int HashLen) // sign an MD5/SHA512 Hash + { size_t SignLen=0; + int Ret=mbedtls_ecdsa_write_signature(&SignCtx, MBEDTLS_MD_SHA512, Hash, HashLen, Sign, &SignLen, mbedtls_ctr_drbg_random, &CtrDrbgCtx); + if(Ret!=0) return 0; // return zero if failure + return SignLen; } // return the size of the signature + + int Verify_SHA256(unsigned char *Sign, int sig_len, const uint8_t *Hash, int HashLen) // Verify a signature + { int Ret=mbedtls_ecdsa_read_signature (&SignCtx, Hash, HashLen, Sign, sig_len); + return Ret; } // return the size of the signature + int Pub_WriteBin(uint8_t *Data, int MaxLen) // write the public key in a binary form { size_t Len=0; if(mbedtls_ecp_point_write_binary(&SignCtx.grp, &SignCtx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &Len, Data, MaxLen)!=0) return 0; @@ -94,6 +134,39 @@ class IGC_Key int Priv_Write(uint8_t *Out, int MaxLen) // write the private key in an ASCII form { return mbedtls_pk_write_key_pem(&Key, Out, MaxLen); } // return zero if success + int Pub_Write_DER(uint8_t *Out, int MaxLen) // write the public key in an ASCII form + { return mbedtls_pk_write_pubkey_der(&Key, Out, MaxLen); } // return zero if success + + int Priv_Write_DER(uint8_t *Out, int MaxLen) // write the private key in an ASCII form + { return mbedtls_pk_write_key_der(&Key, Out, MaxLen); } // return zero if success + +#ifdef WITH_ESP32 + esp_err_t WriteToNVS(const char *Name="IGCKEY", const char *NameSpace="TRACKER") + { uint8_t Buff[256]; + nvs_handle Handle; + esp_err_t Err = nvs_open(NameSpace, NVS_READWRITE, &Handle); + if(Err!=ESP_OK) return Err; + int BuffLen = Write(Buff, 256); + Err = nvs_set_blob(Handle, Name, Buff, BuffLen); + if(Err==ESP_OK) Err = nvs_commit(Handle); + nvs_close(Handle); + return Err; } + + esp_err_t ReadFromNVS(const char *Name="IGCKEY", const char *NameSpace="TRACKER") + { uint8_t Buff[256]; + nvs_handle Handle; + esp_err_t Err = nvs_open(NameSpace, NVS_READWRITE, &Handle); + if(Err!=ESP_OK) return Err; + size_t Size=0; + Err = nvs_get_blob(Handle, Name, 0, &Size); // get the Size of the blob in the Flash + if( (Err==ESP_OK) && (Size<=256) ) + Err = nvs_get_blob(Handle, Name, Buff, &Size); // read the Blob from the Flash + nvs_close(Handle); + if(Err!=ESP_OK) return Err; + if(Read(Buff, Size)==Size) return ESP_OK; + return ESP_ERR_NOT_FOUND; } +#endif // WITH_ESP32 + } ; #endif // __IGC_KEY_H__ diff --git a/main/sdlog.cpp b/main/sdlog.cpp index 7e9886e..a6e88d1 100644 --- a/main/sdlog.cpp +++ b/main/sdlog.cpp @@ -5,24 +5,13 @@ #include #include -#include "mbedtls/md5.h" -// #include "mbedtls/rsa.h" -// #include "mbedtls/platform.h" -// #include "mbedtls/x509_csr.h" -// #include "mbedtls/entropy.h" -// #include "mbedtls/ctr_drbg.h" -// #include "mbedtls/ecdsa.h" -// #include "mbedtls/sha256.h" -// #include "mbedtls/ecp.h" -// #include "mbedtls/pk.h" - #include "hal.h" #include "gps.h" #include "sdlog.h" #include "timesync.h" #include "fifo.h" -#include "igc-key.h" +#include "igc-key.h" // IGC key generate/read/write/sign with // ============================================================================================ @@ -106,8 +95,8 @@ static FILE *IGC_File=0; // static uint32_t IGC_SaveTime=0; uint16_t IGC_FlightNum=0; // flight counter -static mbedtls_md5_context IGC_MD5; // -static uint8_t IGC_Digest[16]; // +static SHA256 IGC_SHA256; // +static uint8_t IGC_Digest[32]; // static void IGC_TimeStamp(void) { struct stat FileStat; @@ -170,7 +159,7 @@ static void IGC_Reopen(void) static int IGC_LogLine(const char *Line, int Len) { int Written = fwrite(Line, 1, Len, IGC_File); - mbedtls_md5_update_ret(&IGC_MD5, (uint8_t *)Line, Written); + IGC_SHA256.Update((uint8_t *)Line, Written); return Written; } static int IGC_LogLine(const char *Line) @@ -282,12 +271,12 @@ static void IGC_Check(void) // check if if(IGC_File) // if IGC file already open { IGC_Log(GPS_Pos[PosIdx]); // log position if(!inFlight) // if no longer in flight - { mbedtls_md5_finish_ret(&IGC_MD5, IGC_Digest); - Line[0]='G'; // produce G-record with MD5 - for(int Idx=0; Idx<16; Idx++) // 16 MD5 bytes + { IGC_SHA256.Finish(IGC_Digest); + Line[0]='G'; // produce G-record with SH256 + for(int Idx=0; Idx<32; Idx++) // 32 SHA256 bytes Format_Hex(Line+1+2*Idx, IGC_Digest[Idx]); // printed as hex - Line[33]='\n'; Line[34]=0; // end-of-line, end-of-string - IGC_LogLine(Line, 34); // write to IGC + Line[65]='\n'; Line[66]=0; // end-of-line, end-of-string + IGC_LogLine(Line, 66); // write to IGC IGC_Close(); IGC_TimeStamp(); } // then close the IGC file else { uint32_t Time=TimeSync_Time(); @@ -300,7 +289,7 @@ static void IGC_Check(void) // check if { for(int Try=0; Try<8; Try++) { int Err=IGC_Open(); if(Err!=(-2)) break; } // try to open a new IGC file but don't overwrite the old ones if(IGC_File) // if open succesfully - { mbedtls_md5_starts_ret(&IGC_MD5); // start the MD5 calculation + { IGC_SHA256.Start(); // start the SHA256 calculation IGC_Header(GPS_Pos[PosIdx]); // then write header IGC_ID(); IGC_Log(GPS_Pos[PosIdx]); } // log first B-record @@ -312,10 +301,10 @@ static void IGC_Check(void) // check if // ============================================================================================ -#ifdef WITH_SDLOG - IGC_Key IGC_SignKey; +#ifdef WITH_SDLOG + /* // Uncomment to force use of a specific curve #define ECPARAMS MBEDTLS_ECP_DP_SECP192R1 @@ -371,8 +360,13 @@ extern "C" IGC_SignKey.Init(); IGC_SignKey.Generate(); + if(IGC_SignKey.ReadFromNVS()!=ESP_OK) IGC_SignKey.WriteToNVS(); + xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + if(IGC_SignKey.Pub_Write((uint8_t *)Line, 512)==0) + Format_String(CONS_UART_Write, Line); + xSemaphoreGive(CONS_Mutex); - mbedtls_md5_init(&IGC_MD5); + IGC_SHA256.Init(); Log_FIFO.Clear();