451 lines
11 KiB
C
451 lines
11 KiB
C
#include "layer1.h"
|
|
|
|
|
|
int readUDS(uint8_t* UDSdigest)
|
|
{
|
|
//Read 8 bytes from RANDFILE
|
|
//calculate sha256
|
|
//print digest
|
|
|
|
FILE *fp = NULL;
|
|
fp = fopen("RANDFILE","rb");
|
|
if (!fp)
|
|
{
|
|
perror("File open failed\n");
|
|
return -1; //FILENOTFOUND
|
|
}
|
|
//uint8_t UDSbuf[UDS_SIZE] = {0}; //{0Xe3,0xc5,0x58,0xaa,0x2f,0xd2,0x19,0x25};
|
|
uint8_t *UDSbuf = calloc(1, sizeof(uint8_t)*UDS_SIZE);
|
|
fread(UDSbuf,UDS_SIZE,1,fp);
|
|
fclose(fp);
|
|
|
|
uint8_t UDS_ID[UDS_DGST_SIZE] = {0};
|
|
|
|
//mbedtls_sha256_ret( &UDSbuf,sizeof(UDSbuf),UDS_ID,0 );
|
|
mbedtls_sha256_ret( UDSbuf,UDS_SIZE,UDSdigest,0 );
|
|
|
|
|
|
for (int i = 0; i < UDS_SIZE; i++)
|
|
printf("%hhx", UDSbuf[i]);
|
|
printf(" : fuse secret\n" );
|
|
|
|
for (int i = 0; i < UDS_DGST_SIZE; i++)
|
|
printf("%hhx", UDSdigest[i]);
|
|
printf(" : UDS ID\n" );
|
|
|
|
free(UDSbuf);
|
|
return RIOTSUCCESS;
|
|
|
|
}
|
|
|
|
|
|
int readFWID(uint8_t* FW_M)
|
|
{
|
|
|
|
// //1. Read functions.c into memory
|
|
// //2. Calcualte hash into arg
|
|
|
|
FILE *fp = NULL;
|
|
fp = fopen("layer1.c", "r");
|
|
if (!fp)
|
|
{
|
|
perror("File open failed\n");
|
|
return -1; //FILENOTFOUND
|
|
}
|
|
|
|
fseek(fp, 0L, SEEK_END);
|
|
long FW_size = ftell(fp);
|
|
rewind(fp);
|
|
|
|
//uint8_t *source = calloc(1,sizeof(uint8_t)*FW_size);
|
|
uint8_t source[FW_size];
|
|
|
|
if (fread(&source, FW_size, 1, fp) < 0)
|
|
{
|
|
perror("File read failed");
|
|
return -1;
|
|
}
|
|
fclose(fp);
|
|
mbedtls_sha256_ret(source,FW_size,FW_M,0 );
|
|
|
|
//Print block. delete later
|
|
// for(int i = 0; i < 100; i++)
|
|
// printf("%x,",source[i]);
|
|
// printf("\n");
|
|
|
|
//printf("File contnts : %s\n", source);
|
|
|
|
for(int i = 0; i < FW_DGST_SIZE; i++)
|
|
printf("%hhx",FW_M[i]);
|
|
printf(" : FW digest\n");
|
|
|
|
//free(source);
|
|
return RIOTSUCCESS;
|
|
|
|
}
|
|
|
|
int _calcCDID(uint8_t * CDID)
|
|
{
|
|
//function should not expose any internal measurements
|
|
//ONLY CDI should be accessible outside layer 0
|
|
|
|
//call readUDS, store measurement
|
|
//call readFWID, store measurement
|
|
//calculate Composite Device Identity
|
|
//return CDI
|
|
|
|
uint8_t* UDS_ID = calloc(1,sizeof(uint8_t)*UDS_DGST_SIZE);
|
|
readUDS(UDS_ID);
|
|
|
|
uint8_t* FW_ID = calloc(1,sizeof(uint8_t)*FW_DGST_SIZE);
|
|
readFWID(FW_ID);
|
|
|
|
mbedtls_sha256_context * sha_ctx;
|
|
mbedtls_sha256_init(sha_ctx);
|
|
if(mbedtls_sha256_starts_ret(sha_ctx,0) < 0 )
|
|
{
|
|
perror("SHA session failed to start\n");
|
|
mbedtls_sha256_free(sha_ctx);
|
|
return -1;
|
|
}
|
|
|
|
if(mbedtls_sha256_update_ret(sha_ctx, UDS_ID, UDS_DGST_SIZE) < 0)
|
|
{
|
|
perror("SHA session update failed\n");
|
|
mbedtls_sha256_free(sha_ctx);
|
|
return -1;
|
|
}
|
|
|
|
if(mbedtls_sha256_update_ret(sha_ctx, FW_ID, FW_DGST_SIZE) < 0)
|
|
{
|
|
perror("SHA session update failed\n");
|
|
mbedtls_sha256_free(sha_ctx);
|
|
return -1;
|
|
}
|
|
|
|
if(mbedtls_sha256_finish_ret(sha_ctx,CDID) < 0)
|
|
{
|
|
perror("SHA session update failed\n");
|
|
mbedtls_sha256_free(sha_ctx);
|
|
return -1;
|
|
}
|
|
|
|
for(int i = 0; i < CDI_DGST_SIZE; i++)
|
|
printf("%hhx",CDID[i]);
|
|
printf(" : CDID\n");
|
|
|
|
free(UDS_ID);
|
|
free(FW_ID);
|
|
return RIOTSUCCESS;
|
|
|
|
}
|
|
|
|
/*int mbedtls_hkdf( const mbedtls_md_info_t *md,
|
|
const unsigned char *salt, size_t salt_len,
|
|
const unsigned char *ikm, size_t ikm_len,
|
|
const unsigned char *info, size_t info_len,
|
|
unsigned char *okm, size_t okm_len ); */
|
|
|
|
int _calcCDIKEY(uint8_t * CDIKEY)
|
|
{
|
|
uint8_t* KEYIN = calloc(1,sizeof(uint8_t)*CDI_DGST_SIZE);
|
|
_calcCDID(KEYIN);
|
|
|
|
for(int i = 0; i < SHA256_DGST_SIZE; i++)
|
|
printf("%hhx",KEYIN[i]);
|
|
printf(" : CDID main\n");
|
|
|
|
const mbedtls_md_info_t * md_info;
|
|
if(!(md_info = mbedtls_md_info_from_type(HKDF_ALG)))
|
|
{
|
|
perror("MD alg type def failed\n");
|
|
return RIOTFAILURE;
|
|
}
|
|
|
|
uint8_t salt[32] = {0x30,0xe2,0x3e,0xcc,0x28,0xc5,0x7b,0xbb,0x38,0x7d,0xe6,0x66,0xbb,
|
|
0xbe,0x67,0x0a,0xf8,0xf3,0x92,0x0e,0xba,0x68,0xd1,0x56,0xea,0x34,0x3f,0xbc,0x4f,
|
|
0xf1,0xd9,0x1e};
|
|
|
|
mbedtls_hkdf(md_info, salt, sizeof(salt), KEYIN, CDI_DGST_SIZE,
|
|
IDENTITY, sizeof(IDENTITY), CDIKEY, CDI_KEY_SIZE);
|
|
|
|
//mbedtls_hkdf_extract( md_info, salt, sizeof(salt),KEYIN, CDI_DGST_SIZE, CDIKEY);
|
|
|
|
for(int i = 0; i < CDI_KEY_SIZE; i++)
|
|
printf("%hhx",CDIKEY[i]);
|
|
printf(" : CDIKEY\n");
|
|
|
|
free(KEYIN);
|
|
|
|
return RIOTSUCCESS;
|
|
}
|
|
|
|
|
|
|
|
//firt generate ECC/RSA key. - Done ECC
|
|
//check for deterministic consistency - inconsistent
|
|
//seed RNGs with CDI
|
|
//let's see how it goes
|
|
|
|
//add entropy source?
|
|
//seed RNG
|
|
//create ctx
|
|
//init
|
|
//gen keypair
|
|
|
|
|
|
/* To use HW TRNG /dev/random as the source of entropy add source to entropy contxt -
|
|
*/
|
|
|
|
int use_dev_random(void *data, unsigned char *output,
|
|
size_t len, size_t *olen )
|
|
{
|
|
FILE *file;
|
|
size_t ret, left = len;
|
|
unsigned char *p = output;
|
|
((void) data);
|
|
|
|
*olen = 0;
|
|
|
|
file = fopen( "/dev/random", "rb" );
|
|
if( file == NULL )
|
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
|
|
|
while( left > 0 )
|
|
{
|
|
/* /dev/random can return much less than requested. If so, try again */
|
|
ret = fread( p, 1, left, file );
|
|
if( ret == 0 && ferror( file ) )
|
|
{
|
|
fclose( file );
|
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
|
}
|
|
|
|
p += ret;
|
|
left -= ret;
|
|
sleep( 1 );
|
|
}
|
|
fclose( file );
|
|
*olen = len;
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
|
|
int seedRNGSource(void *data, unsigned char *output, size_t len)
|
|
{
|
|
//srand(); lib fun call //https://stackoverflow.com/questions/55927662/generate-every-time-same-rsa-key-with-c
|
|
//ctr_drbg //programs/test/benchmark.c:705
|
|
//hmac_drbg
|
|
|
|
//Fill entropy accum with CDI and pass to DRBG
|
|
|
|
|
|
mbedtls_entropy_context * p_ent = data;
|
|
printf("manual update entropy with CDI\n");
|
|
|
|
if(memcpy(output, p_ent -> accumulator.buffer + ACCUM_BUFF_OFFSET , ENTROPY_LEN) < 0)
|
|
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
|
|
|
|
len = ENTROPY_LEN;
|
|
|
|
|
|
return 0;
|
|
|
|
// ((void) data);
|
|
// printf("Direct return CDI to drbg\n");
|
|
|
|
// len = sizeof(CDI);
|
|
// memcpy(output, CDI, len);
|
|
// for(int i = 0; i < len; i++)
|
|
// printf("0x%hhx,",output[i]);
|
|
// printf(" : CDIKEY\n");
|
|
// printf("%d\n", (int)len);
|
|
// return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int deriveECCKeyPair(KeyDrv_context * KD_ctx)
|
|
{
|
|
|
|
printf("inside deriveECCKeyPair layer1\n\n");
|
|
|
|
int ret = 0;
|
|
unsigned char pubkeybuf[100];
|
|
size_t pubkeysize;
|
|
char privkeybuf[100];
|
|
size_t privkeysize;
|
|
char privkeybuf2[100];
|
|
size_t privkey2size;
|
|
|
|
|
|
mbedtls_ecp_group ecpGrp;
|
|
mbedtls_ecp_group_init(&ecpGrp);
|
|
mbedtls_ecp_group_load(&ecpGrp, ECC_CURVE);
|
|
|
|
mbedtls_mpi secret;
|
|
mbedtls_mpi_init(&secret);
|
|
|
|
mbedtls_ecp_point Public;
|
|
mbedtls_ecp_point_init(&Public);
|
|
|
|
mbedtls_entropy_context entropyCtx;
|
|
mbedtls_entropy_init(&entropyCtx);
|
|
|
|
mbedtls_ctr_drbg_context drbgCtx;
|
|
mbedtls_ctr_drbg_init(&drbgCtx);
|
|
|
|
|
|
if (KD_ctx->ENT_MODE == HW_TRNG) //HW RNG
|
|
{
|
|
printf("using /dev/random.... this may take a moment\n");
|
|
mbedtls_entropy_add_source( &entropyCtx, use_dev_random,
|
|
NULL, ENTROPY_LEN, MBEDTLS_ENTROPY_SOURCE_STRONG );
|
|
|
|
mbedtls_ctr_drbg_seed(&drbgCtx, mbedtls_entropy_func, &entropyCtx,
|
|
(const unsigned char *) KD_ctx->phrase, strlen(KD_ctx->phrase) );
|
|
}
|
|
|
|
else if (KD_ctx->ENT_MODE == DETERM) // Deterministic derviation with seed
|
|
{
|
|
printf("Seeding entropy accumulator....\n");
|
|
if(mbedtls_entropy_update_manual(&entropyCtx, KD_ctx->seed, ENTROPY_LEN) < 0)
|
|
{
|
|
perror("Accumulator seed failed\n");
|
|
return RIOTFAILURE;
|
|
}
|
|
|
|
if(mbedtls_ctr_drbg_seed(&drbgCtx, seedRNGSource, &entropyCtx,
|
|
(const unsigned char *) KD_ctx->phrase, sizeof(&KD_ctx->phrase)) < 0)
|
|
{
|
|
perror("drbg seed failed\v");
|
|
return RIOTFAILURE;
|
|
}
|
|
}
|
|
|
|
else //regular SW accumulator used for key derivation
|
|
{
|
|
printf("Accumulating entropy ...\n");
|
|
mbedtls_entropy_update_manual(&entropyCtx, KD_ctx->seed, ENTROPY_LEN);
|
|
mbedtls_ctr_drbg_seed(&drbgCtx, mbedtls_entropy_func, &entropyCtx,
|
|
(const unsigned char *) KD_ctx->phrase, strlen(KD_ctx->phrase) );
|
|
}
|
|
|
|
if(mbedtls_ecp_gen_keypair(&ecpGrp, &secret, &Public,
|
|
mbedtls_ctr_drbg_random, &drbgCtx) <0)
|
|
{
|
|
perror("ECP gen keypair failed\n");
|
|
return RIOTFAILURE;
|
|
}
|
|
|
|
ret = mbedtls_ecp_tls_write_point(&ecpGrp, &Public, MBEDTLS_ECP_PF_UNCOMPRESSED,
|
|
&pubkeysize, pubkeybuf, sizeof(pubkeybuf));
|
|
if(ret < 0)
|
|
{
|
|
perror("ECP write point failure\n");
|
|
return RIOTFAILURE;
|
|
}
|
|
|
|
//printf("%zu : pubkeysize\n", pubkeysize );
|
|
for(int i = 0; i < pubkeysize; i++)
|
|
printf("%hhx",pubkeybuf[i]);
|
|
printf(" : PubKey\n");
|
|
|
|
|
|
ret = mbedtls_mpi_write_string(&secret, 16, privkeybuf, sizeof(privkeybuf), &privkeysize);
|
|
if(ret < 0)
|
|
{
|
|
printf("%d\n", ret);
|
|
perror("MPI write point to string failure\n");
|
|
return RIOTFAILURE;
|
|
}
|
|
|
|
printf("%s : PrivKey\n",privkeybuf);
|
|
|
|
//copy keys to parent function
|
|
mbedtls_ecp_copy(&KD_ctx->Public, &Public);
|
|
mbedtls_mpi_copy(&KD_ctx->secret, &secret); /* Make SK NULL for Identitiy key generation */
|
|
|
|
|
|
|
|
//what now? how to obtain the keys in PEM/DER/bin format?
|
|
|
|
//following experiment better documented in ECC_trial/PKtoPEM.c
|
|
/**
|
|
mbedtls_pk_context ec_pkCtx;
|
|
mbedtls_pk_init(&ec_pkCtx);
|
|
|
|
mbedtls_pk_setup(&ec_pkCtx, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY));
|
|
mbedtls_ecp_keypair *pk_ecp = mbedtls_pk_ec( ec_pkCtx );
|
|
|
|
mbedtls_ecp_copy(&pk_ecp->Q, &Public);
|
|
mbedtls_mpi_copy(&pk_ecp->d, &secret);
|
|
|
|
mbedtls_mpi_write_string(&pk_ecp->d, 16, privkeybuf2, sizeof(privkeybuf2), &privkey2size);
|
|
printf("%s : wrapped PrivKey\n",privkeybuf2);
|
|
|
|
|
|
|
|
ret = 0;
|
|
unsigned char privBuf[16000];
|
|
unsigned char * d_b = privBuf;
|
|
memset(privBuf, 0, 16000);
|
|
unsigned char pubBuf[16000];
|
|
unsigned char * Q_b = pubBuf;
|
|
memset(pubBuf, 0, 16000);
|
|
ret = mbedtls_pk_write_key_pem(&ec_pkCtx, privBuf, 16000);
|
|
printf("write priv pem ret value = %d\n", ret);
|
|
|
|
printf("%s\n", privBuf);
|
|
|
|
ret = mbedtls_pk_write_pubkey_pem(&ec_pkCtx, pubBuf, 16000);
|
|
printf("write pub pem ret value = %d\n", ret);
|
|
|
|
printf("%s\n", pubBuf);
|
|
|
|
**/
|
|
|
|
|
|
mbedtls_mpi_free(&secret);
|
|
mbedtls_ecp_point_free(&Public);
|
|
mbedtls_ecp_group_free(&ecpGrp);
|
|
mbedtls_entropy_free(&entropyCtx);
|
|
mbedtls_ctr_drbg_free(&drbgCtx);
|
|
|
|
printf("leaving deriveECCKeyPair layer1\n\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int deriveRSAKeyPair(void)
|
|
{
|
|
printf("inside deriveRSAKeyPair layer1\n\n");
|
|
|
|
mbedtls_rsa_context rsaCtx;
|
|
mbedtls_rsa_init(&rsaCtx,MBEDTLS_RSA_PKCS_V21, RSA_HASH_ID);
|
|
|
|
mbedtls_entropy_context entropyCtx;
|
|
mbedtls_entropy_init(&entropyCtx);
|
|
|
|
mbedtls_ctr_drbg_context drbgCtx;
|
|
mbedtls_ctr_drbg_init(&drbgCtx);
|
|
|
|
//Seed drbg with secret data now?
|
|
//move "private" string to n param
|
|
int ret = mbedtls_ctr_drbg_seed(&drbgCtx, mbedtls_entropy_func, &entropyCtx,
|
|
(const unsigned char *) "Private", sizeof("Private"));
|
|
|
|
mbedtls_rsa_gen_key(&rsaCtx,mbedtls_ctr_drbg_random, &drbgCtx,
|
|
(unsigned int) 256, 65537);
|
|
|
|
//is the key generated and stored in the contxt struct?
|
|
//what now? how to obtain the keys in PEM/DER/bin format?
|
|
|
|
printf("leaving deriveRSAKeyPair layer1\n\n");
|
|
|
|
return 0;
|
|
}
|