From 2cbc6ed673c1830d777b407c01f7f0a7360fd9c3 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 23 Nov 2016 15:44:53 -0700 Subject: [PATCH 01/16] ARMv8 : handle aggressive optimizers --- wolfcrypt/src/port/arm/armv8-aes.c | 37 +++++++++++++++------------ wolfcrypt/src/port/arm/armv8-sha256.c | 12 ++++++--- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index c95334219..13e106159 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -527,8 +527,8 @@ int wc_InitAes_h(Aes* aes, void* h) "#store current counter value at the end \n" "ST1 {v0.2d}, %[regOut] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg) - :"0" (out), [Key] "m" (aes->key), [input] "r" (in), + :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) + :"0" (out), [Key] "m" (aes->key), [input] "2" (in), [blocks] "r" (numBlocks), [reg] "m" (aes->reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13" @@ -584,8 +584,8 @@ int wc_InitAes_h(Aes* aes, void* h) "ST1 {v0.2d}, %[regOut] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg) - :"0" (out), [Key] "m" (aes->key), [input] "r" (in), + :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) + :"0" (out), [Key] "m" (aes->key), [input] "2" (in), [blocks] "r" (numBlocks), [reg] "m" (aes->reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14" @@ -646,8 +646,8 @@ int wc_InitAes_h(Aes* aes, void* h) "ST1 {v0.2d}, %[regOut] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg) - :"0" (out), [Key] "m" (aes->key), [input] "r" (in), + :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) + :"0" (out), [Key] "m" (aes->key), [input] "2" (in), [blocks] "r" (numBlocks), [reg] "m" (aes->reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14","v15", @@ -720,8 +720,8 @@ int wc_InitAes_h(Aes* aes, void* h) "#store current counter value at the end \n" "ST1 {v13.2d}, %[regOut] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg) - :"0" (out), [Key] "m" (aes->key), [input] "r" (in), + :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) + :"0" (out), [Key] "m" (aes->key), [input] "2" (in), [blocks] "r" (numBlocks), [reg] "m" (aes->reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13" @@ -778,8 +778,8 @@ int wc_InitAes_h(Aes* aes, void* h) "#store current counter value at the end \n" "ST1 {v15.2d}, %[regOut] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg) - :"0" (out), [Key] "m" (aes->key), [input] "r" (in), + :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) + :"0" (out), [Key] "m" (aes->key), [input] "2" (in), [blocks] "r" (numBlocks), [reg] "m" (aes->reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" @@ -840,8 +840,8 @@ int wc_InitAes_h(Aes* aes, void* h) "#store current counter value at the end \n" "ST1 {v17.2d}, %[regOut] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg) - :"0" (out), [Key] "m" (aes->key), [input] "r" (in), + :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) + :"0" (out), [Key] "m" (aes->key), [input] "2" (in), [blocks] "r" (numBlocks), [reg] "m" (aes->reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14","v15", @@ -2039,7 +2039,8 @@ static int Aes192GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, ,[inX] "4" (xPt), [inY] "m" (aes->H) : "cc", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14" - ,"v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24" + ,"v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", + "v24","v25","v26","v27","v28","v29","v30","v31" ); } @@ -2473,7 +2474,8 @@ static int Aes256GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, [ctr] "2" (iCtr) , [h] "m" (aes->H) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10","v11","v12","v13","v14", - "v15", "v16", "v17","v18", "v19", "v20","v21","v22","v23","v24" + "v15", "v16", "v17","v18", "v19", "v20","v21","v22","v23", + "v24","v25","v26","v27","v28","v29","v30","v31" ); @@ -4061,7 +4063,8 @@ static void GMULT(byte* X, byte* Y) : [xOut] "=r" (X), [yOut] "=r" (Y) : [x] "0" (X), [y] "1" (Y) - : + : "cc", "memory", "q0", "q1", "q2", "q3", "q4", "q5", "q6" ,"q7", "q8", + "q9", "q10", "q11" ,"q12", "q13", "q14", "q15" ); } @@ -4597,7 +4600,7 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) "ST1 {v0.16b}, [%[out]] \n" : [out] "=r" (pt) : [h] "0" (pt) - : "cc", "memory" + : "cc", "memory", "v0" ); } #else @@ -4610,7 +4613,7 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) "VST1.32 {q0}, [%[out]] \n" : [out] "=r" (pt) : [h] "0" (pt) - : "cc", "memory" + : "cc", "memory", "q0" ); } #endif diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index cceb8c865..06bc6897c 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -305,7 +305,9 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) [blocks] "2" (numBlocks), [dataIn] "3" (data) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", - "v15", "w8" + "v15", "v16", "v17", "v18", "v19", "v20", "v21", + "v22", "v23", "v24", "v25", "v26", "v27", "v28", + "v29", "v30", "v31", "w8" ); AddLength(sha256, SHA256_BLOCK_SIZE * numBlocks); @@ -488,6 +490,7 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) [buffer] "m" (sha256->buffer) : "cc", "memory", "v0", "v1", "v2", "v3", "v8", "v9", "v10", "v11" , "v12", "v13", "v14", "v15", "v16", "v17", "v18" + , "v19", "v20", "v21", "v22", "v23", "v24", "v25" ); sha256->buffLen = 0; @@ -510,7 +513,7 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "ST1 {v0.2d-v3.2d}, %[out] \n" : [out] "=m" (sha256->buffer) : [in] "m" (sha256->buffer) - : "cc", "memory" + : "cc", "memory", "v0", "v1", "v2", "v3" ); #endif /* ! length ordering dependent on digest endian type ! */ @@ -666,7 +669,8 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "0" (hash) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", - "v15", "v16", "v17", "v18" + "v15", "v16", "v17", "v18", "v19", "v20", "v21", + "v22", "v23", "v24", "v25" ); return wc_InitSha256(sha256); /* reset state */ @@ -1119,7 +1123,7 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "VST1.32 {q3}, [%[out]] \n" : [out] "=r" (bufPt) : [in] "0" (bufPt) - : "cc", "memory" + : "cc", "memory", "q0", "q1", "q2", "q3" ); #endif /* ! length ordering dependent on digest endian type ! */ From 4a7651a09a1668410bb747bd43acdf6473ce87c5 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 17 Oct 2016 19:17:58 -0700 Subject: [PATCH 02/16] STM32 F2/F4 CubeMX and Std Peripheral Library hardware crypto support for RNG, AES, SHA1, DES3 and MD5. Adds new WOLFSSL_STM32_CUBEMX and WOLFSSL_STM32F4 defines. Tested on STM32F437II. --- wolfcrypt/src/aes.c | 384 +++++++++++++++++++++++++++-------- wolfcrypt/src/des3.c | 238 +++++++++++++++------- wolfcrypt/src/md5.c | 31 ++- wolfcrypt/src/random.c | 37 +++- wolfcrypt/src/sha.c | 12 +- wolfssl/wolfcrypt/des3.h | 2 +- wolfssl/wolfcrypt/md5.h | 2 +- wolfssl/wolfcrypt/settings.h | 40 +++- wolfssl/wolfcrypt/sha.h | 2 +- 9 files changed, 549 insertions(+), 199 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 9837e9f29..2f007eeb5 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -201,96 +201,172 @@ void wc_AesAsyncFree(Aes* aes) #endif /* Define AES implementation includes and functions */ -#if defined(STM32F2_CRYPTO) - /* STM32F2 hardware AES support for CBC, CTR modes through the STM32F2 - * Standard Peripheral Library. Documentation located in STM32F2xx - * Standard Peripheral Library document (See note in README). */ - #include "stm32f2xx.h" - #include "stm32f2xx_cryp.h" +#if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) + /* STM32F2/F4 hardware AES support for CBC, CTR modes */ +#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) ||\ + defined(HAVE_AESGCM) static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { - word32 *enc_key; - CRYP_InitTypeDef AES_CRYP_InitStructure; - CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; + int ret = 0; + #ifdef WOLFSSL_STM32_CUBEMX + CRYP_HandleTypeDef hcryp; - enc_key = aes->key; + /* load key into correct registers */ + switch(aes->rounds) { + case 10: /* 128-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + break; + case 12: /* 192-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_192B; + break; + case 14: /* 256-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_256B; + break; + default: + break; + } - /* crypto structure initialization */ - CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); - CRYP_StructInit(&AES_CRYP_InitStructure); + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = (uint8_t*)aes->key; - /* reset registers to their default values */ - CRYP_DeInit(); + HAL_CRYP_Init(&hcryp); - /* load key into correct registers */ - switch(aes->rounds) - { - case 10: /* 128-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; - break; + if (HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE, + outBlock, STM32_HAL_TIMEOUT) != HAL_OK) { + ret = WC_TIMEOUT_E; + } - case 12: /* 192-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; - break; + HAL_CRYP_DeInit(&hcryp); + #else + word32 *enc_key; + CRYP_InitTypeDef AES_CRYP_InitStructure; + CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure; - case 14: /* 256-bit key */ - AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; - AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; - AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; - AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; - AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; - AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; - AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; - AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; - AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; - break; + enc_key = aes->key; - default: - break; - } - CRYP_KeyInit(&AES_CRYP_KeyInitStructure); + /* crypto structure initialization */ + CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure); + CRYP_StructInit(&AES_CRYP_InitStructure); - /* set direction, mode, and datatype */ - AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; - AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB; - AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; - CRYP_Init(&AES_CRYP_InitStructure); + /* reset registers to their default values */ + CRYP_DeInit(); - /* enable crypto processor */ - CRYP_Cmd(ENABLE); + /* load key into correct registers */ + switch(aes->rounds) + { + case 10: /* 128-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[3]; + break; - /* flush IN/OUT FIFOs */ - CRYP_FIFOFlush(); + case 12: /* 192-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[5]; + break; - CRYP_DataIn(*(uint32_t*)&inBlock[0]); - CRYP_DataIn(*(uint32_t*)&inBlock[4]); - CRYP_DataIn(*(uint32_t*)&inBlock[8]); - CRYP_DataIn(*(uint32_t*)&inBlock[12]); + case 14: /* 256-bit key */ + AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b; + AES_CRYP_KeyInitStructure.CRYP_Key0Left = enc_key[0]; + AES_CRYP_KeyInitStructure.CRYP_Key0Right = enc_key[1]; + AES_CRYP_KeyInitStructure.CRYP_Key1Left = enc_key[2]; + AES_CRYP_KeyInitStructure.CRYP_Key1Right = enc_key[3]; + AES_CRYP_KeyInitStructure.CRYP_Key2Left = enc_key[4]; + AES_CRYP_KeyInitStructure.CRYP_Key2Right = enc_key[5]; + AES_CRYP_KeyInitStructure.CRYP_Key3Left = enc_key[6]; + AES_CRYP_KeyInitStructure.CRYP_Key3Right = enc_key[7]; + break; - /* wait until the complete message has been processed */ - while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} + default: + break; + } + CRYP_KeyInit(&AES_CRYP_KeyInitStructure); - *(uint32_t*)&outBlock[0] = CRYP_DataOut(); - *(uint32_t*)&outBlock[4] = CRYP_DataOut(); - *(uint32_t*)&outBlock[8] = CRYP_DataOut(); - *(uint32_t*)&outBlock[12] = CRYP_DataOut(); + /* set direction, mode, and datatype */ + AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt; + AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB; + AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b; + CRYP_Init(&AES_CRYP_InitStructure); - /* disable crypto processor */ - CRYP_Cmd(DISABLE); + /* enable crypto processor */ + CRYP_Cmd(ENABLE); - return 0; + /* flush IN/OUT FIFOs */ + CRYP_FIFOFlush(); + + CRYP_DataIn(*(uint32_t*)&inBlock[0]); + CRYP_DataIn(*(uint32_t*)&inBlock[4]); + CRYP_DataIn(*(uint32_t*)&inBlock[8]); + CRYP_DataIn(*(uint32_t*)&inBlock[12]); + + /* wait until the complete message has been processed */ + while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {} + + *(uint32_t*)&outBlock[0] = CRYP_DataOut(); + *(uint32_t*)&outBlock[4] = CRYP_DataOut(); + *(uint32_t*)&outBlock[8] = CRYP_DataOut(); + *(uint32_t*)&outBlock[12] = CRYP_DataOut(); + + /* disable crypto processor */ + CRYP_Cmd(DISABLE); + #endif /* WOLFSSL_STM32_CUBEMX */ + return ret; } +#endif /* AES_CBC or AES_DIRECT or AESGCM */ + +#ifdef HAVE_AES_DECRYPT + #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) + static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + int ret = 0; + #ifdef WOLFSSL_STM32_CUBEMX + CRYP_HandleTypeDef hcryp; + + /* load key into correct registers */ + switch(aes->rounds) { + case 10: /* 128-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + break; + case 12: /* 192-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_192B; + break; + case 14: /* 256-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_256B; + break; + default: + break; + } + + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = (uint8_t*)aes->key; + + HAL_CRYP_Init(&hcryp); + + if (HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE, + outBlock, STM32_HAL_TIMEOUT) != HAL_OK) { + ret = WC_TIMEOUT_E; + } + + HAL_CRYP_DeInit(&hcryp); + #else + #error AES Decrypt not implemented for STM32 StdPeri lib + #endif /* WOLFSSL_STM32_CUBEMX */ + return ret; + } + #endif /* AES_CBC or AES_DIRECT */ +#endif /* HAVE_AES_DECRYPT */ #elif defined(HAVE_COLDFIRE_SEC) /* Freescale Coldfire SEC support for CBC mode. @@ -1525,9 +1601,10 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) /* wc_AesSetKey */ -#ifdef STM32F2_CRYPTO - int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, - int dir) +#if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) + +int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) { word32 *rk = aes->key; @@ -1538,7 +1615,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) aes->rounds = keylen/4 + 6; XMEMCPY(rk, userKey, keylen); + #ifndef WOLFSSL_STM32_CUBEMX ByteReverseWords(rk, rk, keylen); + #endif return wc_AesSetIV(aes, iv); } @@ -1549,6 +1628,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) return wc_AesSetKey(aes, userKey, keylen, iv, dir); } #endif + #elif defined(HAVE_COLDFIRE_SEC) #if defined (HAVE_THREADX) #include "memory_pools.h" @@ -1574,7 +1654,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { if (AESBuffIn == NULL) { #if defined (HAVE_THREADX) - int s1, s2, s3, s4, s5 ; + int s1, s2, s3, s4, s5 ; s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, sizeof(SECdescriptorType), TX_NO_WAIT); s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn, @@ -1905,7 +1985,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) } #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */ -#endif /* STM32F2_CRYPTO, wc_AesSetKey block */ +#endif /* wc_AesSetKey block */ /* wc_AesSetIV is shared between software and hardware */ @@ -1939,10 +2019,7 @@ int wc_InitAes_h(Aes* aes, void* h) /* AES-DIRECT */ #if defined(WOLFSSL_AES_DIRECT) - #if defined(STM32F2_CRYPTO) && defined(HAVE_AES_DECRYPT) - #error "STM32F2 crypto doesn't yet support AES direct decrypt" - - #elif defined(HAVE_COLDFIRE_SEC) + #if defined(HAVE_COLDFIRE_SEC) #error "Coldfire SEC doesn't yet support AES direct" #elif defined(WOLFSSL_PIC32MZ_CRYPT) @@ -1994,7 +2071,105 @@ int wc_InitAes_h(Aes* aes, void* h) /* AES-CBC */ #ifdef HAVE_AES_CBC -#ifdef STM32F2_CRYPTO +#if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) + +#ifdef WOLFSSL_STM32_CUBEMX + int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int ret = 0; + CRYP_HandleTypeDef hcryp; + + /* load key into correct registers */ + switch(aes->rounds) { + case 10: /* 128-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + break; + case 12: /* 192-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_192B; + break; + case 14: /* 256-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_256B; + break; + default: + break; + } + + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = (uint8_t*)aes->key; + hcryp.Init.pInitVect = (uint8_t*)aes->reg; + + HAL_CRYP_Init(&hcryp); + + while (sz > 0) { + if (HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE, + out, STM32_HAL_TIMEOUT) != HAL_OK) { + ret = WC_TIMEOUT_E; + break; + } + + /* store iv for next call */ + XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + + sz -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + HAL_CRYP_DeInit(&hcryp); + + return ret; + } + #ifdef HAVE_AES_DECRYPT + int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + int ret = 0; + CRYP_HandleTypeDef hcryp; + + /* load key into correct registers */ + switch(aes->rounds) { + case 10: /* 128-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + break; + case 12: /* 192-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_192B; + break; + case 14: /* 256-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_256B; + break; + default: + break; + } + + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = (uint8_t*)aes->key; + hcryp.Init.pInitVect = (uint8_t*)aes->reg; + + HAL_CRYP_Init(&hcryp); + + while (sz > 0) { + if (HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in, AES_BLOCK_SIZE, + out, STM32_HAL_TIMEOUT) != HAL_OK) { + ret = WC_TIMEOUT_E; + } + + /* store iv for next call */ + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + + sz -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + HAL_CRYP_DeInit(&hcryp); + + return ret; + } + #endif /* HAVE_AES_DECRYPT */ +#else int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { word32 *enc_key, *iv; @@ -2222,13 +2397,15 @@ int wc_InitAes_h(Aes* aes, void* h) return 0; } #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_STM32_CUBEMX */ + #elif defined(HAVE_COLDFIRE_SEC) static int wc_AesCbcCrypt(Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader) { #ifdef DEBUG_WOLFSSL int i; int stat1, stat2; int ret; - #endif + #endif int size; volatile int v; @@ -2663,13 +2840,47 @@ int wc_InitAes_h(Aes* aes, void* h) } #endif -#endif /* STM32F2_CRYPTO, AES-CBC block */ +#endif /* AES-CBC block */ #endif /* HAVE_AES_CBC */ /* AES-CTR */ #ifdef WOLFSSL_AES_COUNTER - #ifdef STM32F2_CRYPTO + #if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) + #ifdef WOLFSSL_STM32_CUBEMX + void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + CRYP_HandleTypeDef hcryp; + + /* load key into correct registers */ + switch(aes->rounds) { + case 10: /* 128-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + break; + case 12: /* 192-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_192B; + break; + case 14: /* 256-bit key */ + hcryp.Init.KeySize = CRYP_KEYSIZE_256B; + break; + default: + break; + } + + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = aes->key; + hcryp.Init.pInitVect = aes->reg; + + HAL_CRYP_Init(&hcryp); + + HAL_CRYP_AESCTR_Encrypt(&hcryp, in, AES_BLOCK_SIZE, out, + STM32_HAL_TIMEOUT); + + HAL_CRYP_DeInit(&hcryp); + } + #else void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { word32 *enc_key, *iv; @@ -2772,6 +2983,7 @@ int wc_InitAes_h(Aes* aes, void* h) /* disable crypto processor */ CRYP_Cmd(DISABLE); } + #endif /* WOLFSSL_STM32_CUBEMX */ #elif defined(WOLFSSL_PIC32MZ_CRYPT) void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) @@ -2911,7 +3123,7 @@ int wc_InitAes_h(Aes* aes, void* h) } } - #endif /* STM32F2_CRYPTO, AES-CTR block */ + #endif /* AES-CTR block */ #endif /* WOLFSSL_AES_COUNTER */ @@ -4505,7 +4717,7 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, #ifdef WOLFSSL_ASYNC_CRYPT - + /* Initialize Aes for use with Nitrox device */ int wc_AesAsyncInit(Aes* aes, int devId) { diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index cc27ab3c1..8cb1a3125 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -126,23 +126,23 @@ void wc_Des3AsyncFree(Des3* des3) #endif -#ifdef STM32F2_CRYPTO +#if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) + /* - * STM32F2 hardware DES/3DES support through the STM32F2 standard - * peripheral library. Documentation located in STM32F2xx Standard - * Peripheral Library document (See note in README). + * STM32F2/F4 hardware DES/3DES support through the standard + * peripheral library. (See note in README). */ - #include "stm32f2xx.h" - #include "stm32f2xx_cryp.h" int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) { word32 *dkey = des->key; - + (void)dir; XMEMCPY(dkey, key, 8); + #ifndef WOLFSSL_STM32_CUBEMX ByteReverseWords(dkey, dkey, 8); + #endif wc_Des_SetIV(des, iv); @@ -154,16 +154,18 @@ void wc_Des3AsyncFree(Des3* des3) word32 *dkey1 = des->key[0]; word32 *dkey2 = des->key[1]; word32 *dkey3 = des->key[2]; - + (void)dir; XMEMCPY(dkey1, key, 8); /* set key 1 */ XMEMCPY(dkey2, key + 8, 8); /* set key 2 */ XMEMCPY(dkey3, key + 16, 8); /* set key 3 */ + #ifndef WOLFSSL_STM32_CUBEMX ByteReverseWords(dkey1, dkey1, 8); ByteReverseWords(dkey2, dkey2, 8); ByteReverseWords(dkey3, dkey3, 8); + #endif return wc_Des3_SetIV(des, iv); } @@ -171,6 +173,54 @@ void wc_Des3AsyncFree(Des3* des3) static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz, int dir, int mode) { + #ifdef WOLFSSL_STM32_CUBEMX + CRYP_HandleTypeDef hcryp; + + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = (uint8_t*)des->key; + hcryp.Init.pInitVect = (uint8_t*)des->reg; + + HAL_CRYP_Init(&hcryp); + + while (sz > 0) + { + /* if input and output same will overwrite input iv */ + XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + + if (mode == DES_CBC) { + if (dir == DES_ENCRYPTION) { + HAL_CRYP_DESCBC_Encrypt(&hcryp, (uint8_t*)in, + DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); + } + else { + HAL_CRYP_DESCBC_Decrypt(&hcryp, (uint8_t*)in, + DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); + } + } + else { + if (dir == DES_ENCRYPTION) { + HAL_CRYP_DESECB_Encrypt(&hcryp, (uint8_t*)in, + DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); + } + else { + HAL_CRYP_DESECB_Decrypt(&hcryp, (uint8_t*)in, + DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); + } + } + + /* store iv for next call */ + XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); + + sz -= DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + out += DES_BLOCK_SIZE; + } + + HAL_CRYP_DeInit(&hcryp); + #else word32 *dkey, *iv; CRYP_InitTypeDef DES_CRYP_InitStructure; CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure; @@ -244,6 +294,7 @@ void wc_Des3AsyncFree(Des3* des3) /* disable crypto processor */ CRYP_Cmd(DISABLE); + #endif /* WOLFSSL_STM32_CUBEMX */ } int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) @@ -267,6 +318,39 @@ void wc_Des3AsyncFree(Des3* des3) static void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz, int dir) { + #ifdef WOLFSSL_STM32_CUBEMX + CRYP_HandleTypeDef hcryp; + + XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef)); + hcryp.Instance = CRYP; + hcryp.Init.KeySize = CRYP_KEYSIZE_128B; + hcryp.Init.DataType = CRYP_DATATYPE_8B; + hcryp.Init.pKey = (uint8_t*)des->key; + hcryp.Init.pInitVect = (uint8_t*)des->reg; + + HAL_CRYP_Init(&hcryp); + + while (sz > 0) + { + if (dir == DES_ENCRYPTION) { + HAL_CRYP_TDESCBC_Encrypt(&hcryp, (byte*)in, + DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); + } + else { + HAL_CRYP_TDESCBC_Decrypt(&hcryp, (byte*)in, + DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT); + } + + /* store iv for next call */ + XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE); + + sz -= DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; + out += DES_BLOCK_SIZE; + } + + HAL_CRYP_DeInit(&hcryp); + #else word32 *dkey1, *dkey2, *dkey3, *iv; CRYP_InitTypeDef DES3_CRYP_InitStructure; CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure; @@ -338,7 +422,7 @@ void wc_Des3AsyncFree(Des3* des3) /* disable crypto processor */ CRYP_Cmd(DISABLE); - + #endif /* WOLFSSL_STM32_CUBEMX */ } int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) @@ -369,8 +453,8 @@ extern TX_BYTE_POOL mp_ncached; /* Non Cached memory pool */ #define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64) static unsigned char *desBuffIn = NULL ; static unsigned char *desBuffOut = NULL ; -static byte *secIV ; -static byte *secKey ; +static byte *secIV ; +static byte *secKey ; static volatile SECdescriptorType *secDesc ; static wolfSSL_Mutex Mutex_DesSEC ; @@ -387,12 +471,12 @@ static wolfSSL_Mutex Mutex_DesSEC ; extern volatile unsigned char __MBAR[]; -static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, +static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, byte *key, byte *iv, word32 desc) { #ifdef DEBUG_WOLFSSL - int ret ; int stat1,stat2 ; - #endif + int ret ; int stat1,stat2 ; + #endif int size ; volatile int v ; @@ -401,22 +485,22 @@ static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, secDesc->length1 = 0x0; secDesc->pointer1 = NULL; if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){ - secDesc->length2 = DES_IVLEN ; + secDesc->length2 = DES_IVLEN ; secDesc->length3 = DES_KEYLEN ; } else { - secDesc->length2 = DES3_IVLEN ; + secDesc->length2 = DES3_IVLEN ; secDesc->length3 = DES3_KEYLEN ; } secDesc->pointer2 = secIV ; secDesc->pointer3 = secKey; secDesc->pointer4 = desBuffIn ; secDesc->pointer5 = desBuffOut ; - secDesc->length6 = 0; - secDesc->pointer6 = NULL; + secDesc->length6 = 0; + secDesc->pointer6 = NULL; secDesc->length7 = 0x0; secDesc->pointer7 = NULL; - secDesc->nextDescriptorPtr = NULL ; - + secDesc->nextDescriptorPtr = NULL ; + while(sz) { XMEMCPY(secIV, iv, secDesc->length2) ; if((sz%DES_BUFFER_SIZE) == sz) { @@ -426,10 +510,10 @@ static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, size = DES_BUFFER_SIZE ; sz -= DES_BUFFER_SIZE ; } - + XMEMCPY(desBuffIn, in, size) ; XMEMCPY(secKey, key, secDesc->length3) ; - + secDesc->header = desc ; secDesc->length4 = size; secDesc->length5 = size; @@ -442,16 +526,16 @@ static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, while((secDesc->header>> 24) != 0xff) { if(v++ > 1000)break ; } - + #ifdef DEBUG_WOLFSSL ret = MCF_SEC_SISRH; - stat1 = MCF_SEC_DSR ; - stat2 = MCF_SEC_DISR ; + stat1 = MCF_SEC_DSR ; + stat2 = MCF_SEC_DISR ; if(ret & 0xe0000000) { /* db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2) ; */ } #endif - + XMEMCPY(out, desBuffOut, size) ; if((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) { @@ -459,10 +543,10 @@ static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, } else { XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2) ; } - - in += size ; + + in += size ; out += size ; - + } wc_UnLockMutex(&Mutex_DesSEC) ; @@ -484,23 +568,23 @@ int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) int wc_Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz) { wc_Des_Cbc(out, in, sz, (byte *)des3->key, (byte *)des3->reg, SEC_DESC_DES3_CBC_ENCRYPT) ; - return 0; + return 0; } int wc_Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz) { wc_Des_Cbc(out, in, sz, (byte *)des3->key, (byte *)des3->reg, SEC_DESC_DES3_CBC_DECRYPT) ; - return 0; + return 0; } -static void setParity(byte *buf, int len) +static void setParity(byte *buf, int len) { int i, j ; byte v ; int bits ; - for(i=0; i> 1 ; buf[i] = v << 1 ; @@ -512,7 +596,7 @@ static void setParity(byte *buf, int len) } buf[i] |= (1 - (bits&0x1)) ; } - + } @@ -520,54 +604,54 @@ int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) { if(desBuffIn == NULL) { #if defined (HAVE_THREADX) - int s1, s2, s3, s4, s5 ; - s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, + int s1, s2, s3, s4, s5 ; + s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, sizeof(SECdescriptorType), TX_NO_WAIT); s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn, DES_BUFFER_SIZE, TX_NO_WAIT); s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT); /* Don't know des or des3 to be used. Allocate larger buffers */ s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey, DES3_KEYLEN,TX_NO_WAIT); - s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV, DES3_IVLEN, TX_NO_WAIT); + s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV, DES3_IVLEN, TX_NO_WAIT); #else #warning "Allocate non-Cache buffers" #endif wc_InitMutex(&Mutex_DesSEC) ; } - - XMEMCPY(des->key, key, DES_KEYLEN); - setParity((byte *)des->key, DES_KEYLEN) ; - + + XMEMCPY(des->key, key, DES_KEYLEN); + setParity((byte *)des->key, DES_KEYLEN) ; + if (iv) { XMEMCPY(des->reg, iv, DES_IVLEN); } else { XMEMSET(des->reg, 0x0, DES_IVLEN) ; } - return 0; + return 0; } int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) { - + if(desBuffIn == NULL) { #if defined (HAVE_THREADX) - int s1, s2, s3, s4, s5 ; - s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, + int s1, s2, s3, s4, s5 ; + s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, sizeof(SECdescriptorType), TX_NO_WAIT); s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn, DES_BUFFER_SIZE, TX_NO_WAIT); s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT); s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey, DES3_KEYLEN,TX_NO_WAIT); - s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV, DES3_IVLEN, TX_NO_WAIT); + s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV, DES3_IVLEN, TX_NO_WAIT); #else #warning "Allocate non-Cache buffers" #endif wc_InitMutex(&Mutex_DesSEC) ; } - - XMEMCPY(des3->key[0], key, DES3_KEYLEN); - setParity((byte *)des3->key[0], DES3_KEYLEN) ; - + + XMEMCPY(des3->key[0], key, DES3_KEYLEN); + setParity((byte *)des3->key[0], DES3_KEYLEN) ; + if (iv) { XMEMCPY(des3->reg, iv, DES3_IVLEN); } else { @@ -917,23 +1001,23 @@ int wc_Des3_SetIV(Des3* des, const byte* iv); volatile securityAssociation sa __attribute__((aligned (8))); volatile bufferDescriptor bd __attribute__((aligned (8))); volatile int k ; - + /* get uncached address */ in_l = in; out_l = out ; - sa_p = KVA0_TO_KVA1(&sa) ; + sa_p = KVA0_TO_KVA1(&sa) ; bd_p = KVA0_TO_KVA1(&bd) ; in_p = KVA0_TO_KVA1(in_l) ; out_p= KVA0_TO_KVA1(out_l); - + if(PIC32MZ_IF_RAM(in_p)) XMEMCPY((void *)in_p, (void *)in, sz); XMEMSET((void *)out_p, 0, sz); /* Set up the Security Association */ XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa)); - sa_p->SA_CTRL.ALGO = algo ; + sa_p->SA_CTRL.ALGO = algo ; sa_p->SA_CTRL.LNC = 1; sa_p->SA_CTRL.LOADIV = 1; sa_p->SA_CTRL.FB = 1; @@ -951,17 +1035,17 @@ int wc_Des3_SetIV(Des3* des, const byte* iv); bd_p->BD_CTRL.SA_FETCH_EN = 1; bd_p->BD_CTRL.LAST_BD = 1; bd_p->BD_CTRL.DESC_EN = 1; - + bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; /* (unsigned int)sa_p; */ bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; /* (unsigned int)in_p; */ bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); /* (unsigned int)out_p; */ bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd); bd_p->MSGLEN = sz ; - + /* Fire in the hole! */ CECON = 1 << 6; while (CECON); - + /* Run the engine */ CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; /* (unsigned int)bd_p ; */ CEINTEN = 0x07; @@ -974,12 +1058,11 @@ int wc_Des3_SetIV(Des3* des, const byte* iv); (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) { /* set iv for the next call */ if(dir == PIC32_ENCRYPTION) { - XMEMCPY((void *)iv, (void*)&(out_p[sz-DES_IVLEN]), DES_IVLEN) ; - } else { + XMEMCPY((void *)iv, (void*)&(out_p[sz-DES_IVLEN]), DES_IVLEN) ; + } else { ByteReverseWords((word32*)iv, (word32 *)&(in_p[sz-DES_IVLEN]), DES_IVLEN); - } - + } } ByteReverseWords((word32*)out, (word32 *)KVA0_TO_KVA1(out), sz); @@ -987,33 +1070,33 @@ int wc_Des3_SetIV(Des3* des, const byte* iv); int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) { - DesCrypt(des->key, des->reg, out, in, sz, + DesCrypt(des->key, des->reg, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC ); return 0; } int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) { - DesCrypt(des->key, des->reg, out, in, sz, + DesCrypt(des->key, des->reg, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC); return 0; } int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) { - DesCrypt(des->key[0], des->reg, out, in, sz, + DesCrypt(des->key[0], des->reg, out, in, sz, PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC); return 0; } int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) { - DesCrypt(des->key[0], des->reg, out, in, sz, + DesCrypt(des->key[0], des->reg, out, in, sz, PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC); return 0; } - -#else /* CTaoCrypt software implementation */ + +#else /* Begin wolfCrypt software implementation */ /* permuted choice table (key) */ static const byte pc1[] = { @@ -1306,7 +1389,7 @@ static int DesSetKey(const byte* key, int dir, word32* out) word32 swap = out[i]; out[i] = out[DES_KS_SIZE - 2 - i]; out[DES_KS_SIZE - 2 - i] = swap; - + swap = out[i + 1]; out[i + 1] = out[DES_KS_SIZE - 1 - i]; out[DES_KS_SIZE - 1 - i] = swap; @@ -1406,8 +1489,8 @@ static void DesProcessBlock(Des* des, const byte* in, byte* out) r = ByteReverseWord32(r); #endif IPERM(&l,&r); - - DesRawProcessBlock(&l, &r, des->key); + + DesRawProcessBlock(&l, &r, des->key); FPERM(&l,&r); #ifdef LITTLE_ENDIAN_ORDER @@ -1430,10 +1513,10 @@ static void Des3ProcessBlock(Des3* des, const byte* in, byte* out) r = ByteReverseWord32(r); #endif IPERM(&l,&r); - - DesRawProcessBlock(&l, &r, des->key[0]); - DesRawProcessBlock(&r, &l, des->key[1]); - DesRawProcessBlock(&l, &r, des->key[2]); + + DesRawProcessBlock(&l, &r, des->key[0]); + DesRawProcessBlock(&r, &l, des->key[1]); + DesRawProcessBlock(&l, &r, des->key[2]); FPERM(&l,&r); #ifdef LITTLE_ENDIAN_ORDER @@ -1519,7 +1602,7 @@ int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); out += DES_BLOCK_SIZE; - in += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; } return 0; } @@ -1535,14 +1618,15 @@ int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz) DesProcessBlock(des, in, out); out += DES_BLOCK_SIZE; - in += DES_BLOCK_SIZE; + in += DES_BLOCK_SIZE; } return 0; } #endif /* WOLFSSL_DES_ECB */ -#endif /* STM32F2_CRYPTO */ +#endif /* End wolfCrypt software implementation */ + void wc_Des_SetIV(Des* des, const byte* iv) { diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index 80ea23d8d..fdde46ff7 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -57,24 +57,21 @@ #endif -#ifdef STM32F2_HASH +#if defined(STM32F2_HASH) || defined(STM32F4_HASH) /* - * STM32F2 hardware MD5 support through the STM32F2 standard peripheral - * library. Documentation located in STM32F2xx Standard Peripheral Library - * document (See note in README). + * STM32F2/F4 hardware MD5 support through the standard peripheral + * library. (See note in README). */ - #include "stm32f2xx.h" - #include "stm32f2xx_hash.h" void wc_InitMd5(Md5* md5) { - /* STM32F2 struct notes: - * md5->buffer = first 4 bytes used to hold partial block if needed + /* STM32 struct notes: + * md5->buffer = first 4 bytes used to hold partial block if needed * md5->buffLen = num bytes currently stored in md5->buffer * md5->loLen = num bytes that have been written to STM32 FIFO */ XMEMSET(md5->buffer, 0, MD5_REG_SIZE); - + md5->buffLen = 0; md5->loLen = 0; @@ -83,7 +80,7 @@ /* configure algo used, algo mode, datatype */ HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); - HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH + HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH | HASH_DataType_8b); /* reset HASH processor */ @@ -157,7 +154,7 @@ /* wait until Busy flag == RESET */ while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} - + /* read message digest */ md5->digest[0] = HASH->HR[0]; md5->digest[1] = HASH->HR[1]; @@ -171,7 +168,7 @@ wc_InitMd5(md5); /* reset state */ } -#else /* CTaoCrypt software implementation */ +#else /* Begin wolfCrypt software implementation */ #ifndef WOLFSSL_HAVE_MIN #define WOLFSSL_HAVE_MIN @@ -292,7 +289,7 @@ static void Transform(Md5* md5) MD5STEP(F4, d, a, b, c, md5->buffer[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, md5->buffer[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, md5->buffer[9] + 0xeb86d391, 21); - + /* Add the working vars back into digest state[] */ md5->digest[0] += a; md5->digest[1] += b; @@ -300,7 +297,7 @@ static void Transform(Md5* md5) md5->digest[3] += d; } -#endif /* FREESCALE_MMCAU */ +#endif /* End Software implementation */ static INLINE void AddLength(Md5* md5, word32 len) @@ -356,9 +353,9 @@ void wc_Md5Final(Md5* md5, byte* hash) md5->buffLen = 0; } XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen); - + /* put lengths in bits */ - md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + + md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + (md5->hiLen << 3); md5->loLen = md5->loLen << 3; @@ -379,7 +376,7 @@ void wc_Md5Final(Md5* md5, byte* hash) wc_InitMd5(md5); /* reset state */ } -#endif /* STM32F2_HASH */ +#endif /* End wolfCrypt software implementation */ int wc_Md5Hash(const byte* data, word32 len, byte* hash) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index b953e2dd7..491bc86e7 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -1436,18 +1436,37 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } -#elif defined(STM32F2_RNG) - #undef RNG - #include "stm32f2xx_rng.h" - #include "stm32f2xx_rcc.h" +#elif defined(STM32F2_RNG) || defined(STM32F4_RNG) /* * wc_Generate a RNG seed using the hardware random number generator - * on the STM32F2. Documentation located in STM32F2xx Standard Peripheral - * Library document (See note in README). - */ + * on the STM32F2/F4. */ + +#ifdef WOLFSSL_STM32_CUBEMX + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + RNG_HandleTypeDef hrng; + int i; + (void)os; + + /* enable RNG clock source */ + __HAL_RCC_RNG_CLK_ENABLE(); + + /* enable RNG peripheral */ + hrng.Instance = RNG; + HAL_RNG_Init(&hrng); + + for (i = 0; i < (int)sz; i++) { + /* get value */ + output[i] = (byte)HAL_RNG_GetRandomNumber(&hrng); + } + + return 0; + } +#else int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { int i; + (void)os; /* enable RNG clock source */ RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); @@ -1455,7 +1474,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) /* enable RNG peripheral */ RNG_Cmd(ENABLE); - for (i = 0; i < sz; i++) { + for (i = 0; i < (int)sz; i++) { /* wait until RNG number is ready */ while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { } @@ -1465,6 +1484,8 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } +#endif /* WOLFSSL_STM32_CUBEMX */ + #elif defined(WOLFSSL_LPC43xx) || defined(WOLFSSL_STM32F2xx) || defined(MBED) \ || defined(WOLFSSL_EMBOS) diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index e6fe9d396..499d72399 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -73,18 +73,16 @@ #define wc_ShaUpdate wc_ShaUpdate_sw #define wc_ShaFinal wc_ShaFinal_sw -#elif defined(STM32F2_HASH) +#elif defined(STM32F2_HASH) || defined(STM32F4_HASH) + /* - * STM32F2 hardware SHA1 support through the STM32F2 standard peripheral - * library. Documentation located in STM32F2xx Standard Peripheral Library - * document (See note in README). + * STM32F2/F4 hardware SHA1 support through the standard peripheral + * library. (See note in README). */ - #include "stm32f2xx.h" - #include "stm32f2xx_hash.h" int wc_InitSha(Sha* sha) { - /* STM32F2 struct notes: + /* STM32 struct notes: * sha->buffer = first 4 bytes used to hold partial block if needed * sha->buffLen = num bytes currently stored in sha->buffer * sha->loLen = num bytes that have been written to STM32 FIFO diff --git a/wolfssl/wolfcrypt/des3.h b/wolfssl/wolfcrypt/des3.h index 07ddb1aaa..db12cc900 100644 --- a/wolfssl/wolfcrypt/des3.h +++ b/wolfssl/wolfcrypt/des3.h @@ -58,7 +58,7 @@ enum { #define DES3_KEYLEN 24 -#ifdef STM32F2_CRYPTO +#if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) enum { DES_CBC = 0, DES_ECB = 1 diff --git a/wolfssl/wolfcrypt/md5.h b/wolfssl/wolfcrypt/md5.h index bed0b984c..17783b173 100644 --- a/wolfssl/wolfcrypt/md5.h +++ b/wolfssl/wolfcrypt/md5.h @@ -40,7 +40,7 @@ /* in bytes */ enum { -#ifdef STM32F2_HASH +#if defined(STM32F2_HASH) || defined(STM32F4_HASH) MD5_REG_SIZE = 4, /* STM32 register size, bytes */ #endif MD5 = 0, /* hash type unique */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index cd269517a..5346dbf09 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -922,10 +922,48 @@ static char *fgets(char *buff, int sz, FILE *fp) #define SIZEOF_LONG_LONG 8 #define NO_DEV_RANDOM #define NO_WOLFSSL_DIR + #undef NO_RABBIT #define NO_RABBIT #define STM32F2_RNG #define STM32F2_CRYPTO - #define KEIL_INTRINSICS + #ifndef __GNUC__ + #define KEIL_INTRINSICS + #endif + #define NO_OLD_RNGNAME + #ifdef WOLFSSL_STM32_CUBEMX + #include "stm32f2xx_hal.h" + #ifndef STM32_HAL_TIMEOUT + #define STM32_HAL_TIMEOUT 0xFF + #endif + #else + #include "stm32f2xx.h" + #include "stm32f2xx_cryp.h" + #include "stm32f2xx_hash.h" + #endif /* WOLFSSL_STM32_CUBEMX */ +#endif + +#ifdef WOLFSSL_STM32F4 + #define SIZEOF_LONG_LONG 8 + #define NO_DEV_RANDOM + #define NO_WOLFSSL_DIR + #undef NO_RABBIT + #define NO_RABBIT + #define STM32F4_RNG + #define STM32F4_CRYPTO + #define NO_OLD_RNGNAME + #ifndef __GNUC__ + #define KEIL_INTRINSICS + #endif + #ifdef WOLFSSL_STM32_CUBEMX + #include "stm32f4xx_hal.h" + #ifndef STM32_HAL_TIMEOUT + #define STM32_HAL_TIMEOUT 0xFF + #endif + #else + #include "stm32f4xx.h" + #include "stm32f4xx_cryp.h" + #include "stm32f4xx_hash.h" + #endif /* WOLFSSL_STM32_CUBEMX */ #endif #ifdef MICRIUM diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index b107f08b5..6dbd91b87 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -43,7 +43,7 @@ #ifndef HAVE_FIPS /* avoid redefining structs */ /* in bytes */ enum { -#ifdef STM32F2_HASH +#if defined(STM32F2_HASH) || defined(STM32F4_HASH) SHA_REG_SIZE = 4, /* STM32 register size, bytes */ #endif SHA = 1, /* hash type unique */ From 932199c5e9833c9d9fae0a92a336eabab8888c1b Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 2 Nov 2016 10:13:15 -0700 Subject: [PATCH 03/16] Fix build warning about unused static functions wc_AesEncrypt and wc_AesDecrypt with STM32. --- wolfcrypt/src/aes.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 2f007eeb5..5df7ca393 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -204,8 +204,7 @@ void wc_AesAsyncFree(Aes* aes) #if defined(STM32F2_CRYPTO) || defined(STM32F4_CRYPTO) /* STM32F2/F4 hardware AES support for CBC, CTR modes */ -#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) ||\ - defined(HAVE_AESGCM) +#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM) static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { int ret = 0; @@ -322,10 +321,10 @@ void wc_AesAsyncFree(Aes* aes) #endif /* WOLFSSL_STM32_CUBEMX */ return ret; } -#endif /* AES_CBC or AES_DIRECT or AESGCM */ +#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */ #ifdef HAVE_AES_DECRYPT - #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) + #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { int ret = 0; @@ -365,7 +364,7 @@ void wc_AesAsyncFree(Aes* aes) #endif /* WOLFSSL_STM32_CUBEMX */ return ret; } - #endif /* AES_CBC or AES_DIRECT */ + #endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM */ #endif /* HAVE_AES_DECRYPT */ #elif defined(HAVE_COLDFIRE_SEC) From 9fcb6e4e3c8e82b15f790aeb3f3e12ceb5a6016a Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Dec 2016 10:25:56 -0800 Subject: [PATCH 04/16] Remove obsolete duplicate declaration for wc_RsaFunction in the KSDK port header. --- wolfssl/wolfcrypt/port/nxp/ksdk_port.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wolfssl/wolfcrypt/port/nxp/ksdk_port.h b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h index d6acdd764..5b2673a45 100755 --- a/wolfssl/wolfcrypt/port/nxp/ksdk_port.h +++ b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h @@ -41,10 +41,6 @@ int ksdk_port_init(void); int wolfcrypt_fp_invmod(fp_int *a, fp_int *b, fp_int *c); int _wolfcrypt_fp_exptmod(fp_int *G, fp_int *X, fp_int *P, fp_int *Y); int _fp_exptmod(fp_int *G, fp_int *X, fp_int *P, fp_int *Y); - #ifndef NO_RSA - #include - int wc_RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng); - #endif #endif /* FREESCALE_LTC_TFM */ #if defined(FREESCALE_LTC_ECC) From c0e006d42cb85a0463e72cf32b0e76f4d6b35889 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Dec 2016 12:38:05 -0800 Subject: [PATCH 05/16] Fixes for build with small stack enabled. --- wolfcrypt/src/hmac.c | 4 ++-- wolfcrypt/src/pkcs7.c | 18 +++++++++--------- wolfcrypt/src/sha256.c | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 910309542..a699b6542 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -873,8 +873,8 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, } #ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(prk, hmac->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmp, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(prk, myHmac.heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 67a6151d2..b80b634ef 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1425,7 +1425,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) WOLFSSL_MSG("Failed to create RecipientInfo"); wc_FreeRng(&rng); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return recipSz; } @@ -1436,7 +1436,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) wc_FreeRng(&rng); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -1445,7 +1445,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType); if (contentTypeSz == 0) { #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return BAD_FUNC_ARG; } @@ -1457,7 +1457,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) plain = (byte*)XMALLOC(desOutSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return MEMORY_E; } @@ -1472,7 +1472,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) if (encryptedContent == NULL) { XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return MEMORY_E; } @@ -1489,7 +1489,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return BAD_FUNC_ARG; } @@ -1502,7 +1502,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } @@ -1537,7 +1537,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return BUFFER_E; } @@ -1577,7 +1577,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK - XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); + XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return idx; diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 97697c26b..e0d986546 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -1760,10 +1760,10 @@ static int Transform_AVX2(Sha256* sha256) RegToDigest(S_0,S_1,S_2,S_3,S_4,S_5,S_6,S_7) ; - #ifdef WOLFSSL_SMALL_STACK - XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - +#ifdef WOLFSSL_SMALL_STACK + XFREE(W_K, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return 0; } From 944e5fba03582d5ac60ce5c044a8daeb27dfe1bf Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 6 Dec 2016 21:42:15 +0000 Subject: [PATCH 06/16] ARMv8 : load pointer to AES key and counter into a register along with pointer to SHA256 K table to handle tight optimized loops on function call with -flto --- wolfcrypt/src/port/arm/armv8-aes.c | 73 ++++++++++++++------------- wolfcrypt/src/port/arm/armv8-sha256.c | 6 ++- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 13e106159..e59bd2571 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -476,6 +476,8 @@ int wc_InitAes_h(Aes* aes, void* h) /* do as many block size ops as possible */ if (numBlocks > 0) { + word32* key = aes->key; + word32* reg = aes->reg; /* AESE exor's input with round key shift rows of exor'ed result @@ -487,10 +489,10 @@ int wc_InitAes_h(Aes* aes, void* h) case 10: /* AES 128 BLOCK */ __asm__ __volatile__ ( "MOV w11, %w[blocks] \n" - "LD1 {v1.2d-v4.2d}, %[Key], #64 \n" - "LD1 {v5.2d-v8.2d}, %[Key], #64 \n" - "LD1 {v9.2d-v11.2d},%[Key], #48 \n" - "LD1 {v0.2d}, %[reg] \n" + "LD1 {v1.2d-v4.2d}, [%[Key]], #64 \n" + "LD1 {v5.2d-v8.2d}, [%[Key]], #64 \n" + "LD1 {v9.2d-v11.2d},[%[Key]], #48 \n" + "LD1 {v0.2d}, [%[reg]] \n" "LD1 {v12.2d}, [%[input]], #16 \n" "1:\n" @@ -525,11 +527,11 @@ int wc_InitAes_h(Aes* aes, void* h) "2:\n" "#store current counter value at the end \n" - "ST1 {v0.2d}, %[regOut] \n" + "ST1 {v0.2d}, [%[regOut]] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) - :"0" (out), [Key] "m" (aes->key), [input] "2" (in), - [blocks] "r" (numBlocks), [reg] "m" (aes->reg) + :[out] "=r" (out), [regOut] "=r" (reg), "=r" (in) + :"0" (out), [Key] "r" (key), [input] "2" (in), + [blocks] "r" (numBlocks), [reg] "1" (reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13" ); @@ -675,14 +677,17 @@ int wc_InitAes_h(Aes* aes, void* h) /* do as many block size ops as possible */ if (numBlocks > 0) { + word32* key = aes->key; + word32* reg = aes->reg; + switch(aes->rounds) { case 10: /* AES 128 BLOCK */ __asm__ __volatile__ ( "MOV w11, %w[blocks] \n" - "LD1 {v1.2d-v4.2d}, %[Key], #64 \n" - "LD1 {v5.2d-v8.2d}, %[Key], #64 \n" - "LD1 {v9.2d-v11.2d},%[Key], #48 \n" - "LD1 {v13.2d}, %[reg] \n" + "LD1 {v1.2d-v4.2d}, [%[Key]], #64 \n" + "LD1 {v5.2d-v8.2d}, [%[Key]], #64 \n" + "LD1 {v9.2d-v11.2d},[%[Key]], #48 \n" + "LD1 {v13.2d}, [%[reg]] \n" "1:\n" "LD1 {v0.2d}, [%[input]], #16 \n" @@ -718,11 +723,11 @@ int wc_InitAes_h(Aes* aes, void* h) "2: \n" "#store current counter value at the end \n" - "ST1 {v13.2d}, %[regOut] \n" + "ST1 {v13.2d}, [%[regOut]] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) - :"0" (out), [Key] "m" (aes->key), [input] "2" (in), - [blocks] "r" (numBlocks), [reg] "m" (aes->reg) + :[out] "=r" (out), [regOut] "=r" (reg), "=r" (in) + :"0" (out), [Key] "r" (key), [input] "2" (in), + [blocks] "r" (numBlocks), [reg] "1" (reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13" ); @@ -731,11 +736,11 @@ int wc_InitAes_h(Aes* aes, void* h) case 12: /* AES 192 BLOCK */ __asm__ __volatile__ ( "MOV w11, %w[blocks] \n" - "LD1 {v1.2d-v4.2d}, %[Key], #64 \n" - "LD1 {v5.2d-v8.2d}, %[Key], #64 \n" - "LD1 {v9.2d-v12.2d},%[Key], #64 \n" - "LD1 {v13.16b}, %[Key], #16 \n" - "LD1 {v15.2d}, %[reg] \n" + "LD1 {v1.2d-v4.2d}, [%[Key]], #64 \n" + "LD1 {v5.2d-v8.2d}, [%[Key]], #64 \n" + "LD1 {v9.2d-v12.2d},[%[Key]], #64 \n" + "LD1 {v13.16b}, [%[Key]], #16 \n" + "LD1 {v15.2d}, [%[reg]] \n" "LD1 {v0.2d}, [%[input]], #16 \n" "1: \n" @@ -776,11 +781,11 @@ int wc_InitAes_h(Aes* aes, void* h) "2:\n" "#store current counter value at the end \n" - "ST1 {v15.2d}, %[regOut] \n" + "ST1 {v15.2d}, [%[regOut]] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) - :"0" (out), [Key] "m" (aes->key), [input] "2" (in), - [blocks] "r" (numBlocks), [reg] "m" (aes->reg) + :[out] "=r" (out), [regOut] "=r" (reg), "=r" (in) + :"0" (out), [Key] "r" (key), [input] "2" (in), + [blocks] "r" (numBlocks), [reg] "1" (reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15" ); @@ -789,11 +794,11 @@ int wc_InitAes_h(Aes* aes, void* h) case 14: /* AES 256 BLOCK */ __asm__ __volatile__ ( "MOV w11, %w[blocks] \n" - "LD1 {v1.2d-v4.2d}, %[Key], #64 \n" - "LD1 {v5.2d-v8.2d}, %[Key], #64 \n" - "LD1 {v9.2d-v12.2d}, %[Key], #64 \n" - "LD1 {v13.2d-v15.2d}, %[Key], #48 \n" - "LD1 {v17.2d}, %[reg] \n" + "LD1 {v1.2d-v4.2d}, [%[Key]], #64 \n" + "LD1 {v5.2d-v8.2d}, [%[Key]], #64 \n" + "LD1 {v9.2d-v12.2d}, [%[Key]], #64 \n" + "LD1 {v13.2d-v15.2d}, [%[Key]], #48 \n" + "LD1 {v17.2d}, [%[reg]] \n" "LD1 {v0.2d}, [%[input]], #16 \n" "1: \n" @@ -838,11 +843,11 @@ int wc_InitAes_h(Aes* aes, void* h) "2:\n" "#store current counter value at the end \n" - "ST1 {v17.2d}, %[regOut] \n" + "ST1 {v17.2d}, [%[regOut]] \n" - :[out] "=r" (out), [regOut] "=m" (aes->reg), "=r" (in) - :"0" (out), [Key] "m" (aes->key), [input] "2" (in), - [blocks] "r" (numBlocks), [reg] "m" (aes->reg) + :[out] "=r" (out), [regOut] "=r" (reg), "=r" (in) + :"0" (out), [Key] "r" (key), [input] "2" (in), + [blocks] "r" (numBlocks), [reg] "1" (reg) : "cc", "memory", "w11", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14","v15", "v16", "v17" diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 06bc6897c..fdf2634bf 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -133,6 +133,8 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) numBlocks = (len + sha256->buffLen)/SHA256_BLOCK_SIZE; if (numBlocks > 0) { + word32* k = (word32*)K; + /* get leftover amount after blocks */ add = (len + sha256->buffLen) - numBlocks * SHA256_BLOCK_SIZE; __asm__ volatile ( @@ -300,8 +302,8 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) "STP q12, q13, %[out] \n" : [out] "=m" (sha256->digest), "=m" (sha256->buffer), "=r" (numBlocks), - "=r" (data) - : [k] "r" (K), [digest] "m" (sha256->digest), [buffer] "m" (sha256->buffer), + "=r" (data), "=r" (k) + : [k] "4" (k), [digest] "m" (sha256->digest), [buffer] "m" (sha256->buffer), [blocks] "2" (numBlocks), [dataIn] "3" (data) : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", From fdc297f6bd8695684180c995a52a8664ab888b88 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 6 Dec 2016 16:15:45 -0800 Subject: [PATCH 07/16] Moved the check for the size of long, long long, and __m128 to before the checks for libraries. In some combination of autotools, making a 32-bit build, the autoconf test code can't link libnetwork and crashes, leaving those sizes all set to 0. --- configure.ac | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index ee8d9822c..cc8d85808 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,13 @@ AS_IF([ test -n "$CFLAG_VISIBILITY" ], [ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) +# Moved these size of and type checks before the library checks. +# The library checks add the library to subsequent test compiles +# and in some rare cases, the networking check causes these sizeof +# checks to fail. +AC_CHECK_SIZEOF(long long, 8) +AC_CHECK_SIZEOF(long, 4) +AC_CHECK_TYPES(__uint128_t) AC_CHECK_FUNCS([gethostbyname]) AC_CHECK_FUNCS([getaddrinfo]) AC_CHECK_FUNCS([gettimeofday]) @@ -85,9 +92,6 @@ AC_CHECK_HEADERS([sys/socket.h]) AC_CHECK_HEADERS([sys/time.h]) AC_CHECK_HEADERS([errno.h]) AC_CHECK_LIB(network,socket) -AC_CHECK_SIZEOF(long long, 8) -AC_CHECK_SIZEOF(long, 4) -AC_CHECK_TYPES(__uint128_t) AC_C_BIGENDIAN # mktime check takes forever on some systems, if time supported it would be # highly unusual for mktime to be missing From eaca90db286065ed671aa298baf2645de44ffa97 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 29 Aug 2016 10:02:06 -0700 Subject: [PATCH 08/16] New Atmel support (WOLFSSL_ATMEL) and port for ATECC508A (WOLFSSL_ATECC508A). Adds wolfCrypt support for ECC Hardware acceleration using the ATECC508A. Adds new PK callback for ECC shared secret. Fixed missing "wc_InitRng_ex" when using "CUSTOM_RAND_GENERATE_BLOCK". Added ATECC508A RNG block function for P-RNG bypass ability. Added internal "wolfSSL_GetEccPrivateKey" function for getting reference to private key for ECC shared secret (used in test.h for testing PK_CALLBACK mode). Added README.md for using the Atmel ATECC508A port. --- src/internal.c | 391 ++++++++++++++++----------- src/io.c | 2 + src/ssl.c | 65 +++++ wolfcrypt/benchmark/benchmark.c | 3 +- wolfcrypt/src/asn.c | 10 +- wolfcrypt/src/ecc.c | 258 ++++++++++++++++-- wolfcrypt/src/include.am | 4 +- wolfcrypt/src/port/atmel/README.md | 8 + wolfcrypt/src/port/atmel/atmel.c | 244 +++++++++++++++++ wolfcrypt/src/random.c | 17 ++ wolfcrypt/src/wc_port.c | 10 +- wolfssl/internal.h | 5 +- wolfssl/ssl.h | 10 + wolfssl/test.h | 62 +++++ wolfssl/wolfcrypt/ecc.h | 33 ++- wolfssl/wolfcrypt/include.am | 3 +- wolfssl/wolfcrypt/port/atmel/atmel.h | 66 +++++ 17 files changed, 1006 insertions(+), 185 deletions(-) mode change 100644 => 100755 wolfcrypt/src/asn.c create mode 100644 wolfcrypt/src/port/atmel/README.md create mode 100755 wolfcrypt/src/port/atmel/atmel.c mode change 100644 => 100755 wolfcrypt/src/random.c create mode 100755 wolfssl/wolfcrypt/port/atmel/atmel.h diff --git a/src/internal.c b/src/internal.c index ef62d7dc0..fde5d6ee6 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2966,15 +2966,29 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, } int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, - byte* out, word32* outSz) + byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen, + int side, void* ctx) { int ret; (void)ssl; + (void)pubKeyDer; + (void)pubKeySz; + (void)side; + (void)ctx; WOLFSSL_ENTER("EccSharedSecret"); - ret = wc_ecc_shared_secret(priv_key, pub_key, out, outSz); +#ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb) { + ret = ssl->ctx->EccSharedSecretCb(ssl, pubKeyDer, pubKeySz, + out, outlen, side, ctx); + } + else +#endif + { + ret = wc_ecc_shared_secret(priv_key, pub_key, out, outlen); + } /* Handle async pending response */ #if defined(WOLFSSL_ASYNC_CRYPT) @@ -15437,20 +15451,25 @@ int SendClientKeyExchange(WOLFSSL* ssl) ERROR_OUT(NO_PEER_KEY, exit_scke); } - /* create private key */ - ssl->sigKey = XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->sigKey == NULL) { - ERROR_OUT(MEMORY_E, exit_scke); - } - ssl->sigType = DYNAMIC_TYPE_ECC; + #ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb == NULL) + #endif + { + /* create private key */ + ssl->sigKey = XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + ssl->sigType = DYNAMIC_TYPE_ECC; - ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_scke; + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_scke; + } + ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey); } - ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey); break; #endif /* HAVE_ECC && !NO_PSK */ #ifdef HAVE_NTRU @@ -15463,41 +15482,46 @@ int SendClientKeyExchange(WOLFSSL* ssl) #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - ecc_key* peerKey; + #ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb == NULL) + #endif + { + ecc_key* peerKey; - if (ssl->specs.static_ecdh) { - /* TODO: EccDsa is really fixed Ecc change naming */ - if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || - !ssl->peerEccDsaKey->dp) { + if (ssl->specs.static_ecdh) { + /* TODO: EccDsa is really fixed Ecc change naming */ + if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || + !ssl->peerEccDsaKey->dp) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + peerKey = ssl->peerEccDsaKey; + } + else { + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + peerKey = ssl->peerEccKey; + } + if (peerKey == NULL) { ERROR_OUT(NO_PEER_KEY, exit_scke); } - peerKey = ssl->peerEccDsaKey; - } - else { - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { - ERROR_OUT(NO_PEER_KEY, exit_scke); + + /* create private key */ + ssl->sigKey = XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); } - peerKey = ssl->peerEccKey; - } - if (peerKey == NULL) { - ERROR_OUT(NO_PEER_KEY, exit_scke); - } + ssl->sigType = DYNAMIC_TYPE_ECC; - /* create private key */ - ssl->sigKey = XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->sigKey == NULL) { - ERROR_OUT(MEMORY_E, exit_scke); + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_scke; + } + ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey); } - ssl->sigType = DYNAMIC_TYPE_ECC; - - ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_scke; - } - ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey); break; } #endif /* HAVE_ECC */ @@ -15649,21 +15673,20 @@ int SendClientKeyExchange(WOLFSSL* ssl) output += esSz; encSz = esSz + OPAQUE16_LEN; - /* Place ECC key in output buffer, leaving room for size */ + /* length is used for public key size */ *length = MAX_ENCRYPT_SZ; - ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, - output + 1, length); - if (ret != 0) { - ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + + #ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb == NULL) + #endif + { + /* Place ECC key in buffer, leaving room for size */ + ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, + output + OPAQUE8_LEN, length); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + } } - - *output = (byte)*length; /* place size of key in output buffer */ - encSz += *length + 1; - - /* Create shared ECC key leaving room at the begining - of buffer for size of shared key. Note sizeof - preMasterSecret is ENCRYPT_LEN currently 512 */ - *length = sizeof(ssl->arrays->preMasterSecret) - OPAQUE16_LEN; break; } #endif /* HAVE_ECC && !NO_PSK */ @@ -15684,18 +15707,17 @@ int SendClientKeyExchange(WOLFSSL* ssl) #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - /* precede export with 1 byte length */ - *length = MAX_ENCRYPT_SZ; - ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, - encSecret + 1, length); - if (ret != 0) { - ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + #ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb == NULL) + #endif + { + /* Place ECC key in buffer, leaving room for size */ + ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, + encSecret + OPAQUE8_LEN, &encSz); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + } } - - encSecret[0] = (byte)*length; - encSz = *length + 1; - - *length = sizeof(ssl->arrays->preMasterSecret); break; } #endif /* HAVE_ECC */ @@ -15778,10 +15800,22 @@ int SendClientKeyExchange(WOLFSSL* ssl) #if defined(HAVE_ECC) && !defined(NO_PSK) case ecdhe_psk_kea: { - ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey, - ssl->peerEccKey, + /* Create shared ECC key leaving room at the begining + of buffer for size of shared key. */ + ssl->arrays->preMasterSz = ENCRYPT_LEN - OPAQUE16_LEN; + + ret = EccSharedSecret(ssl, + (ecc_key*)ssl->sigKey, ssl->peerEccKey, + output + OPAQUE8_LEN, length, ssl->arrays->preMasterSecret + OPAQUE16_LEN, - length); + &ssl->arrays->preMasterSz, + WOLFSSL_CLIENT_END, + #ifdef HAVE_PK_CALLBACKS + ssl->EccSharedSecretCtx + #else + NULL + #endif + ); break; } #endif /* HAVE_ECC && !NO_PSK */ @@ -15815,8 +15849,20 @@ int SendClientKeyExchange(WOLFSSL* ssl) ecc_key* peerKey = (ssl->specs.static_ecdh) ? ssl->peerEccDsaKey : ssl->peerEccKey; - ret = EccSharedSecret(ssl, (ecc_key*)ssl->sigKey, peerKey, - ssl->arrays->preMasterSecret, length); + ssl->arrays->preMasterSz = ENCRYPT_LEN; + + ret = EccSharedSecret(ssl, + (ecc_key*)ssl->sigKey, peerKey, + encSecret + OPAQUE8_LEN, &encSz, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + WOLFSSL_CLIENT_END, + #ifdef HAVE_PK_CALLBACKS + ssl->EccSharedSecretCtx + #else + NULL + #endif + ); break; } #endif /* HAVE_ECC */ @@ -15861,6 +15907,11 @@ int SendClientKeyExchange(WOLFSSL* ssl) { byte* pms = ssl->arrays->preMasterSecret; + /* validate args */ + if (output == NULL || *length == 0) { + ERROR_OUT(BAD_FUNC_ARG, exit_scke); + } + c16toa((word16)*length, output); encSz += *length + OPAQUE16_LEN; c16toa((word16)ssl->arrays->preMasterSz, pms); @@ -15884,10 +15935,19 @@ int SendClientKeyExchange(WOLFSSL* ssl) { byte* pms = ssl->arrays->preMasterSecret; + /* validate args */ + if (output == NULL || *length > ENCRYPT_LEN) { + ERROR_OUT(BAD_FUNC_ARG, exit_scke); + } + + /* place size of public key in output buffer */ + *output = (byte)*length; + encSz += *length + OPAQUE8_LEN; + /* Create pre master secret is the concatination of eccSize + eccSharedKey + pskSize + pskKey */ - c16toa((word16)*length, pms); - ssl->arrays->preMasterSz += OPAQUE16_LEN + *length; + c16toa((word16)ssl->arrays->preMasterSz, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN; pms += ssl->arrays->preMasterSz; c16toa((word16)ssl->arrays->psk_keySz, pms); @@ -15910,7 +15970,9 @@ int SendClientKeyExchange(WOLFSSL* ssl) #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - ssl->arrays->preMasterSz = *length; + /* place size of public key in buffer */ + *encSecret = (byte)encSz; + encSz += OPAQUE8_LEN; break; } #endif /* HAVE_ECC */ @@ -19839,11 +19901,6 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - if (!ssl->specs.static_ecdh && - ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); - } break; } #endif /* HAVE_ECC */ @@ -19872,11 +19929,6 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_MSG("No server PSK callback set"); ERROR_OUT(PSK_KEY_ERROR, exit_dcke); } - - if (ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); - } break; } #endif /* HAVE_ECC && !NO_PSK */ @@ -20093,42 +20145,47 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ERROR_OUT(BUFFER_ERROR, exit_dcke); } - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); + #ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb == NULL) + #endif + { + if (!ssl->specs.static_ecdh && + ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } + if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - ERROR_OUT(MEMORY_E, exit_dcke); + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dcke); + } + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; - } - } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; + + if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, + private_key->dp->id)) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); } + + ssl->peerEccKeyPresent = 1; } - if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, - private_key->dp->id)) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); - } - - idx += length; - ssl->peerEccKeyPresent = 1; - - ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); - - if (ret != 0) { - goto exit_dcke; - } break; } #endif /* HAVE_ECC */ @@ -20229,42 +20286,45 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ERROR_OUT(BUFFER_ERROR, exit_dcke); } - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); + #ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->EccSharedSecretCb == NULL) + #endif + { + if (ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } + if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - ERROR_OUT(MEMORY_E, exit_dcke); + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dcke); + } + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; + else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } } - } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; + + if (wc_ecc_import_x963_ex(input + idx, length, + ssl->peerEccKey, ssl->eccTempKey->dp->id)) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); } - } - if (wc_ecc_import_x963_ex(input + idx, length, - ssl->peerEccKey, ssl->eccTempKey->dp->id)) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); - } - idx += length; - ssl->peerEccKeyPresent = 1; - - /* Note sizeof preMasterSecret is ENCRYPT_LEN currently 512 */ - ssl->sigLen = sizeof(ssl->arrays->preMasterSecret); - - if (ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + ssl->peerEccKeyPresent = 1; } break; } @@ -20325,9 +20385,21 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, private_key = (ecc_key*)ssl->sigKey; } + ssl->arrays->preMasterSz = ENCRYPT_LEN; + /* Generate shared secret */ - ret = EccSharedSecret(ssl, private_key, ssl->peerEccKey, - ssl->arrays->preMasterSecret, &ssl->sigLen); + ret = EccSharedSecret(ssl, + private_key, ssl->peerEccKey, + input + idx, &length, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + WOLFSSL_SERVER_END, + #ifdef HAVE_PK_CALLBACKS + ssl->EccSharedSecretCtx + #else + NULL + #endif + ); break; } #endif /* HAVE_ECC */ @@ -20377,12 +20449,21 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #if defined(HAVE_ECC) && !defined(NO_PSK) case ecdhe_psk_kea: { + ssl->sigLen = ENCRYPT_LEN - OPAQUE16_LEN; + /* Generate shared secret */ ret = EccSharedSecret(ssl, - ssl->eccTempKey, - ssl->peerEccKey, + ssl->eccTempKey, ssl->peerEccKey, + input + idx, &length, ssl->arrays->preMasterSecret + OPAQUE16_LEN, - &ssl->sigLen); + &ssl->sigLen, + WOLFSSL_SERVER_END, + #ifdef HAVE_PK_CALLBACKS + ssl->EccSharedSecretCtx + #else + NULL + #endif + ); break; } #endif /* HAVE_ECC && !NO_PSK */ @@ -20436,7 +20517,8 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - ssl->arrays->preMasterSz = ssl->sigLen; + /* skip past the imported peer key */ + idx += length; break; } #endif /* HAVE_ECC */ @@ -20483,6 +20565,9 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { byte* pms = ssl->arrays->preMasterSecret; + /* skip past the imported peer key */ + idx += length; + /* Add preMasterSecret */ c16toa((word16)ssl->sigLen, pms); ssl->arrays->preMasterSz += OPAQUE16_LEN + ssl->sigLen; diff --git a/src/io.c b/src/io.c index c861350d1..bbfd971af 100644 --- a/src/io.c +++ b/src/io.c @@ -80,6 +80,8 @@ #elif defined(WOLFSSL_VXWORKS) #include #include + #elif defined(WOLFSSL_ATMEL) + #include "socket/include/socket.h" #else #include #include diff --git a/src/ssl.c b/src/ssl.c index c02016ed9..f82a6cf46 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -958,6 +958,51 @@ int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz) ssl->options.minEccKeySz = keySz / 8; return SSL_SUCCESS; } + +/* Gets ECC key for shared secret callback testing + * Client side: returns peer key + * Server side: returns private key + */ +int wolfSSL_GetEccKey(WOLFSSL* ssl, struct ecc_key** key) +{ + if (ssl == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + if (ssl->options.side == WOLFSSL_CLIENT_END) { + if (ssl->specs.static_ecdh) { + if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || + !ssl->peerEccDsaKey->dp) { + return NO_PEER_KEY; + } + *key = (struct ecc_key*)ssl->peerEccDsaKey; + } + else { + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + return NO_PEER_KEY; + } + *key = (struct ecc_key*)ssl->peerEccKey; + } + } + else if (ssl->options.side == WOLFSSL_SERVER_END) { + if (ssl->specs.static_ecdh) { + if (ssl->sigKey == NULL) { + return NO_PRIVATE_KEY; + } + *key = (struct ecc_key*)ssl->sigKey; + } + else { + if (!ssl->eccTempKeyPresent) { + return NO_PRIVATE_KEY; + } + *key = (struct ecc_key*)ssl->eccTempKey; + } + } + + return 0; +} + #endif /* !NO_RSA */ #ifndef NO_RSA @@ -18202,6 +18247,26 @@ void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl) return NULL; } +void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb) +{ + if (ctx) + ctx->EccSharedSecretCb = cb; +} + +void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->EccSharedSecretCtx = ctx; +} + + +void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->EccSharedSecretCtx; + + return NULL; +} #endif /* HAVE_ECC */ #ifndef NO_RSA diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 87f92c720..07a488f58 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -2530,7 +2530,8 @@ void bench_ed25519KeySign(void) } #elif defined(WOLFSSL_IAR_ARM_TIME) || defined (WOLFSSL_MDK_ARM) || defined(WOLFSSL_USER_CURRTIME) - extern double current_time(int reset); + /* declared above at line 189 */ + /* extern double current_time(int reset); */ #elif defined FREERTOS diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c old mode 100644 new mode 100755 index 84b4d8813..28e3cb02a --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -149,10 +149,16 @@ ASN Options: #elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) #include #ifndef XTIME - #define XTIME(t1) 0 + #define XTIME(t1) ksdk_time((t1)) #endif #define XGMTIME(c, t) gmtime((c)) +#elif defined(WOLFSSL_ATMEL) + #define XTIME(t1) atmel_get_curr_time_and_date((t1)) + #define WOLFSSL_GMTIME + #define USE_WOLF_TM + #define USE_WOLF_TIME_T + #elif defined(IDIRECT_DEV_TIME) /*Gets the timestamp from cloak software owned by VT iDirect in place of time() from */ @@ -224,6 +230,8 @@ ASN Options: #elif defined(TIME_OVERRIDES) extern time_t XTIME(time_t * timer); extern struct tm* XGMTIME(const time_t* timer, struct tm* tmp); +#elif defined(WOLFSSL_GMTIME) + struct tm* gmtime(const time_t* timer); #endif diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 4e53d8938..142f94e32 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -918,6 +918,12 @@ const ecc_set_type ecc_sets[] = { static oid_cache_t ecc_oid_cache[sizeof(ecc_sets)/sizeof(ecc_set_type)]; #endif +#ifdef HAVE_COMP_KEY +static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); +#endif + +#ifndef WOLFSSL_ATECC508A + int ecc_map(ecc_point*, mp_int*, mp_digit); int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, mp_int* a, mp_int* modulus, mp_digit mp); @@ -932,9 +938,7 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB, int mp_jacobi(mp_int* a, mp_int* n, int* c); int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); -#ifdef HAVE_COMP_KEY -static int wc_ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); -#endif +#endif /* WOLFSSL_ATECC508A */ static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) @@ -972,6 +976,7 @@ static int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id) return 0; } +#ifndef WOLFSSL_ATECC508A /* helper for either lib */ static int get_digit_count(mp_int* a) @@ -2263,6 +2268,9 @@ int wc_ecc_cmp_point(ecc_point* a, ecc_point *b) return MP_EQ; } +#endif /* !WOLFSSL_ATECC508A */ + + /** Returns whether an ECC idx is valid or not n The idx number to check return 1 if valid, 0 if not @@ -2295,11 +2303,13 @@ int wc_ecc_is_valid_idx(int n) int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen) { + int err = 0; +#ifndef WOLFSSL_ATECC508A word32 x = 0; ecc_point* result; mp_int prime; mp_int a; - int err; +#endif /* !WOLFSSL_ATECC508A */ if (private_key == NULL || public_key == NULL || out == NULL || outlen == NULL) { @@ -2340,6 +2350,15 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, } #endif +#ifdef WOLFSSL_ATECC508A + err = atcatls_ecdh(private_key->slot, public_key->pubkey, out); + if (err != ATCA_SUCCESS) { + err = BAD_COND_E; + } + *outlen = private_key->dp->size; + +#else + /* make new point */ result = wc_ecc_new_point_h(private_key->heap); if (result == NULL) { @@ -2379,9 +2398,13 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, #endif wc_ecc_del_point_h(result, private_key->heap); +#endif /* WOLFSSL_ATECC508A */ + return err; } +#ifndef WOLFSSL_ATECC508A + /** Create an ECC shared secret between private key and public point private_key The private ECC key (heap hint based on private key) @@ -2455,8 +2478,10 @@ int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, return err; } +#endif /* !WOLFSSL_ATECC508A */ #endif /* HAVE_ECC_DHE */ +#ifndef WOLFSSL_ATECC508A /* return 1 if point is at infinity, 0 if not, < 0 on error */ int wc_ecc_point_is_at_infinity(ecc_point* p) { @@ -2469,10 +2494,13 @@ int wc_ecc_point_is_at_infinity(ecc_point* p) return 0; } +#endif /* WOLFSSL_ATECC508A */ + int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) { int err; +#ifndef WOLFSSL_ATECC508A ecc_point* base = NULL; mp_int prime; mp_int a; @@ -2482,6 +2510,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) #else byte buf[ECC_MAXSIZE_GEN]; #endif +#endif /* !WOLFSSL_ATECC508A */ if (key == NULL || rng == NULL) { return BAD_FUNC_ARG; @@ -2510,6 +2539,15 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) } #endif +#ifdef WOLFSSL_ATECC508A + key->type = ECC_PRIVATEKEY; + err = atcatls_create_key(key->slot, key->pubkey); + if (err != ATCA_SUCCESS) { + err = BAD_COND_E; + } + +#else + #ifdef WOLFSSL_SMALL_STACK buf = (byte*)XMALLOC(ECC_MAXSIZE_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) @@ -2628,6 +2666,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) #ifdef WOLFSSL_SMALL_STACK XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif +#endif /* WOLFSSL_ATECC508A */ return err; } @@ -2721,6 +2760,13 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) key->dp = NULL; key->idx = 0; +#ifdef WOLFSSL_ATECC508A + key->slot = atmel_ecc_alloc(); + if (key->slot == ATECC_INVALID_SLOT) { + return ECC_BAD_ARG_E; + } +#else + #ifndef USE_FAST_MATH key->pubkey.x->dp = NULL; key->pubkey.y->dp = NULL; @@ -2742,6 +2788,8 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId) alt_fp_init(key->pubkey.z); #endif +#endif /* WOLFSSL_ATECC508A */ + #ifdef WOLFSSL_HEAP_TEST key->heap = (void*)WOLFSSL_HEAP_TEST; #else @@ -2810,16 +2858,61 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, } #endif + /* is this a private key? */ + if (key->type != ECC_PRIVATEKEY) + return ECC_BAD_ARG_E; + + /* is the IDX valid ? */ + if (wc_ecc_is_valid_idx(key->idx) != 1) + return ECC_BAD_ARG_E; + if ((err = mp_init_multi(&r, &s, NULL, NULL, NULL, NULL)) != MP_OKAY) { return err; } - err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s); - if (err == MP_OKAY) { - /* encoded with DSA header */ - err = StoreECC_DSA_Sig(out, outlen, &r, &s); +#ifdef WOLFSSL_ATECC508A + /* Check args */ + if (inlen != ATECC_KEY_SIZE || *outlen < SIGN_RSP_SIZE) { + err = ECC_BAD_ARG_E; + goto exit_sign; } + /* Sign: Result is 32-bytes of R then 32-bytes of S */ + err = atcatls_sign(key->slot, in, out); + if (err != ATCA_SUCCESS) { + err = BAD_COND_E; + goto exit_sign; + } + + /* Load R and S */ + err = mp_read_unsigned_bin(&r, &out[0], ATECC_KEY_SIZE); + if (err != MP_OKAY) { + goto exit_sign; + } + err = mp_read_unsigned_bin(&s, &out[ATECC_KEY_SIZE], ATECC_KEY_SIZE); + if (err != MP_OKAY) { + goto exit_sign; + } + + /* Check for zeros */ + if (mp_iszero(&r) || mp_iszero(&s)) { + err = MP_ZERO_E; + goto exit_sign; + } + +#else + + err = wc_ecc_sign_hash_ex(in, inlen, rng, key, &r, &s); + if (err != MP_OKAY) { + goto exit_sign; + } + + err = StoreECC_DSA_Sig(out, outlen, &r, &s); + +#endif /* WOLFSSL_ATECC508A */ + +exit_sign: + #ifndef USE_FAST_MATH mp_clear(&r); mp_clear(&s); @@ -2829,6 +2922,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, } #endif /* !NO_ASN */ +#ifndef WOLFSSL_ATECC508A + /** Sign a message digest in The message digest to sign @@ -2937,6 +3032,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return err; } +#endif /* !WOLFSSL_ATECC508A */ #endif /* HAVE_ECC_SIGN */ /** @@ -2955,13 +3051,20 @@ void wc_ecc_free(ecc_key* key) } #endif +#ifdef WOLFSSL_ATECC508A + atmel_ecc_free(key->slot); + key->slot = -1; +#else + mp_clear(key->pubkey.x); mp_clear(key->pubkey.y); mp_clear(key->pubkey.z); mp_forcezero(&key->k); +#endif /* !WOLFSSL_ATECC508A */ } +#ifndef WOLFSSL_ATECC508A #ifdef ECC_SHAMIR /** Computes kA*A + kB*B = C using Shamir's Trick @@ -3187,8 +3290,8 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, return err; } - #endif /* ECC_SHAMIR */ +#endif /* !WOLFSSL_ATECC508A */ #ifdef HAVE_ECC_VERIFY @@ -3219,6 +3322,9 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, mp_int r; mp_int s; int err; +#ifdef WOLFSSL_ATECC508A + byte sigRS[ATECC_KEY_SIZE*2]; +#endif if (sig == NULL || hash == NULL || stat == NULL || key == NULL) { return ECC_BAD_ARG_E; @@ -3255,9 +3361,33 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, XMEMSET(&s, 0, sizeof(s)); err = DecodeECC_DSA_Sig(sig, siglen, &r, &s); + if (err != 0) { + goto exit_verify; + } - if (err == MP_OKAY) - err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key); +#ifdef WOLFSSL_ATECC508A + /* Extract R and S */ + err = mp_to_unsigned_bin(&r, &sigRS[0]); + if (err != MP_OKAY) { + goto exit_verify; + } + err = mp_to_unsigned_bin(&s, &sigRS[ATECC_KEY_SIZE]); + if (err != MP_OKAY) { + goto exit_verify; + } + + err = atcatls_verify(hash, sigRS, key->pubkey, (bool*)stat); + if (err != ATCA_SUCCESS) { + err = BAD_COND_E; + } + +#else + + err = wc_ecc_verify_hash_ex(&r, &s, hash, hashlen, stat, key); + +#endif /* WOLFSSL_ATECC508A */ + +exit_verify: #ifndef USE_FAST_MATH mp_clear(&r); @@ -3268,6 +3398,9 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, } #endif /* !NO_ASN */ + +#ifndef WOLFSSL_ATECC508A + /** Verify an ECC signature r The signature R component to verify @@ -3442,9 +3575,11 @@ done: return err; } +#endif /* !WOLFSSL_ATECC508A */ #endif /* HAVE_ECC_VERIFY */ #ifdef HAVE_ECC_KEY_IMPORT +#ifndef WOLFSSL_ATECC508A /* import point from der */ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, ecc_point* point) @@ -3567,6 +3702,7 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, return err; } +#endif /* !WOLFSSL_ATECC508A */ #endif /* HAVE_ECC_KEY_IMPORT */ #ifdef HAVE_ECC_KEY_EXPORT @@ -3574,13 +3710,15 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, word32* outLen) { + int ret = MP_OKAY; + word32 numlen; +#ifndef WOLFSSL_ATECC508A #ifdef WOLFSSL_SMALL_STACK byte* buf; #else byte buf[ECC_BUFSIZE]; #endif - word32 numlen; - int ret = MP_OKAY; +#endif /* !WOLFSSL_ATECC508A */ if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0)) return ECC_BAD_ARG_E; @@ -3602,6 +3740,12 @@ int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, return BUFFER_E; } +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + ret = BAD_COND_E; + +#else + /* store byte 0x04 */ out[0] = 0x04; @@ -3633,6 +3777,7 @@ done: #ifdef WOLFSSL_SMALL_STACK XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif +#endif /* WOLFSSL_ATECC508A */ return ret; } @@ -3641,13 +3786,15 @@ done: /* export public ECC key in ANSI X9.63 format */ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) { + word32 numlen; + int ret = MP_OKAY; +#ifndef WOLFSSL_ATECC508A #ifdef WOLFSSL_SMALL_STACK byte* buf; #else byte buf[ECC_BUFSIZE]; #endif - word32 numlen; - int ret = MP_OKAY; +#endif /* return length needed only */ if (key != NULL && out == NULL && outLen != NULL) { @@ -3669,6 +3816,12 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) return BUFFER_E; } +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + ret = BAD_COND_E; + +#else + /* store byte 0x04 */ out[0] = 0x04; @@ -3700,6 +3853,7 @@ done: #ifdef WOLFSSL_SMALL_STACK XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif +#endif /* WOLFSSL_ATECC508A */ return ret; } @@ -3722,6 +3876,8 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, #endif /* HAVE_ECC_KEY_EXPORT */ +#ifndef WOLFSSL_ATECC508A + /* is ecc point on curve described by dp ? */ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime) { @@ -3815,9 +3971,9 @@ static int ecc_is_point(const ecc_set_type* dp, ecc_point* ecp, mp_int* prime) /* validate privkey * generator == pubkey, 0 on success */ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) { + int err = MP_OKAY; ecc_point* base = NULL; ecc_point* res = NULL; - int err; if (key == NULL) return BAD_FUNC_ARG; @@ -3863,13 +4019,21 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) /* check privkey generator helper, creates prime needed */ static int ecc_check_privkey_gen_helper(ecc_key* key) { + int err = MP_OKAY; +#ifndef WOLFSSL_ATECC508A mp_int prime; mp_int a; - int err; +#endif /* !WOLFSSL_ATECC508A */ if (key == NULL) return BAD_FUNC_ARG; +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + err = BAD_COND_E; + +#else + err = mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL); if (err != MP_OKAY) return err; @@ -3886,6 +4050,7 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) mp_clear(&prime); mp_clear(&a); #endif +#endif /* WOLFSSL_ATECC508A */ return err; } @@ -3918,18 +4083,28 @@ static int ecc_check_pubkey_order(ecc_key* key, mp_int* a, mp_int* prime, return err; } +#endif /* !WOLFSSL_ATECC508A */ + /* perform sanity checks on ecc key validity, 0 on success */ int wc_ecc_check_key(ecc_key* key) { + int err = MP_OKAY; +#ifndef WOLFSSL_ATECC508A mp_int prime; /* used by multiple calls so let's cache */ mp_int a; mp_int order; /* other callers have, so let's gen here */ - int err; +#endif /* !WOLFSSL_ATECC508A */ if (key == NULL) return BAD_FUNC_ARG; +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + err = BAD_COND_E; + +#else + /* pubkey point cannot be at infinity */ if (wc_ecc_point_is_at_infinity(&key->pubkey)) return ECC_INF_E; @@ -3963,6 +4138,7 @@ int wc_ecc_check_key(ecc_key* key) mp_clear(&a); mp_clear(&prime); #endif +#endif /* WOLFSSL_ATECC508A */ return err; } @@ -3972,8 +4148,10 @@ int wc_ecc_check_key(ecc_key* key) int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, int curve_id) { - int err; + int err = MP_OKAY; +#ifndef WOLFSSL_ATECC508A int compressed = 0; +#endif /* !WOLFSSL_ATECC508A */ if (in == NULL || key == NULL) return BAD_FUNC_ARG; @@ -3983,6 +4161,12 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, return ECC_BAD_ARG_E; } +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + err = BAD_COND_E; + +#else + /* init key */ #ifdef ALT_ECC_SIZE key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; @@ -4107,6 +4291,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, mp_clear(key->pubkey.z); mp_clear(&key->k); } +#endif /* WOLFSSL_ATECC508A */ return err; } @@ -4140,8 +4325,15 @@ int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) *outLen = numlen; XMEMSET(out, 0, *outLen); +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + return BAD_COND_E; + +#else + return mp_to_unsigned_bin(&key->k, out + (numlen - mp_unsigned_bin_size(&key->k))); +#endif /* WOLFSSL_ATECC508A */ } #endif /* HAVE_ECC_KEY_EXPORT */ @@ -4155,8 +4347,16 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, const byte* pu key->type = ECC_PRIVATEKEY; +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + return BAD_COND_E; + +#else + ret = mp_read_unsigned_bin(&key->k, priv, privSz); +#endif /* WOLFSSL_ATECC508A */ + #ifdef WOLFSSL_VALIDATE_ECC_IMPORT if (ret == MP_OKAY) ret = ecc_check_privkey_gen_helper(key); @@ -4222,7 +4422,7 @@ int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, const char* qy, const char* d, int curve_id) { - int err; + int err = MP_OKAY; if (key == NULL || qx == NULL || qy == NULL || d == NULL) { return BAD_FUNC_ARG; @@ -4234,6 +4434,12 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, return err; } +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + err = BAD_COND_E; + +#else + /* init key */ #ifdef ALT_ECC_SIZE key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; @@ -4278,6 +4484,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, mp_clear(key->pubkey.z); mp_clear(&key->k); } +#endif /* WOLFSSL_ATECC508A */ return err; } @@ -6373,6 +6580,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, #ifdef HAVE_COMP_KEY +#ifndef WOLFSSL_ATECC508A /* computes the jacobi c = (a | n) (or Legendre if n is prime) * HAC pp. 73 Algorithm 2.149 @@ -6664,6 +6872,7 @@ int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) return res; } +#endif /* !WOLFSSL_ATECC508A */ /* export public ECC key in ANSI X9.63 format compressed */ @@ -6685,6 +6894,12 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen return BUFFER_E; } +#ifdef WOLFSSL_ATECC508A + /* TODO: Implement equiv call to ATECC508A */ + ret = BAD_COND_E; + +#else + /* store first byte */ out[0] = mp_isodd(key->pubkey.y) == MP_YES ? 0x03 : 0x02; @@ -6693,6 +6908,9 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen ret = mp_to_unsigned_bin(key->pubkey.x, out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x))); *outLen = 1 + numlen; + +#endif /* WOLFSSL_ATECC508A */ + return ret; } diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 5c76a03b6..9a3ce0a3b 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -47,7 +47,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/nrf51.c \ wolfcrypt/src/port/arm/armv8-aes.c \ wolfcrypt/src/port/arm/armv8-sha256.c \ - wolfssl/wolfcrypt/port/nxp/ksdk_port.c + wolfssl/wolfcrypt/port/nxp/ksdk_port.c \ + wolfcrypt/src/port/atmel/atmel.c \ + wolfcrypt/src/port/atmel/README.md if BUILD_CAVIUM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c diff --git a/wolfcrypt/src/port/atmel/README.md b/wolfcrypt/src/port/atmel/README.md new file mode 100644 index 000000000..00f527507 --- /dev/null +++ b/wolfcrypt/src/port/atmel/README.md @@ -0,0 +1,8 @@ +# Atmel ATECC508A Port + +* Adds wolfCrypt support for ECC Hardware acceleration using the ATECC508A + * The new defines added for this port are: `WOLFSSL_ATMEL` and `WOLFSSL_ATECC508A`. +* Adds new PK callback for Pre Master Secret. + + +For details see our [wolfSSL Atmel ATECC508A](wolfhttps://wolfssl.com/wolfSSL/wolfssl-atmel.html) page. diff --git a/wolfcrypt/src/port/atmel/atmel.c b/wolfcrypt/src/port/atmel/atmel.c new file mode 100755 index 000000000..4c5ed0dcc --- /dev/null +++ b/wolfcrypt/src/port/atmel/atmel.c @@ -0,0 +1,244 @@ +/* atmel.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLFSSL_ATMEL + +#include +#include +#include +#include + +#define Aes Aes_Remap +#define Gmac Gmac_Remap +#include "asf.h" +#undef Aes +#undef Gmac + +#include + +static bool mAtcaInitDone = 0; + +#ifdef WOLFSSL_ATECC508A + +/* List of available key slots */ +static int mSlotList[ATECC_MAX_SLOT+1]; + +/** + * \brief Structure to contain certificate information. + */ +t_atcert atcert = { + .signer_ca_size = 512, + .signer_ca = { 0 }, + .signer_ca_pubkey = { 0 }, + .end_user_size = 512, + .end_user = { 0 }, + .end_user_pubkey = { 0 } +}; + +static int atmel_init_enc_key(void); + +#endif /* WOLFSSL_ATECC508A */ + + +/** + * \brief Generate random number to be used for hash. + */ +int atmel_get_random_number(uint32_t count, uint8_t* rand_out) +{ + int ret = 0; +#ifdef WOLFSSL_ATECC508A + uint8_t i = 0; + uint32_t copy_count = 0; + uint8_t rng_buffer[RANDOM_NUM_SIZE]; + + if (rand_out == NULL) { + return -1; + } + + while(i < count) { + + ret = atcatls_random(rng_buffer); + if (ret != 0) { + WOLFSSL_MSG("Failed to create random number!"); + return -1; + } + copy_count = (count - i > RANDOM_NUM_SIZE) ? RANDOM_NUM_SIZE : count - i; + XMEMCPY(&rand_out[i], rng_buffer, copy_count); + i += copy_count; + } + atcab_printbin_label((const uint8_t*)"\r\nRandom Number", rand_out, count); +#else + // TODO: Use on-board TRNG +#endif + return ret; +} + +int atmel_get_random_block(unsigned char* output, unsigned int sz) +{ + return atmel_get_random_number((uint32_t)sz, (uint8_t*)output); +} + +extern struct rtc_module *_rtc_instance[RTC_INST_NUM]; +long atmel_get_curr_time_and_date(long* tm) +{ + (void)tm; + + /* Get current time */ + //struct rtc_calendar_time rtcTime; + //rtc_calendar_get_time(_rtc_instance[0], &rtcTime); + + /* Convert rtc_calendar_time to seconds since UTC */ + + return 0; +} + + + +#ifdef WOLFSSL_ATECC508A + +/* Function to allocate new slot number */ +int atmel_ecc_alloc(void) +{ + int i, slot = -1; + for (i=0; i <= ATECC_MAX_SLOT; i++) { + /* Find free slot */ + if (mSlotList[i] == ATECC_INVALID_SLOT) { + mSlotList[i] = i; + slot = i; + break; + } + } + return slot; +} + + +/* Function to return slot number to avail list */ +void atmel_ecc_free(int slot) +{ + if (slot >= 0 && slot <= ATECC_MAX_SLOT) { + /* Mark slot of free */ + mSlotList[slot] = ATECC_INVALID_SLOT; + } +} + + +/** + * \brief Give enc key to read pms. + */ +static int atmel_set_enc_key(uint8_t* enckey, int16_t keysize) +{ + if (enckey == NULL || keysize != ATECC_KEY_SIZE) { + return -1; + } + + XMEMSET(enckey, 0xFF, keysize); // use default values + + return SSL_SUCCESS; +} + + +/** + * \brief Write enc key before. + */ +static int atmel_init_enc_key(void) +{ + uint8_t ret = 0; + uint8_t read_key[ATECC_KEY_SIZE] = { 0 }; + + XMEMSET(read_key, 0xFF, sizeof(read_key)); + ret = atcab_write_bytes_slot(0x04, 0, read_key, sizeof(read_key)); + if (ret != ATCA_SUCCESS) { + WOLFSSL_MSG("Failed to write key"); + return -1; + } + + ret = atcatlsfn_set_get_enckey(atmel_set_enc_key); + if (ret != ATCA_SUCCESS) { + WOLFSSL_MSG("Failed to set enckey"); + return -1; + } + + return ret; +} + +static void atmel_show_rev_info(void) +{ +#if 0 + uint32_t revision = 0; + atcab_info((uint8_t*)&revision); + printf("ATECC508A Revision: %x\n", (unsigned int)revision); +#endif +} + +#endif /* WOLFSSL_ATECC508A */ + + + +void atmel_init(void) +{ + if (!mAtcaInitDone) { +#ifdef WOLFSSL_ATECC508A + int i; + + /* Init the free slot list */ + for (i=0; i<=ATECC_MAX_SLOT; i++) { + if (i == 0 || i == 2 || i == 7) { + /* ECC Slots (mark avail) */ + mSlotList[i] = ATECC_INVALID_SLOT; + } + else { + mSlotList[i] = i; + } + } + + /* Initialize the CryptoAuthLib to communicate with ATECC508A */ + atcatls_init(&cfg_ateccx08a_i2c_default); + + /* Init the I2C pipe encryption key. */ + /* Value is generated/stored during pair for the ATECC508A and stored + on micro flash */ + /* For this example its a fixed value */ + if (atmel_init_enc_key() != ATCA_SUCCESS) { + WOLFSSL_MSG("Failed to initialize transport key"); + } + + /* show revision information */ + atmel_show_rev_info(); + + /* Configure the ECC508 for use with TLS API funcitons */ + #if 0 + atcatls_device_provision(); + #else + atcatls_config_default(); + #endif +#endif /* WOLFSSL_ATECC508A */ + + mAtcaInitDone = 1; + } +} + +#endif /* WOLFSSL_ATMEL */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c old mode 100644 new mode 100755 index b953e2dd7..df0512196 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -1619,6 +1619,23 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } +#elif defined(WOLFSSL_ATMEL) + #include + + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + int ret = 0; + + (void)os; + if (output == NULL) { + return BUFFER_E; + } + + ret = atmel_get_random_number(sz, output); + + return ret; + } + #elif defined(NO_DEV_RANDOM) #error "you need to write an os specific wc_GenerateSeed() here" diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 5e3c32a49..669298cb6 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -39,6 +39,10 @@ #include #endif +#ifdef WOLFSSL_ATMEL + #include +#endif + #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */ #pragma warning(disable: 4996) @@ -50,7 +54,7 @@ static volatile int initRefCount = 0; /* Used to initialize state for wolfcrypt return 0 on success */ -int wolfCrypt_Init() +int wolfCrypt_Init(void) { int ret = 0; @@ -77,6 +81,10 @@ int wolfCrypt_Init() ksdk_port_init(); #endif + #ifdef WOLFSSL_ATMEL + atmel_init(); + #endif + #ifdef WOLFSSL_ARMASM WOLFSSL_MSG("Using ARM hardware acceleration"); #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2ecbd06ce..3859c1534 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2036,6 +2036,7 @@ struct WOLFSSL_CTX { #ifdef HAVE_ECC CallbackEccSign EccSignCb; /* User EccSign Callback handler */ CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */ + CallbackEccSharedSecret EccSharedSecretCb; /* User EccVerify Callback handler */ #endif /* HAVE_ECC */ #ifndef NO_RSA CallbackRsaSign RsaSignCb; /* User RsaSign Callback handler */ @@ -2850,6 +2851,7 @@ struct WOLFSSL { #ifdef HAVE_ECC void* EccSignCtx; /* Ecc Sign Callback Context */ void* EccVerifyCtx; /* Ecc Verify Callback Context */ + void* EccSharedSecretCtx; /* Ecc Pms Callback Context */ #endif /* HAVE_ECC */ #ifndef NO_RSA void* RsaSignCtx; /* Rsa Sign Callback Context */ @@ -3044,7 +3046,8 @@ WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); const byte* out, word32 outSz, ecc_key* key, byte* keyBuf, word32 keySz, void* ctx); WOLFSSL_LOCAL int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, - ecc_key* pub_key, byte* out, word32* outSz); + ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out, + word32* outlen, int side, void* ctx); #endif /* HAVE_ECC */ #ifdef WOLFSSL_TRUST_PEER_CERT diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 839200393..e574697bb 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1043,6 +1043,8 @@ WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, short); #ifdef HAVE_ECC WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short); WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short); +struct ecc_key; +WOLFSSL_API int wolfSSL_GetEccKey(WOLFSSL*, struct ecc_key**); #endif /* NO_RSA */ WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short); @@ -1341,6 +1343,14 @@ WOLFSSL_API void wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX*, CallbackEccVerify); WOLFSSL_API void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl); +typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ +WOLFSSL_API void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX*, CallbackEccSharedSecret); +WOLFSSL_API void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl); + typedef int (*CallbackRsaSign)(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz, unsigned char* out, unsigned int* outSz, diff --git a/wolfssl/test.h b/wolfssl/test.h index a488418f1..9eb46cbfd 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1705,6 +1705,67 @@ static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz, return ret; } +static INLINE int myEccSharedSecret(WOLFSSL* ssl, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx) +{ + int ret; + ecc_key* privKey; + ecc_key* pubKey; + ecc_key tmpKey; + + (void)ssl; + (void)ctx; + + ret = wc_ecc_init(&tmpKey); + if (ret != 0) { + return ret; + } + + /* for client: create and export public key */ + if (side == WOLFSSL_CLIENT_END) { + WC_RNG rng; + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wolfSSL_GetEccKey(ssl, &pubKey); + if (ret != 0) { + return ret; + } + privKey = &tmpKey; + + ret = wc_ecc_make_key_ex(&rng, 0, privKey, pubKey->dp->id); + if (ret == 0) { + ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); + } + wc_FreeRng(&rng); + } + } + + /* for server: import public key */ + else if (side == WOLFSSL_SERVER_END) { + ret = wolfSSL_GetEccKey(ssl, &privKey); + if (ret != 0) { + return ret; + } + pubKey = &tmpKey; + + ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, privKey->dp->id); + } + else { + ret = -1; + } + + /* generate shared secret and return it */ + if (ret == 0) { + ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); + } + + wc_ecc_free(&tmpKey); + + return ret; +} + #endif /* HAVE_ECC */ #ifndef NO_RSA @@ -1834,6 +1895,7 @@ static INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx, WOLFSSL* ssl) #ifdef HAVE_ECC wolfSSL_CTX_SetEccSignCb(ctx, myEccSign); wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify); + wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret); #endif /* HAVE_ECC */ #ifndef NO_RSA wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 7c25c13cf..2ae7d2a45 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -34,6 +34,11 @@ #include #endif +#ifdef WOLFSSL_ATECC508A + #include +#endif /* WOLFSSL_ATECC508A */ + + #ifdef __cplusplus extern "C" { #endif @@ -205,7 +210,7 @@ typedef struct alt_fp_int { int used, sign, size; fp_digit dp[FP_SIZE_ECC]; } alt_fp_int; -#endif +#endif /* ALT_ECC_SIZE */ /* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpreted as affine */ @@ -224,16 +229,21 @@ typedef struct { /* An ECC Key */ -typedef struct { +typedef struct ecc_key { int type; /* Public or Private */ int idx; /* Index into the ecc_sets[] for the parameters of this curve if -1, this key is using user supplied curve in dp */ const ecc_set_type* dp; /* domain parameters, either points to NIST curves (idx >= 0) or user supplied */ + void* heap; /* heap hint */ +#ifdef WOLFSSL_ATECC508A + int slot; /* Key Slot Number (-1 unknown) */ + byte pubkey[PUB_KEY_SIZE]; +#else ecc_point pubkey; /* public key */ mp_int k; /* private key */ - void* heap; /* heap hint */ +#endif #ifdef WOLFSSL_ASYNC_CRYPT AsyncCryptDev asyncDev; @@ -257,9 +267,11 @@ int wc_ecc_check_key(ecc_key* key); WOLFSSL_API int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen); +#ifndef WOLFSSL_ATECC508A WOLFSSL_API int wc_ecc_shared_secret_ssh(ecc_key* private_key, ecc_point* point, byte* out, word32 *outlen); +#endif /* !WOLFSSL_ATECC508A */ #endif /* HAVE_ECC_DHE */ #ifdef HAVE_ECC_SIGN @@ -289,6 +301,11 @@ void wc_ecc_free(ecc_key* key); WOLFSSL_API void wc_ecc_fp_free(void); +WOLFSSL_API +int wc_ecc_is_valid_idx(int n); + +#ifndef WOLFSSL_ATECC508A + WOLFSSL_API ecc_point* wc_ecc_new_point(void); WOLFSSL_API @@ -304,14 +321,14 @@ int wc_ecc_cmp_point(ecc_point* a, ecc_point *b); WOLFSSL_API int wc_ecc_point_is_at_infinity(ecc_point *p); WOLFSSL_API -int wc_ecc_is_valid_idx(int n); -WOLFSSL_API int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map); - WOLFSSL_LOCAL int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap); +#endif /* !WOLFSSL_ATECC508A */ + + #ifdef HAVE_ECC_KEY_EXPORT /* ASN key helpers */ WOLFSSL_API @@ -346,12 +363,16 @@ int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy, #ifdef HAVE_ECC_KEY_EXPORT WOLFSSL_API int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen); +#endif /* HAVE_ECC_KEY_EXPORT */ + +#ifdef HAVE_ECC_KEY_EXPORT WOLFSSL_API int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out, word32* outLen); #endif /* HAVE_ECC_KEY_EXPORT */ + #ifdef HAVE_ECC_KEY_IMPORT WOLFSSL_API int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 4dddbc687..7c9c0fb7f 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -65,7 +65,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/ti/ti-hash.h \ wolfssl/wolfcrypt/port/ti/ti-ccm.h \ wolfssl/wolfcrypt/port/nrf51.h \ - wolfssl/wolfcrypt/port/nxp/ksdk_port.h + wolfssl/wolfcrypt/port/nxp/ksdk_port.h \ + wolfssl/wolfcrypt/port/atmel/atmel.h if BUILD_CAVIUM noinst_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h diff --git a/wolfssl/wolfcrypt/port/atmel/atmel.h b/wolfssl/wolfcrypt/port/atmel/atmel.h new file mode 100755 index 000000000..99532dbad --- /dev/null +++ b/wolfssl/wolfcrypt/port/atmel/atmel.h @@ -0,0 +1,66 @@ +/* atecc508.h + * + * Copyright (C) 2006-2016 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _ATECC508_H_ +#define _ATECC508_H_ + +#include + +#ifdef WOLFSSL_ATECC508A + #undef SHA_BLOCK_SIZE + #define SHA_BLOCK_SIZE SHA_BLOCK_SIZE_REMAP + #include + #include + #include + #include + #undef SHA_BLOCK_SIZE +#endif + +/* ATECC508A only supports ECC-256 */ +#define ATECC_KEY_SIZE (32) +#define ATECC_MAX_SLOT (0x7) /* Only use 0-7 */ +#define ATECC_INVALID_SLOT (-1) + +struct WOLFSSL; +struct WOLFSSL_X509_STORE_CTX; + +// Cert Structure +typedef struct t_atcert { + uint32_t signer_ca_size; + uint8_t signer_ca[512]; + uint8_t signer_ca_pubkey[64]; + uint32_t end_user_size; + uint8_t end_user[512]; + uint8_t end_user_pubkey[64]; +} t_atcert; + +extern t_atcert atcert; + + +/* Amtel port functions */ +void atmel_init(void); +int atmel_get_random_number(uint32_t count, uint8_t* rand_out); +long atmel_get_curr_time_and_date(long* tm); + +int atmel_ecc_alloc(void); +void atmel_ecc_free(int slot); + +#endif /* _ATECC508_H_ */ From 45d26876c88b02028e28d070e0b2864d02055bd4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 5 Dec 2016 11:36:53 -0800 Subject: [PATCH 09/16] Moved wolfSSL_GetEccKey logic to internal.c and use only for PK_CALLBACK. Added other ECC key info to the EccSharedSecretCb. Cleanup of the "if (ssl->ctx->EccSharedSecretCb == NULL)" logic to revert indent so changes are minimized. Removed new wolfSSL_GetEccKey API. --- src/internal.c | 366 +++++++++++++++++++++++++++++-------------------- src/ssl.c | 44 ------ wolfssl/ssl.h | 4 +- wolfssl/test.h | 51 +++---- 4 files changed, 249 insertions(+), 216 deletions(-) diff --git a/src/internal.c b/src/internal.c index fde5d6ee6..5e8933532 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2965,6 +2965,62 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, return ret; } +#ifdef HAVE_PK_CALLBACKS + /* Gets ECC key for shared secret callback testing + * Client side: returns peer key + * Server side: returns private key + */ + static int EccGetKey(WOLFSSL* ssl, byte* otherKeyDer, + word32* otherKeySz, word32* otherKeyId) + { + int ret = NO_PEER_KEY; + ecc_key* otherKey = NULL; + + if (ssl == NULL || otherKeyDer == NULL || otherKeySz == NULL) { + return BAD_FUNC_ARG; + } + + if (ssl->options.side == WOLFSSL_CLIENT_END) { + if (ssl->specs.static_ecdh) { + if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || + !ssl->peerEccDsaKey->dp) { + return NO_PEER_KEY; + } + otherKey = (struct ecc_key*)ssl->peerEccDsaKey; + } + else { + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + return NO_PEER_KEY; + } + otherKey = (struct ecc_key*)ssl->peerEccKey; + } + } + else if (ssl->options.side == WOLFSSL_SERVER_END) { + if (ssl->specs.static_ecdh) { + if (ssl->sigKey == NULL) { + return NO_PRIVATE_KEY; + } + otherKey = (struct ecc_key*)ssl->sigKey; + } + else { + if (!ssl->eccTempKeyPresent) { + return NO_PRIVATE_KEY; + } + otherKey = (struct ecc_key*)ssl->eccTempKey; + } + } + + if (otherKey) { + ret = wc_ecc_export_x963(otherKey, otherKeyDer, otherKeySz); + if (otherKeyId) + *otherKeyId = otherKey->dp->id; + } + + return ret; + } +#endif /* HAVE_PK_CALLBACKS */ + int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, byte* pubKeyDer, word32* pubKeySz, byte* out, word32* outlen, int side, void* ctx) @@ -2981,8 +3037,15 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->EccSharedSecretCb) { - ret = ssl->ctx->EccSharedSecretCb(ssl, pubKeyDer, pubKeySz, - out, outlen, side, ctx); + byte* otherKeyDer = NULL; + word32 otherKeySz = 0; + word32 otherKeyId = ECC_CURVE_DEF; + + ret = EccGetKey(ssl, otherKeyDer, &otherKeySz, &otherKeyId); + if (ret == 0) { + ret = ssl->ctx->EccSharedSecretCb(ssl, otherKeyDer, otherKeySz, + otherKeyId, pubKeyDer, pubKeySz, out, outlen, side, ctx); + } } else #endif @@ -15452,24 +15515,27 @@ int SendClientKeyExchange(WOLFSSL* ssl) } #ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb == NULL) - #endif - { - /* create private key */ - ssl->sigKey = XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->sigKey == NULL) { - ERROR_OUT(MEMORY_E, exit_scke); - } - ssl->sigType = DYNAMIC_TYPE_ECC; - - ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_scke; - } - ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, ssl->peerEccKey); + /* if callback then use it for shared secret */ + if (ssl->ctx->EccSharedSecretCb != NULL) { + break; } + #endif + + /* create private key */ + ssl->sigKey = XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + ssl->sigType = DYNAMIC_TYPE_ECC; + + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_scke; + } + ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, + ssl->peerEccKey); break; #endif /* HAVE_ECC && !NO_PSK */ #ifdef HAVE_NTRU @@ -15482,46 +15548,49 @@ int SendClientKeyExchange(WOLFSSL* ssl) #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { - #ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb == NULL) - #endif - { - ecc_key* peerKey; + ecc_key* peerKey; - if (ssl->specs.static_ecdh) { - /* TODO: EccDsa is really fixed Ecc change naming */ - if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || - !ssl->peerEccDsaKey->dp) { - ERROR_OUT(NO_PEER_KEY, exit_scke); - } - peerKey = ssl->peerEccDsaKey; - } - else { - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { - ERROR_OUT(NO_PEER_KEY, exit_scke); - } - peerKey = ssl->peerEccKey; - } - if (peerKey == NULL) { + #ifdef HAVE_PK_CALLBACKS + /* if callback then use it for shared secret */ + if (ssl->ctx->EccSharedSecretCb != NULL) { + break; + } + #endif + + if (ssl->specs.static_ecdh) { + /* TODO: EccDsa is really fixed Ecc change naming */ + if (!ssl->peerEccDsaKey || + !ssl->peerEccDsaKeyPresent || + !ssl->peerEccDsaKey->dp) { ERROR_OUT(NO_PEER_KEY, exit_scke); } - - /* create private key */ - ssl->sigKey = XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->sigKey == NULL) { - ERROR_OUT(MEMORY_E, exit_scke); - } - ssl->sigType = DYNAMIC_TYPE_ECC; - - ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_scke; - } - ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey); + peerKey = ssl->peerEccDsaKey; } + else { + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + peerKey = ssl->peerEccKey; + } + if (peerKey == NULL) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + + /* create private key */ + ssl->sigKey = XMALLOC(sizeof(ecc_key), + ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->sigKey == NULL) { + ERROR_OUT(MEMORY_E, exit_scke); + } + ssl->sigType = DYNAMIC_TYPE_ECC; + + ret = wc_ecc_init_ex((ecc_key*)ssl->sigKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_scke; + } + ret = EccMakeKey(ssl, (ecc_key*)ssl->sigKey, peerKey); break; } #endif /* HAVE_ECC */ @@ -15677,15 +15746,17 @@ int SendClientKeyExchange(WOLFSSL* ssl) *length = MAX_ENCRYPT_SZ; #ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb == NULL) + /* if callback then use it for shared secret */ + if (ssl->ctx->EccSharedSecretCb != NULL) { + break; + } #endif - { - /* Place ECC key in buffer, leaving room for size */ - ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, - output + OPAQUE8_LEN, length); - if (ret != 0) { - ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); - } + + /* Place ECC key in buffer, leaving room for size */ + ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, + output + OPAQUE8_LEN, length); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); } break; } @@ -15708,15 +15779,17 @@ int SendClientKeyExchange(WOLFSSL* ssl) case ecc_diffie_hellman_kea: { #ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb == NULL) + /* if callback then use it for shared secret */ + if (ssl->ctx->EccSharedSecretCb != NULL) { + break; + } #endif - { - /* Place ECC key in buffer, leaving room for size */ - ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, - encSecret + OPAQUE8_LEN, &encSz); - if (ret != 0) { - ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); - } + + /* Place ECC key in buffer, leaving room for size */ + ret = wc_ecc_export_x963((ecc_key*)ssl->sigKey, + encSecret + OPAQUE8_LEN, &encSz); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); } break; } @@ -20146,46 +20219,47 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb == NULL) + /* if callback then use it for shared secret */ + if (ssl->ctx->EccSharedSecretCb != NULL) { + break; + } #endif - { - if (!ssl->specs.static_ecdh && - ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); - } - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - ERROR_OUT(MEMORY_E, exit_dcke); - } - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; - } - } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; - } - } - - if (wc_ecc_import_x963_ex(input + idx, length, ssl->peerEccKey, - private_key->dp->id)) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); - } - - ssl->peerEccKeyPresent = 1; + if (!ssl->specs.static_ecdh && + ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); } + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC( + sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dcke); + } + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } + } + + if (wc_ecc_import_x963_ex(input + idx, length, + ssl->peerEccKey, private_key->dp->id)) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + ssl->peerEccKeyPresent = 1; break; } #endif /* HAVE_ECC */ @@ -20287,45 +20361,47 @@ int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #ifdef HAVE_PK_CALLBACKS - if (ssl->ctx->EccSharedSecretCb == NULL) - #endif - { - if (ssl->eccTempKeyPresent == 0) { - WOLFSSL_MSG("Ecc ephemeral key not made correctly"); - ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); - } - - if (ssl->peerEccKey == NULL) { - /* alloc/init on demand */ - ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), - ssl->heap, DYNAMIC_TYPE_ECC); - if (ssl->peerEccKey == NULL) { - WOLFSSL_MSG("PeerEccKey Memory error"); - ERROR_OUT(MEMORY_E, exit_dcke); - } - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; - } - } - else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ - wc_ecc_free(ssl->peerEccKey); - ssl->peerEccKeyPresent = 0; - ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, - ssl->devId); - if (ret != 0) { - goto exit_dcke; - } - } - - if (wc_ecc_import_x963_ex(input + idx, length, - ssl->peerEccKey, ssl->eccTempKey->dp->id)) { - ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); - } - - ssl->peerEccKeyPresent = 1; + /* if callback then use it for shared secret */ + if (ssl->ctx->EccSharedSecretCb != NULL) { + break; } + #endif + + if (ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } + + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC( + sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + ERROR_OUT(MEMORY_E, exit_dcke); + } + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } + } + else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, + ssl->devId); + if (ret != 0) { + goto exit_dcke; + } + } + + if (wc_ecc_import_x963_ex(input + idx, length, + ssl->peerEccKey, ssl->eccTempKey->dp->id)) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + ssl->peerEccKeyPresent = 1; break; } #endif /* HAVE_ECC && !NO_PSK */ diff --git a/src/ssl.c b/src/ssl.c index f82a6cf46..a865bed42 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -959,50 +959,6 @@ int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz) return SSL_SUCCESS; } -/* Gets ECC key for shared secret callback testing - * Client side: returns peer key - * Server side: returns private key - */ -int wolfSSL_GetEccKey(WOLFSSL* ssl, struct ecc_key** key) -{ - if (ssl == NULL || key == NULL) { - return BAD_FUNC_ARG; - } - - if (ssl->options.side == WOLFSSL_CLIENT_END) { - if (ssl->specs.static_ecdh) { - if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || - !ssl->peerEccDsaKey->dp) { - return NO_PEER_KEY; - } - *key = (struct ecc_key*)ssl->peerEccDsaKey; - } - else { - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { - return NO_PEER_KEY; - } - *key = (struct ecc_key*)ssl->peerEccKey; - } - } - else if (ssl->options.side == WOLFSSL_SERVER_END) { - if (ssl->specs.static_ecdh) { - if (ssl->sigKey == NULL) { - return NO_PRIVATE_KEY; - } - *key = (struct ecc_key*)ssl->sigKey; - } - else { - if (!ssl->eccTempKeyPresent) { - return NO_PRIVATE_KEY; - } - *key = (struct ecc_key*)ssl->eccTempKey; - } - } - - return 0; -} - #endif /* !NO_RSA */ #ifndef NO_RSA diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index e574697bb..f331ff31b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1043,8 +1043,6 @@ WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, short); #ifdef HAVE_ECC WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short); WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short); -struct ecc_key; -WOLFSSL_API int wolfSSL_GetEccKey(WOLFSSL*, struct ecc_key**); #endif /* NO_RSA */ WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short); @@ -1344,6 +1342,8 @@ WOLFSSL_API void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl); typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, + const unsigned char* otherKeyDer, unsigned int otherKeySz, + unsigned int otherKeyId, unsigned char* pubKeyDer, unsigned int* pubKeySz, unsigned char* out, unsigned int* outlen, int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 9eb46cbfd..eb53cae0c 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1706,51 +1706,51 @@ static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz, } static INLINE int myEccSharedSecret(WOLFSSL* ssl, + const unsigned char* otherKeyDer, unsigned int otherKeySz, + unsigned int otherKeyId, unsigned char* pubKeyDer, unsigned int* pubKeySz, unsigned char* out, unsigned int* outlen, int side, void* ctx) { - int ret; - ecc_key* privKey; - ecc_key* pubKey; - ecc_key tmpKey; + int ret; + ecc_key privKey; + ecc_key pubKey; (void)ssl; (void)ctx; - ret = wc_ecc_init(&tmpKey); + ret = wc_ecc_init(&privKey); if (ret != 0) { return ret; } + ret = wc_ecc_init(&pubKey); + if (ret != 0) { + wc_ecc_free(&privKey); + return ret; + } /* for client: create and export public key */ if (side == WOLFSSL_CLIENT_END) { - WC_RNG rng; + WC_RNG rng; ret = wc_InitRng(&rng); if (ret == 0) { - ret = wolfSSL_GetEccKey(ssl, &pubKey); - if (ret != 0) { - return ret; - } - privKey = &tmpKey; - - ret = wc_ecc_make_key_ex(&rng, 0, privKey, pubKey->dp->id); - if (ret == 0) { - ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); - } + ret = wc_ecc_import_x963_ex(otherKeyDer, otherKeySz, &pubKey, + otherKeyId); + if (ret == 0) + ret = wc_ecc_make_key_ex(&rng, 0, &privKey, otherKeyId); + if (ret == 0) + ret = wc_ecc_export_x963(&privKey, pubKeyDer, pubKeySz); wc_FreeRng(&rng); } } /* for server: import public key */ else if (side == WOLFSSL_SERVER_END) { - ret = wolfSSL_GetEccKey(ssl, &privKey); - if (ret != 0) { - return ret; - } - pubKey = &tmpKey; - - ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, privKey->dp->id); + ret = wc_ecc_import_x963_ex(otherKeyDer, otherKeySz, &privKey, + otherKeyId); + if (ret == 0) + ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &pubKey, + otherKeyId); } else { ret = -1; @@ -1758,10 +1758,11 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl, /* generate shared secret and return it */ if (ret == 0) { - ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); + ret = wc_ecc_shared_secret(&privKey, &pubKey, out, outlen); } - wc_ecc_free(&tmpKey); + wc_ecc_free(&privKey); + wc_ecc_free(&pubKey); return ret; } From 4dd393077f340d121b47aab69f3d5699a2d37074 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Dec 2016 13:00:48 -0800 Subject: [PATCH 10/16] Updated EccSharedSecret callback to use ecc_key* peer directly. Passes examples with "-P" tests and new pkcallback test script. --- src/internal.c | 32 ++++++++++++++------------------ wolfssl/ssl.h | 5 ++--- wolfssl/test.h | 41 ++++++++++++++++------------------------- 3 files changed, 32 insertions(+), 46 deletions(-) diff --git a/src/internal.c b/src/internal.c index 5e8933532..83ce2f4a0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2970,13 +2970,12 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, * Client side: returns peer key * Server side: returns private key */ - static int EccGetKey(WOLFSSL* ssl, byte* otherKeyDer, - word32* otherKeySz, word32* otherKeyId) + static int EccGetKey(WOLFSSL* ssl, ecc_key** otherKey) { int ret = NO_PEER_KEY; - ecc_key* otherKey = NULL; + ecc_key* tmpKey = NULL; - if (ssl == NULL || otherKeyDer == NULL || otherKeySz == NULL) { + if (ssl == NULL || otherKey == NULL) { return BAD_FUNC_ARG; } @@ -2986,14 +2985,14 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, !ssl->peerEccDsaKey->dp) { return NO_PEER_KEY; } - otherKey = (struct ecc_key*)ssl->peerEccDsaKey; + tmpKey = (struct ecc_key*)ssl->peerEccDsaKey; } else { if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || !ssl->peerEccKey->dp) { return NO_PEER_KEY; } - otherKey = (struct ecc_key*)ssl->peerEccKey; + tmpKey = (struct ecc_key*)ssl->peerEccKey; } } else if (ssl->options.side == WOLFSSL_SERVER_END) { @@ -3001,20 +3000,19 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out, if (ssl->sigKey == NULL) { return NO_PRIVATE_KEY; } - otherKey = (struct ecc_key*)ssl->sigKey; + tmpKey = (struct ecc_key*)ssl->sigKey; } else { if (!ssl->eccTempKeyPresent) { return NO_PRIVATE_KEY; } - otherKey = (struct ecc_key*)ssl->eccTempKey; + tmpKey = (struct ecc_key*)ssl->eccTempKey; } } - if (otherKey) { - ret = wc_ecc_export_x963(otherKey, otherKeyDer, otherKeySz); - if (otherKeyId) - *otherKeyId = otherKey->dp->id; + if (tmpKey) { + *otherKey = tmpKey; + ret = 0; } return ret; @@ -3037,14 +3035,12 @@ int EccSharedSecret(WOLFSSL* ssl, ecc_key* priv_key, ecc_key* pub_key, #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->EccSharedSecretCb) { - byte* otherKeyDer = NULL; - word32 otherKeySz = 0; - word32 otherKeyId = ECC_CURVE_DEF; + ecc_key* otherKey = NULL; - ret = EccGetKey(ssl, otherKeyDer, &otherKeySz, &otherKeyId); + ret = EccGetKey(ssl, &otherKey); if (ret == 0) { - ret = ssl->ctx->EccSharedSecretCb(ssl, otherKeyDer, otherKeySz, - otherKeyId, pubKeyDer, pubKeySz, out, outlen, side, ctx); + ret = ssl->ctx->EccSharedSecretCb(ssl, otherKey, pubKeyDer, + pubKeySz, out, outlen, side, ctx); } } else diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index f331ff31b..64cfcbb3e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1341,9 +1341,8 @@ WOLFSSL_API void wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX*, CallbackEccVerify); WOLFSSL_API void wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl); -typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, - const unsigned char* otherKeyDer, unsigned int otherKeySz, - unsigned int otherKeyId, +struct ecc_key; +typedef int (*CallbackEccSharedSecret)(WOLFSSL* ssl, struct ecc_key* otherKey, unsigned char* pubKeyDer, unsigned int* pubKeySz, unsigned char* out, unsigned int* outlen, int side, void* ctx); /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ diff --git a/wolfssl/test.h b/wolfssl/test.h index eb53cae0c..632313b8d 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1705,52 +1705,44 @@ static INLINE int myEccVerify(WOLFSSL* ssl, const byte* sig, word32 sigSz, return ret; } -static INLINE int myEccSharedSecret(WOLFSSL* ssl, - const unsigned char* otherKeyDer, unsigned int otherKeySz, - unsigned int otherKeyId, +static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, unsigned char* pubKeyDer, unsigned int* pubKeySz, unsigned char* out, unsigned int* outlen, int side, void* ctx) { - int ret; - ecc_key privKey; - ecc_key pubKey; + int ret; + ecc_key* privKey; + ecc_key* pubKey; + ecc_key tmpKey; (void)ssl; (void)ctx; - ret = wc_ecc_init(&privKey); + ret = wc_ecc_init(&tmpKey); if (ret != 0) { return ret; } - ret = wc_ecc_init(&pubKey); - if (ret != 0) { - wc_ecc_free(&privKey); - return ret; - } /* for client: create and export public key */ if (side == WOLFSSL_CLIENT_END) { WC_RNG rng; ret = wc_InitRng(&rng); if (ret == 0) { - ret = wc_ecc_import_x963_ex(otherKeyDer, otherKeySz, &pubKey, - otherKeyId); + privKey = &tmpKey; + pubKey = otherKey; + ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id); if (ret == 0) - ret = wc_ecc_make_key_ex(&rng, 0, &privKey, otherKeyId); - if (ret == 0) - ret = wc_ecc_export_x963(&privKey, pubKeyDer, pubKeySz); + ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); wc_FreeRng(&rng); } } /* for server: import public key */ else if (side == WOLFSSL_SERVER_END) { - ret = wc_ecc_import_x963_ex(otherKeyDer, otherKeySz, &privKey, - otherKeyId); - if (ret == 0) - ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &pubKey, - otherKeyId); + privKey = otherKey; + pubKey = &tmpKey; + ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, + otherKey->dp->id); } else { ret = -1; @@ -1758,11 +1750,10 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl, /* generate shared secret and return it */ if (ret == 0) { - ret = wc_ecc_shared_secret(&privKey, &pubKey, out, outlen); + ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen); } - wc_ecc_free(&privKey); - wc_ecc_free(&pubKey); + wc_ecc_free(&tmpKey); return ret; } From 5c59ccdeb9f1ef1ca496e124dce7fee1104e3005 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Dec 2016 13:12:18 -0800 Subject: [PATCH 11/16] Fix scan-build warning. Updated "side" variable failure case to return proper error code. --- wolfssl/test.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/wolfssl/test.h b/wolfssl/test.h index 632313b8d..e0a3c1a0e 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1711,8 +1711,8 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, int side, void* ctx) { int ret; - ecc_key* privKey; - ecc_key* pubKey; + ecc_key* privKey = NULL; + ecc_key* pubKey = NULL; ecc_key tmpKey; (void)ssl; @@ -1726,10 +1726,12 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, /* for client: create and export public key */ if (side == WOLFSSL_CLIENT_END) { WC_RNG rng; + + privKey = &tmpKey; + pubKey = otherKey; + ret = wc_InitRng(&rng); if (ret == 0) { - privKey = &tmpKey; - pubKey = otherKey; ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id); if (ret == 0) ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz); @@ -1741,11 +1743,12 @@ static INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, else if (side == WOLFSSL_SERVER_END) { privKey = otherKey; pubKey = &tmpKey; + ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey, otherKey->dp->id); } else { - ret = -1; + ret = BAD_FUNC_ARG; } /* generate shared secret and return it */ From 82c12fb7be3c797c209a8a89bfb33476ff820585 Mon Sep 17 00:00:00 2001 From: Nickolas Lapp Date: Wed, 7 Dec 2016 10:20:46 -0700 Subject: [PATCH 12/16] Fix DES3 on STM32 CUBEMX --- wolfcrypt/src/des3.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 8cb1a3125..4fc510154 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -151,6 +151,7 @@ void wc_Des3AsyncFree(Des3* des3) int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) { + #ifndef WOLFSSL_STM32_CUBEMX word32 *dkey1 = des->key[0]; word32 *dkey2 = des->key[1]; word32 *dkey3 = des->key[2]; @@ -161,10 +162,12 @@ void wc_Des3AsyncFree(Des3* des3) XMEMCPY(dkey2, key + 8, 8); /* set key 2 */ XMEMCPY(dkey3, key + 16, 8); /* set key 3 */ - #ifndef WOLFSSL_STM32_CUBEMX ByteReverseWords(dkey1, dkey1, 8); ByteReverseWords(dkey2, dkey2, 8); ByteReverseWords(dkey3, dkey3, 8); + #else + (void)dir; + XMEMCPY(des->key[0], key, DES3_KEYLEN); /* CUBEMX wants keys in sequential memory */ #endif return wc_Des3_SetIV(des, iv); @@ -479,9 +482,9 @@ static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, #endif int size ; volatile int v ; - + wc_LockMutex(&Mutex_DesSEC) ; - + secDesc->length1 = 0x0; secDesc->pointer1 = NULL; if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){ @@ -549,7 +552,7 @@ static void wc_Des_Cbc(byte* out, const byte* in, word32 sz, } wc_UnLockMutex(&Mutex_DesSEC) ; - + } @@ -615,7 +618,7 @@ int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) #else #warning "Allocate non-Cache buffers" #endif - + wc_InitMutex(&Mutex_DesSEC) ; } @@ -645,7 +648,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) #else #warning "Allocate non-Cache buffers" #endif - + wc_InitMutex(&Mutex_DesSEC) ; } From ea1a03d53835521bf45acea50c99c3f181cc176a Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 7 Dec 2016 10:50:26 +1000 Subject: [PATCH 13/16] Get the hash of the handshake messages rather than finalize. Inconsistency between SHA256 and SHA384/SHA512 when getting hash. More handshake messages can be added after this operation. --- src/internal.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index 83ce2f4a0..925fb9b4b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10040,17 +10040,20 @@ static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 - ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,hashes->sha256); + ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, + hashes->sha256); if (ret != 0) return ret; #endif #ifdef WOLFSSL_SHA384 - ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,hashes->sha384); + ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, + hashes->sha384); if (ret != 0) return ret; #endif #ifdef WOLFSSL_SHA512 - ret = wc_Sha512Final(&ssl->hsHashes->hashSha512,hashes->sha512); + ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, + hashes->sha512); if (ret != 0) return ret; #endif From 289acd088aa42f16cea2a729177091272d867864 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 8 Dec 2016 14:29:26 +1000 Subject: [PATCH 14/16] Remove state save and restore --- src/internal.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/internal.c b/src/internal.c index 925fb9b4b..a62c1e634 100644 --- a/src/internal.c +++ b/src/internal.c @@ -10023,13 +10023,6 @@ static void BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest) static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) { int ret = 0; - /* store current states, building requires get_digest which resets state */ - #ifdef WOLFSSL_SHA384 - Sha384 sha384 = ssl->hsHashes->hashSha384; - #endif - #ifdef WOLFSSL_SHA512 - Sha512 sha512 = ssl->hsHashes->hashSha512; - #endif (void)hashes; @@ -10064,17 +10057,7 @@ static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) BuildMD5_CertVerify(ssl, hashes->md5); BuildSHA_CertVerify(ssl, hashes->sha); } - - /* restore */ #endif - if (IsAtLeastTLSv1_2(ssl)) { - #ifdef WOLFSSL_SHA384 - ssl->hsHashes->hashSha384 = sha384; - #endif - #ifdef WOLFSSL_SHA512 - ssl->hsHashes->hashSha512 = sha512; - #endif - } return ret; } From d2b5a9538d0d35708082cc04ecd2c71b74bb9f68 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 8 Dec 2016 15:11:41 -0700 Subject: [PATCH 15/16] Prevent forcezero from running on freed memory --- src/sniffer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sniffer.c b/src/sniffer.c index d6185c200..33278f4e0 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1197,6 +1197,7 @@ static int LoadKeyFile(byte** keyBuf, word32* keyBufSz, if (saveBufSz < 0) { saveBufSz = 0; free(saveBuf); + saveBuf = NULL; } else ret = 0; @@ -1205,8 +1206,10 @@ static int LoadKeyFile(byte** keyBuf, word32* keyBufSz, ForceZero(loadBuf, (word32)fileSz); free(loadBuf); - *keyBuf = saveBuf; - *keyBufSz = (word32)saveBufSz; + if (saveBuf) { + *keyBuf = saveBuf; + *keyBufSz = (word32)saveBufSz; + } } else { *keyBuf = loadBuf; From d2ed611757462fb2eb1445547287617faa7b7909 Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 8 Dec 2016 16:52:12 -0800 Subject: [PATCH 16/16] fix nxp distcheck filename typo --- wolfcrypt/src/include.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 9a3ce0a3b..714d5d434 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -47,7 +47,7 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/nrf51.c \ wolfcrypt/src/port/arm/armv8-aes.c \ wolfcrypt/src/port/arm/armv8-sha256.c \ - wolfssl/wolfcrypt/port/nxp/ksdk_port.c \ + wolfcrypt/src/port/nxp/ksdk_port.c \ wolfcrypt/src/port/atmel/atmel.c \ wolfcrypt/src/port/atmel/README.md