2022-01-24 02:08:50 +00:00
|
|
|
#ifndef __IGC_KEY_H__
|
|
|
|
#define __IGC_KEY_H__
|
|
|
|
|
2022-02-11 14:38:06 +00:00
|
|
|
// #define MBEDTLS_ECDSA_DETERMINISTIC
|
|
|
|
|
|
|
|
// #include "mbedtls/md5.h"
|
|
|
|
#include "mbedtls/sha256.h"
|
2022-01-24 02:08:50 +00:00
|
|
|
#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"
|
2022-02-11 14:38:06 +00:00
|
|
|
#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); }
|
|
|
|
|
|
|
|
} ;
|
2022-01-24 02:08:50 +00:00
|
|
|
|
|
|
|
// Uncomment to force use of a specific curve
|
2022-02-11 14:38:06 +00:00
|
|
|
#define ECPARAMS MBEDTLS_ECP_DP_SECP256K1
|
2022-01-24 02:08:50 +00:00
|
|
|
|
|
|
|
#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;
|
|
|
|
|
2022-02-11 14:38:06 +00:00
|
|
|
static const uint8_t PrivBinSize = 36; // 72; // [bytes] max. size for the private key in binary form
|
2022-01-24 02:08:50 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-02-11 14:38:06 +00:00
|
|
|
int Sign_MD5_SHA256(uint8_t *Sign, const uint8_t *Hash, int HashLen) // sign an MD5/SHA256 Hash
|
2022-01-24 02:08:50 +00:00
|
|
|
{ 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
|
|
|
|
|
2022-02-11 14:38:06 +00:00
|
|
|
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
|
|
|
|
|
2022-01-24 02:08:50 +00:00
|
|
|
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
|
|
|
|
|
2022-02-11 14:38:06 +00:00
|
|
|
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
|
|
|
|
|
2022-01-24 02:08:50 +00:00
|
|
|
} ;
|
|
|
|
|
|
|
|
#endif // __IGC_KEY_H__
|