esp32-ogn-tracker/main/igc-key.h

174 wiersze
8.2 KiB
C++

#ifndef __IGC_KEY_H__
#define __IGC_KEY_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"
#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 "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); }
void Clone(const SHA256 &Src) { mbedtls_sha256_clone(&Context, &Src.Context); }
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_SECP256K1
#if !defined(ECPARAMS)
#define ECPARAMS mbedtls_ecp_curve_list()->grp_id
#endif
class IGC_Key
{ public:
mbedtls_ecdsa_context SignCtx; // this seems to be the key-pair as it is defined: typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
mbedtls_ctr_drbg_context CtrDrbgCtx; // RNG parameter, used to produce the key but as well to produce signature
mbedtls_pk_context Key;
mbedtls_x509write_csr Req;
mbedtls_entropy_context Entropy;
static const uint8_t PrivBinSize = 36; // 72; // [bytes] max. size for the private key in binary form
public:
// IGC_Key() { Init(); }
int Init(void) // initialize on startup
{ const char *Pers = "ecdsa";
mbedtls_x509write_csr_init(&Req);
mbedtls_pk_init(&Key);
mbedtls_ecdsa_init(&SignCtx);
mbedtls_ctr_drbg_init(&CtrDrbgCtx);
mbedtls_entropy_init(&Entropy);
int Ret = mbedtls_ctr_drbg_seed( &CtrDrbgCtx, mbedtls_entropy_func, &Entropy,
(const unsigned char *)Pers, strlen(Pers) );
return Ret; } // return zero on success
int Generate(void) // produce a new pair of keys: private and public key
{ // key-pair, curve, RNG function, RNG parameter
int Ret = mbedtls_ecdsa_genkey(&SignCtx, ECPARAMS, mbedtls_ctr_drbg_random, &CtrDrbgCtx); // produce key-pair
if(Ret!=0) return Ret;
Ret = mbedtls_pk_setup(&Key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
if(Ret!=0) return Ret;
Key.pk_ctx = &SignCtx; // ?
return Ret; } // return zero on success
int Write(uint8_t *Data, int MaxLen=240) // write both private and public keys to a binary record
{ if(MaxLen<=PrivBinSize) return 0;
if(Priv_WriteBin(Data, PrivBinSize)!=0) return 0;
int Len=Pub_WriteBin(Data+PrivBinSize, MaxLen-PrivBinSize); if(Len==0) return 0;
return Len+PrivBinSize; } // return the number of bytes
int Read(const uint8_t *Data, int Len)
{ if(Len<=PrivBinSize) return 0;
if(Priv_ReadBin(Data, PrivBinSize)!=0) return 0;
if(Pub_ReadBin(Data+PrivBinSize, Len-PrivBinSize)!=0) return 0;
// int Ret = mbedtls_pk_setup(&Key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
Key.pk_ctx = &SignCtx; // ?
return Len; } // return number of bytes read
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;
return Len; } // return number of bytes written
int Pub_ReadBin(const uint8_t *Data, int Len)
{ return mbedtls_ecp_point_read_binary(&SignCtx.grp, &SignCtx.Q, Data, Len); } // return zero for success
int Priv_WriteBin(uint8_t *Data, int Len=PrivBinSize) // write the private key in a binary form
{ return mbedtls_mpi_write_binary(&SignCtx.d, Data, Len); } // return zero if success (always fills the whole buffer adding leading zeros)
int Priv_ReadBin(const uint8_t *Data, int Len=PrivBinSize) // read the private key in the binary form
{ return mbedtls_mpi_read_binary(&SignCtx.d, Data, Len); } // return zero for success
int Pub_Write(uint8_t *Out, int MaxLen) // write the public key in an ASCII form
{ return mbedtls_pk_write_pubkey_pem(&Key, Out, MaxLen); } // return zero if success
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__