From 205da484163e6957d4cec5a9da1a9f2ceefa66ab Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 7 Jul 2017 15:12:51 -0700 Subject: [PATCH 1/4] Fixes for building ARMv8. Adds missing SHA224 and AES KeyWrap. Fixes for FE/GE warning with Aarch32. Fix possible build error with `ed25519_test` with `ret` not defined. --- wolfcrypt/src/port/arm/armv8-aes.c | 171 ++++++++++++++++++++ wolfcrypt/src/port/arm/armv8-sha256.c | 221 ++++++++++++++++++++++---- wolfcrypt/test/test.c | 3 +- wolfssl/wolfcrypt/fe_operations.h | 2 +- 4 files changed, 360 insertions(+), 37 deletions(-) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 0dc43e4e4..fff935ea6 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -4645,6 +4645,177 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_DIRECT */ +#ifdef HAVE_AES_KEYWRAP + +/* Initialize key wrap counter with value */ +static INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value) +{ + int i; + word32 bytes; + + bytes = sizeof(word32); + for (i = 0; i < (int)sizeof(word32); i++) { + inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF; + bytes--; + } +} + +/* Increment key wrap counter */ +static INLINE void IncrementKeyWrapCounter(byte* inOutCtr) +{ + int i; + + /* in network byte order so start at end and work back */ + for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) { + if (++inOutCtr[i]) /* we're done unless we overflow */ + return; + } +} + +/* Decrement key wrap counter */ +static INLINE void DecrementKeyWrapCounter(byte* inOutCtr) +{ + int i; + + for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) { + if (--inOutCtr[i] != 0xFF) /* we're done unless we underflow */ + return; + } +} + +/* perform AES key wrap (RFC3394), return out sz on success, negative on err */ +int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, + byte* out, word32 outSz, const byte* iv) +{ + Aes aes; + byte* r; + word32 i; + int ret, j; + + byte t[KEYWRAP_BLOCK_SIZE]; + byte tmp[AES_BLOCK_SIZE]; + + /* n must be at least 2, output size is n + 8 bytes */ + if (key == NULL || in == NULL || inSz < 2 || + out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE)) + return BAD_FUNC_ARG; + + /* input must be multiple of 64-bits */ + if (inSz % KEYWRAP_BLOCK_SIZE != 0) + return BAD_FUNC_ARG; + + /* user IV is optional */ + if (iv == NULL) { + XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE); + } else { + XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE); + } + + r = out + 8; + XMEMCPY(r, in, inSz); + XMEMSET(t, 0, sizeof(t)); + + ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION); + if (ret != 0) + return ret; + + for (j = 0; j <= 5; j++) { + for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) { + + /* load R[i] */ + XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE); + + wc_AesEncryptDirect(&aes, tmp, tmp); + + /* calculate new A */ + IncrementKeyWrapCounter(t); + xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE); + + /* save R[i] */ + XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE); + r += KEYWRAP_BLOCK_SIZE; + } + r = out + KEYWRAP_BLOCK_SIZE; + } + + /* C[0] = A */ + XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE); + + return inSz + KEYWRAP_BLOCK_SIZE; +} + +int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, + byte* out, word32 outSz, const byte* iv) +{ + Aes aes; + byte* r; + word32 i, n; + int ret, j; + + byte t[KEYWRAP_BLOCK_SIZE]; + byte tmp[AES_BLOCK_SIZE]; + + const byte* expIv; + const byte defaultIV[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 + }; + + (void)iv; + + if (key == NULL || in == NULL || inSz < 3 || + out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE)) + return BAD_FUNC_ARG; + + /* input must be multiple of 64-bits */ + if (inSz % KEYWRAP_BLOCK_SIZE != 0) + return BAD_FUNC_ARG; + + /* user IV optional */ + if (iv != NULL) { + expIv = iv; + } else { + expIv = defaultIV; + } + + /* A = C[0], R[i] = C[i] */ + XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE); + XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE); + XMEMSET(t, 0, sizeof(t)); + + ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION); + if (ret != 0) + return ret; + + /* initialize counter to 6n */ + n = (inSz - 1) / KEYWRAP_BLOCK_SIZE; + InitKeyWrapCounter(t, 6 * n); + + for (j = 5; j >= 0; j--) { + for (i = n; i >= 1; i--) { + + /* calculate A */ + xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE); + DecrementKeyWrapCounter(t); + + /* load R[i], starting at end of R */ + r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE); + XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE); + wc_AesDecryptDirect(&aes, tmp, tmp); + + /* save R[i] */ + XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE); + } + } + + /* verify IV */ + if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0) + return BAD_KEYWRAP_IV_E; + + return inSz - KEYWRAP_BLOCK_SIZE; +} + +#endif /* HAVE_AES_KEYWRAP */ + int wc_AesGetKeySize(Aes* aes, word32* keySize) { int ret = 0; diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 48d7230ef..6f708915f 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -26,7 +26,9 @@ #include -#if !defined(NO_SHA256) && defined(WOLFSSL_ARMASM) +#ifdef WOLFSSL_ARMASM +#if !defined(NO_SHA256) || defined(WOLFSSL_SHA224) + #include #include #include @@ -56,7 +58,7 @@ static const ALIGN32 word32 K[64] = { }; -int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId) +static int InitSha256(Sha256* sha256) { int ret = 0; @@ -77,41 +79,25 @@ int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId) sha256->loLen = 0; sha256->hiLen = 0; - (void)heap; - (void)devId; - return ret; } -int wc_InitSha256(Sha256* sha256) -{ - return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); -} - -void wc_Sha256Free(Sha256* sha256) -{ - (void)sha256; -} - static INLINE void AddLength(Sha256* sha256, word32 len) { word32 tmp = sha256->loLen; - if ( (sha256->loLen += len) < tmp) + if ((sha256->loLen += len) < tmp) sha256->hiLen++; /* carry low to high */ } #ifdef __aarch64__ + /* ARMv8 hardware accleration */ -int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) +static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len) { word32 add; word32 numBlocks; - if (sha256 == NULL || (data == NULL && len != 0)) { - return BAD_FUNC_ARG; - } - /* only perform actions if a buffer is passed in */ if (len > 0) { /* fill leftover buffer with data */ @@ -320,14 +306,10 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) } -int wc_Sha256Final(Sha256* sha256, byte* hash) +static INLINE int Sha256Final(Sha256* sha256, byte* hash) { byte* local; - if (sha256 == NULL || hash == NULL) { - return BAD_FUNC_ARG; - } - local = (byte*)sha256->buffer; AddLength(sha256, sha256->buffLen); /* before adding pads */ @@ -667,20 +649,17 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "v22", "v23", "v24", "v25" ); - return wc_InitSha256(sha256); /* reset state */ + return 0; } #else /* not using 64 bit */ + /* ARMv8 hardware accleration Aarch32 */ -int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) +static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len) { word32 add; word32 numBlocks; - if (sha256 == NULL || (data == NULL && len != 0)) { - return BAD_FUNC_ARG; - } - /* only perform actions if a buffer is passed in */ if (len > 0) { /* fill leftover buffer with data */ @@ -903,7 +882,7 @@ int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) } -int wc_Sha256Final(Sha256* sha256, byte* hash) +static INLINE int Sha256Final(Sha256* sha256, byte* hash) { byte* local; @@ -1298,12 +1277,66 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) "q15" ); - return wc_InitSha256(sha256); /* reset state */ + return 0; } #endif /* __aarch64__ */ +#ifndef NO_SHA256 + +int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId) +{ + int ret = 0; + + if (sha256 == NULL) + return BAD_FUNC_ARG; + + sha256->heap = heap; + + ret = InitSha256(sha256); + if (ret != 0) + return ret; + + (void)devId; + + return ret; +} + +int wc_InitSha256(Sha256* sha256) +{ + return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID); +} + +void wc_Sha256Free(Sha256* sha256) +{ + (void)sha256; +} + +int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) +{ + if (sha256 == NULL || (data == NULL && len != 0)) { + return BAD_FUNC_ARG; + } + + return Sha256Update(sha256, data, len); +} + +int wc_Sha256Final(Sha256* sha256, byte* hash) +{ + int ret; + + if (sha256 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = Sha256Final(sha256, hash); + if (ret != 0) + return ret; + + return InitSha256(sha256); /* reset state */ +} + int wc_Sha256GetHash(Sha256* sha256, byte* hash) { int ret; @@ -1331,4 +1364,122 @@ int wc_Sha256Copy(Sha256* src, Sha256* dst) return ret; } -#endif /* NO_SHA256 and WOLFSSL_ARMASM */ +#endif /* !NO_SHA256 */ + + +#ifdef WOLFSSL_SHA224 + static int InitSha224(Sha224* sha224) + { + + int ret = 0; + + if (sha224 == NULL) { + return BAD_FUNC_ARG; + } + + sha224->digest[0] = 0xc1059ed8; + sha224->digest[1] = 0x367cd507; + sha224->digest[2] = 0x3070dd17; + sha224->digest[3] = 0xf70e5939; + sha224->digest[4] = 0xffc00b31; + sha224->digest[5] = 0x68581511; + sha224->digest[6] = 0x64f98fa7; + sha224->digest[7] = 0xbefa4fa4; + + sha224->buffLen = 0; + sha224->loLen = 0; + sha224->hiLen = 0; + + return ret; + } + + int wc_InitSha224_ex(Sha224* sha224, void* heap, int devId) + { + int ret = 0; + + if (sha224 == NULL) + return BAD_FUNC_ARG; + + sha224->heap = heap; + + ret = InitSha224(sha224); + if (ret != 0) + return ret; + + (void)devId; + + return ret; + } + + int wc_InitSha224(Sha224* sha224) + { + return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID); + } + + int wc_Sha224Update(Sha224* sha224, const byte* data, word32 len) + { + int ret; + + if (sha224 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + + ret = Sha256Update((Sha256 *)sha224, data, len); + + return ret; + } + + int wc_Sha224Final(Sha224* sha224, byte* hash) + { + int ret; + word32 hashTmp[SHA256_DIGEST_SIZE/sizeof(word32)]; + + if (sha224 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = Sha256Final((Sha256*)sha224, (byte*)hashTmp); + if (ret != 0) + return ret; + + XMEMCPY(hash, hashTmp, SHA224_DIGEST_SIZE); + + return InitSha224(sha224); /* reset state */ + } + + void wc_Sha224Free(Sha224* sha224) + { + if (sha224 == NULL) + return; + } + + int wc_Sha224GetHash(Sha224* sha224, byte* hash) + { + int ret; + Sha224 tmpSha224; + + if (sha224 == NULL || hash == NULL) + return BAD_FUNC_ARG; + + ret = wc_Sha224Copy(sha224, &tmpSha224); + if (ret == 0) { + ret = wc_Sha224Final(&tmpSha224, hash); + } + return ret; + } + int wc_Sha224Copy(Sha224* src, Sha224* dst) + { + int ret = 0; + + if (src == NULL || dst == NULL) + return BAD_FUNC_ARG; + + XMEMCPY(dst, src, sizeof(Sha224)); + + return ret; + } + +#endif /* WOLFSSL_SHA224 */ + +#endif /* !NO_SHA256 || WOLFSSL_SHA224 */ +#endif /* WOLFSSL_ARMASM */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 942f4e0b3..633908136 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -11693,6 +11693,7 @@ done: int ed25519_test(void) { + int ret; WC_RNG rng; #if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_EXPORT) &&\ defined(HAVE_ED25519_KEY_IMPORT) @@ -11701,7 +11702,7 @@ int ed25519_test(void) byte exportSKey[ED25519_KEY_SIZE]; word32 exportPSz; word32 exportSSz; - int i, ret; + int i; word32 outlen; #ifdef HAVE_ED25519_VERIFY int verify; diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h index 0cb616e4e..342ca28cc 100644 --- a/wolfssl/wolfcrypt/fe_operations.h +++ b/wolfssl/wolfcrypt/fe_operations.h @@ -90,7 +90,7 @@ WOLFSSL_LOCAL void fe_mul121666(fe,fe); WOLFSSL_LOCAL void fe_cmov(fe,const fe, int); WOLFSSL_LOCAL void fe_pow22523(fe,const fe); -#if defined(HAVE___UINT128_T) +#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) /* 64 type needed for SHA512 */ WOLFSSL_LOCAL uint64_t load_3(const unsigned char *in); WOLFSSL_LOCAL uint64_t load_4(const unsigned char *in); From a5cdbb18cb7ed574eb85c5a496f9ec9502b62998 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 10 Jul 2017 19:12:41 -0700 Subject: [PATCH 2/4] Reworked the AES Key Wrap to use existing code in aes.c (instead of duplicating code in armv8-aes.c). Cleanup for GE/FE math on 32-bit to remove duplicate #ifdef check. Fixed AES GCM arg check for authIn to allows NULL. --- src/include.am | 3 +- wolfcrypt/src/aes.c | 132 +++++++++++----------- wolfcrypt/src/port/arm/armv8-aes.c | 173 +---------------------------- wolfssl/wolfcrypt/fe_operations.h | 2 - 4 files changed, 69 insertions(+), 241 deletions(-) diff --git a/src/include.am b/src/include.am index 1140dd0e8..d3fc04266 100644 --- a/src/include.am +++ b/src/include.am @@ -92,10 +92,9 @@ endif endif if BUILD_AES +src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c if BUILD_ARMASM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/arm/armv8-aes.c -else -src_libwolfssl_la_SOURCES += wolfcrypt/src/aes.c endif endif diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 69051dfcc..9c6a3ab64 100755 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -27,9 +27,10 @@ #include #ifndef NO_AES - #include +#ifndef WOLFSSL_ARMASM + /* fips wrapper calls, user can call direct */ #ifdef HAVE_FIPS int wc_AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, @@ -5197,6 +5198,70 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, #endif /* HAVE_AESCCM */ +/* Initialize Aes for use with async hardware */ +int wc_AesInit(Aes* aes, void* heap, int devId) +{ + int ret = 0; + + if (aes == NULL) + return BAD_FUNC_ARG; + + aes->heap = heap; + +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) + ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES, + aes->heap, devId); +#else + (void)devId; +#endif /* WOLFSSL_ASYNC_CRYPT */ + + return ret; +} + +/* Free Aes from use with async hardware */ +void wc_AesFree(Aes* aes) +{ + if (aes == NULL) + return; + +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) + wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES); +#endif /* WOLFSSL_ASYNC_CRYPT */ +} + + +int wc_AesGetKeySize(Aes* aes, word32* keySize) +{ + int ret = 0; + + if (aes == NULL || keySize == NULL) { + return BAD_FUNC_ARG; + } + + switch (aes->rounds) { + case 10: + *keySize = 16; + break; + case 12: + *keySize = 24; + break; + case 14: + *keySize = 32; + break; + default: + *keySize = 0; + ret = BAD_FUNC_ARG; + } + + return ret; +} + +#endif /* !WOLFSSL_TI_CRYPT */ + +#endif /* HAVE_FIPS */ +#endif /* !WOLFSSL_ARMASM */ + + #ifdef HAVE_AES_KEYWRAP /* Initialize key wrap counter with value */ @@ -5368,67 +5433,4 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, #endif /* HAVE_AES_KEYWRAP */ - -/* Initialize Aes for use with async hardware */ -int wc_AesInit(Aes* aes, void* heap, int devId) -{ - int ret = 0; - - if (aes == NULL) - return BAD_FUNC_ARG; - - aes->heap = heap; - -#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) - ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES, - aes->heap, devId); -#else - (void)devId; -#endif /* WOLFSSL_ASYNC_CRYPT */ - - return ret; -} - -/* Free Aes from use with async hardware */ -void wc_AesFree(Aes* aes) -{ - if (aes == NULL) - return; - -#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) - wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES); -#endif /* WOLFSSL_ASYNC_CRYPT */ -} - - -int wc_AesGetKeySize(Aes* aes, word32* keySize) -{ - int ret = 0; - - if (aes == NULL || keySize == NULL) { - return BAD_FUNC_ARG; - } - - switch (aes->rounds) { - case 10: - *keySize = 16; - break; - case 12: - *keySize = 24; - break; - case 14: - *keySize = 32; - break; - default: - *keySize = 0; - ret = BAD_FUNC_ARG; - } - - return ret; -} - -#endif /* !WOLFSSL_TI_CRYPT */ - -#endif /* HAVE_FIPS */ - -#endif /* NO_AES */ +#endif /* !NO_AES */ diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index fff935ea6..7b839d95f 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -2531,7 +2531,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* sanity checks */ if (aes == NULL || (iv == NULL && ivSz > 0) || (authTag == NULL) || - (authIn == NULL) || + (authIn == NULL && authInSz > 0) || (in == NULL && sz > 0) || (out == NULL && sz > 0)) { WOLFSSL_MSG("a NULL parameter passed in when size is larger than 0"); @@ -4645,177 +4645,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_DIRECT */ -#ifdef HAVE_AES_KEYWRAP - -/* Initialize key wrap counter with value */ -static INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value) -{ - int i; - word32 bytes; - - bytes = sizeof(word32); - for (i = 0; i < (int)sizeof(word32); i++) { - inOutCtr[i+sizeof(word32)] = (value >> ((bytes - 1) * 8)) & 0xFF; - bytes--; - } -} - -/* Increment key wrap counter */ -static INLINE void IncrementKeyWrapCounter(byte* inOutCtr) -{ - int i; - - /* in network byte order so start at end and work back */ - for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) { - if (++inOutCtr[i]) /* we're done unless we overflow */ - return; - } -} - -/* Decrement key wrap counter */ -static INLINE void DecrementKeyWrapCounter(byte* inOutCtr) -{ - int i; - - for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) { - if (--inOutCtr[i] != 0xFF) /* we're done unless we underflow */ - return; - } -} - -/* perform AES key wrap (RFC3394), return out sz on success, negative on err */ -int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, - byte* out, word32 outSz, const byte* iv) -{ - Aes aes; - byte* r; - word32 i; - int ret, j; - - byte t[KEYWRAP_BLOCK_SIZE]; - byte tmp[AES_BLOCK_SIZE]; - - /* n must be at least 2, output size is n + 8 bytes */ - if (key == NULL || in == NULL || inSz < 2 || - out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE)) - return BAD_FUNC_ARG; - - /* input must be multiple of 64-bits */ - if (inSz % KEYWRAP_BLOCK_SIZE != 0) - return BAD_FUNC_ARG; - - /* user IV is optional */ - if (iv == NULL) { - XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE); - } else { - XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE); - } - - r = out + 8; - XMEMCPY(r, in, inSz); - XMEMSET(t, 0, sizeof(t)); - - ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_ENCRYPTION); - if (ret != 0) - return ret; - - for (j = 0; j <= 5; j++) { - for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) { - - /* load R[i] */ - XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE); - - wc_AesEncryptDirect(&aes, tmp, tmp); - - /* calculate new A */ - IncrementKeyWrapCounter(t); - xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE); - - /* save R[i] */ - XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE); - r += KEYWRAP_BLOCK_SIZE; - } - r = out + KEYWRAP_BLOCK_SIZE; - } - - /* C[0] = A */ - XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE); - - return inSz + KEYWRAP_BLOCK_SIZE; -} - -int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, - byte* out, word32 outSz, const byte* iv) -{ - Aes aes; - byte* r; - word32 i, n; - int ret, j; - - byte t[KEYWRAP_BLOCK_SIZE]; - byte tmp[AES_BLOCK_SIZE]; - - const byte* expIv; - const byte defaultIV[] = { - 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 - }; - - (void)iv; - - if (key == NULL || in == NULL || inSz < 3 || - out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE)) - return BAD_FUNC_ARG; - - /* input must be multiple of 64-bits */ - if (inSz % KEYWRAP_BLOCK_SIZE != 0) - return BAD_FUNC_ARG; - - /* user IV optional */ - if (iv != NULL) { - expIv = iv; - } else { - expIv = defaultIV; - } - - /* A = C[0], R[i] = C[i] */ - XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE); - XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE); - XMEMSET(t, 0, sizeof(t)); - - ret = wc_AesSetKey(&aes, key, keySz, NULL, AES_DECRYPTION); - if (ret != 0) - return ret; - - /* initialize counter to 6n */ - n = (inSz - 1) / KEYWRAP_BLOCK_SIZE; - InitKeyWrapCounter(t, 6 * n); - - for (j = 5; j >= 0; j--) { - for (i = n; i >= 1; i--) { - - /* calculate A */ - xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE); - DecrementKeyWrapCounter(t); - - /* load R[i], starting at end of R */ - r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE); - XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE); - wc_AesDecryptDirect(&aes, tmp, tmp); - - /* save R[i] */ - XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE); - } - } - - /* verify IV */ - if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0) - return BAD_KEYWRAP_IV_E; - - return inSz - KEYWRAP_BLOCK_SIZE; -} - -#endif /* HAVE_AES_KEYWRAP */ - int wc_AesGetKeySize(Aes* aes, word32* keySize) { int ret = 0; diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h index 342ca28cc..318712a82 100644 --- a/wolfssl/wolfcrypt/fe_operations.h +++ b/wolfssl/wolfcrypt/fe_operations.h @@ -90,11 +90,9 @@ WOLFSSL_LOCAL void fe_mul121666(fe,fe); WOLFSSL_LOCAL void fe_cmov(fe,const fe, int); WOLFSSL_LOCAL void fe_pow22523(fe,const fe); -#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) /* 64 type needed for SHA512 */ WOLFSSL_LOCAL uint64_t load_3(const unsigned char *in); WOLFSSL_LOCAL uint64_t load_4(const unsigned char *in); -#endif #endif /* !CURVE25519_SMALL || !ED25519_SMALL */ From 5bb8de627e911af11287926b1c9ffb88a3a87a38 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 12 Jul 2017 09:04:10 -0700 Subject: [PATCH 3/4] Fixes based on peer review (thanks). --- wolfcrypt/src/aes.c | 8 ++++---- wolfcrypt/src/port/arm/armv8-sha256.c | 18 ++---------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 9c6a3ab64..440fa71a6 100755 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -29,7 +29,6 @@ #ifndef NO_AES #include -#ifndef WOLFSSL_ARMASM /* fips wrapper calls, user can call direct */ #ifdef HAVE_FIPS @@ -190,6 +189,8 @@ #include #endif +#ifndef WOLFSSL_ARMASM + #ifdef DEBUG_AESNI #include #endif @@ -5256,10 +5257,8 @@ int wc_AesGetKeySize(Aes* aes, word32* keySize) return ret; } -#endif /* !WOLFSSL_TI_CRYPT */ - -#endif /* HAVE_FIPS */ #endif /* !WOLFSSL_ARMASM */ +#endif /* !WOLFSSL_TI_CRYPT */ #ifdef HAVE_AES_KEYWRAP @@ -5433,4 +5432,5 @@ int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz, #endif /* HAVE_AES_KEYWRAP */ +#endif /* HAVE_FIPS */ #endif /* !NO_AES */ diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 6f708915f..bb01692d2 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -1287,20 +1287,13 @@ static INLINE int Sha256Final(Sha256* sha256, byte* hash) int wc_InitSha256_ex(Sha256* sha256, void* heap, int devId) { - int ret = 0; - if (sha256 == NULL) return BAD_FUNC_ARG; sha256->heap = heap; - - ret = InitSha256(sha256); - if (ret != 0) - return ret; - (void)devId; - return ret; + return InitSha256(sha256); } int wc_InitSha256(Sha256* sha256) @@ -1395,20 +1388,13 @@ int wc_Sha256Copy(Sha256* src, Sha256* dst) int wc_InitSha224_ex(Sha224* sha224, void* heap, int devId) { - int ret = 0; - if (sha224 == NULL) return BAD_FUNC_ARG; sha224->heap = heap; - - ret = InitSha224(sha224); - if (ret != 0) - return ret; - (void)devId; - return ret; + return InitSha224(sha224); } int wc_InitSha224(Sha224* sha224) From c777097e5493c27b3f4673d2c28fae7f2e621128 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 12 Jul 2017 09:49:27 -0700 Subject: [PATCH 4/4] Fix `wc_AesGcmDecrypt` arg check for `authIn`. --- wolfcrypt/src/port/arm/armv8-aes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index 7b839d95f..623f27119 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -2596,7 +2596,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* sanity checks */ if (aes == NULL || (iv == NULL && ivSz > 0) || (authTag == NULL) || - (authIn == NULL) || + (authIn == NULL && authInSz > 0) || (in == NULL && sz > 0) || (out == NULL && sz > 0)) { WOLFSSL_MSG("a NULL parameter passed in when size is larger than 0");