From 4214e472f9f4d10cfc3824acc0f15c5df59d2416 Mon Sep 17 00:00:00 2001 From: "atul.jha" Date: Fri, 24 Jul 2020 16:24:10 +0200 Subject: [PATCH] move key derivatin to layer1 --- trial3/layer1.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- trial3/layer1.h | 13 ++++++++++--- trial3/layer2.c | 42 ++++++++++++++++++++++++------------------ trial3/out/main | Bin 18128 -> 18520 bytes 4 files changed, 80 insertions(+), 22 deletions(-) diff --git a/trial3/layer1.c b/trial3/layer1.c index 781a92a..e62b3cc 100644 --- a/trial3/layer1.c +++ b/trial3/layer1.c @@ -180,4 +180,49 @@ int _calcCDIKEY(uint8_t * CDIKEY) free(KEYIN); return RIOTSUCCESS; -} \ No newline at end of file +} + +int deriveECCKeyPair(mbedtls_mpi * SK, mbedtls_ecp_point * PK) +{ + + printf("inside deriveECCKeyPair layer1\n\n"); + + 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); + + //Seed drbg with secret data now? + + int ret = mbedtls_ctr_drbg_seed(&drbgCtx, mbedtls_entropy_func, &entropyCtx, + (const unsigned char *) "Private", sizeof("Private")); + + ret = mbedtls_ecp_gen_keypair(&ecpGrp, &secret, &Public, + mbedtls_ctr_drbg_random, &drbgCtx); + + mbedtls_ecp_copy(PK, &Public); + mbedtls_mpi_copy(SK, &secret); + + 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){return 0;} \ No newline at end of file diff --git a/trial3/layer1.h b/trial3/layer1.h index baeddd0..43a46b4 100644 --- a/trial3/layer1.h +++ b/trial3/layer1.h @@ -1,11 +1,16 @@ #include #include - -#include +#include +#include +#include #include +#include +#include +#include #include #include +#include #include #include @@ -17,4 +22,6 @@ int readUDS(uint8_t* UDSdigest); int readFWID(uint8_t * FW_M); int _calcCDID(uint8_t * CDID); -int _calcCDIKEY(uint8_t * CDIKEY); \ No newline at end of file +int _calcCDIKEY(uint8_t * CDIKEY); +int deriveECCKeyPair(mbedtls_mpi * SK, mbedtls_ecp_point * PK); +int deriveRSAKeyPair(void); \ No newline at end of file diff --git a/trial3/layer2.c b/trial3/layer2.c index 5dfff3e..bbe7132 100644 --- a/trial3/layer2.c +++ b/trial3/layer2.c @@ -60,30 +60,36 @@ void deriveDeviceIDKeyPair(uint8_t * CDIKEY, int isECC) { - mbedtls_ecp_group ecpGrp; - mbedtls_ecp_group_init(&ecpGrp); - mbedtls_ecp_group_load(&ecpGrp, ECC_CURVE); + // mbedtls_ecp_group ecpGrp; + // mbedtls_ecp_group_init(&ecpGrp); + // mbedtls_ecp_group_load(&ecpGrp, ECC_CURVE); - mbedtls_mpi secret; + // 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); + + // int ret = mbedtls_ctr_drbg_seed(&drbgCtx, mbedtls_entropy_func, &entropyCtx, + // (const unsigned char *) "Private", sizeof("Private")); + + // ret = mbedtls_ecp_gen_keypair(&ecpGrp, &secret, &Public, + // mbedtls_ctr_drbg_random, &drbgCtx); + + + 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); - - - int ret = mbedtls_ctr_drbg_seed(&drbgCtx, mbedtls_entropy_func, &entropyCtx, - (const unsigned char *) "Private", sizeof("Private")); - - ret = mbedtls_ecp_gen_keypair(&ecpGrp, &secret, &Public, - mbedtls_ctr_drbg_random, &drbgCtx); - - + deriveECCKeyPair(&secret, &Public);b return; } diff --git a/trial3/out/main b/trial3/out/main index 03f69ebb6dd65a1dd80f49d3fe1f67bb0e44464f..a9ecfe1dd50d9f93537f930febdae163409cbbc2 100755 GIT binary patch literal 18520 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 Cl28Ny delta 5480 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 TjB;a7wF