From 8e64d564dca42f78f943829c4cb2ff2c645b43e1 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 10 Jun 2016 15:46:35 -0700 Subject: [PATCH] NXP/Freescale K8X MMCAU / LTC core support for RSA, ECC, Ed/Curve25519, AES, DSA, DES3, MD5, RNG, SHA and SHA2. --- src/internal.c | 13 +- wolfcrypt/src/aes.c | 397 +++++- wolfcrypt/src/asn.c | 20 +- wolfcrypt/src/curve25519.c | 77 +- wolfcrypt/src/des3.c | 127 +- wolfcrypt/src/dsa.c | 26 +- wolfcrypt/src/ecc.c | 19 +- wolfcrypt/src/ed25519.c | 69 +- wolfcrypt/src/fe_low_mem.c | 4 +- wolfcrypt/src/fe_operations.c | 4 +- wolfcrypt/src/include.am | 3 +- wolfcrypt/src/integer.c | 3 - wolfcrypt/src/md5.c | 18 +- wolfcrypt/src/port/nxp/ksdk_port.c | 1782 ++++++++++++++++++++++++ wolfcrypt/src/random.c | 34 +- wolfcrypt/src/rsa.c | 30 +- wolfcrypt/src/sha.c | 54 +- wolfcrypt/src/sha256.c | 65 +- wolfcrypt/src/tfm.c | 39 +- wolfssl/wolfcrypt/curve25519.h | 3 + wolfssl/wolfcrypt/ed25519.h | 5 + wolfssl/wolfcrypt/fe_operations.h | 2 + wolfssl/wolfcrypt/include.am | 3 +- wolfssl/wolfcrypt/port/nxp/ksdk_port.h | 75 + wolfssl/wolfcrypt/rsa.h | 1 + wolfssl/wolfcrypt/settings.h | 212 ++- wolfssl/wolfcrypt/sha.h | 26 +- wolfssl/wolfcrypt/sha256.h | 8 + wolfssl/wolfcrypt/tfm.h | 1 + 29 files changed, 2901 insertions(+), 219 deletions(-) create mode 100755 wolfcrypt/src/port/nxp/ksdk_port.c create mode 100755 wolfssl/wolfcrypt/port/nxp/ksdk_port.h diff --git a/src/internal.c b/src/internal.c index 71924d2fd..8b2413d90 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4587,14 +4587,21 @@ ProtocolVersion MakeDTLSv1_2(void) return (word32) mqxTime.SECONDS; } +#elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) -#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) + #include "include/task.h" - #include "fsl_pit_driver.h" + unsigned int LowResTimer(void) + { + return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ); + } +#elif defined(FREESCALE_KSDK_BM) + + #include "lwip/sys.h" /* lwIP */ word32 LowResTimer(void) { - return PIT_DRV_GetUs(); + return sys_now()/1000; } #elif defined(WOLFSSL_TIRTOS) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 1821d632b..4aac5afb9 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -299,19 +299,36 @@ void wc_AesAsyncFree(Aes* aes) #include "sec.h" #include "mcf5475_sec.h" #include "mcf5475_siu.h" +#elif defined(FREESCALE_LTC) + #include "fsl_ltc.h" + #if defined(FREESCALE_LTC_AES_GCM) + #undef NEED_AES_TABLES + #undef GCM_TABLE + #else + /* if LTC doesn't have GCM, use software with LTC AES ECB mode */ + static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + wc_AesEncryptDirect(aes, outBlock, inBlock); + return 0; + } + static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + wc_AesDecryptDirect(aes, outBlock, inBlock); + return 0; + } + #endif #elif defined(FREESCALE_MMCAU) /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes * through the CAU/mmCAU library. Documentation located in * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User - * Guide (See note in README). - * NOTE: no support for AES-CTR */ - #include "cau_api.h" + * Guide (See note in README). */ + #include "fsl_mmcau.h" static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) { int ret = wolfSSL_CryptHwMutexLock(); if(ret == 0) { - cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock); + MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds, outBlock); wolfSSL_CryptHwMutexUnLock(); } return ret; @@ -321,7 +338,7 @@ void wc_AesAsyncFree(Aes* aes) { int ret = wolfSSL_CryptHwMutexLock(); if(ret == 0) { - cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock); + MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds, outBlock); wolfSSL_CryptHwMutexUnLock(); } return ret; @@ -1592,6 +1609,28 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) return 0; } +#elif defined(FREESCALE_LTC) + int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, + int dir) + { + if (!((keylen == 16) || (keylen == 24) || (keylen == 32))) + return BAD_FUNC_ARG; + + aes->rounds = keylen/4 + 6; + XMEMCPY(aes->key, userKey, keylen); + + #ifdef WOLFSSL_AES_COUNTER + aes->left = 0; + #endif /* WOLFSSL_AES_COUNTER */ + + return wc_AesSetIV(aes, iv); + } + + int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen, + const byte* iv, int dir) + { + return wc_AesSetKey(aes, userKey, keylen, iv, dir); + } #elif defined(FREESCALE_MMCAU) int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir) @@ -1607,11 +1646,15 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) if (rk == NULL) return BAD_FUNC_ARG; + #ifdef WOLFSSL_AES_COUNTER + aes->left = 0; + #endif /* WOLFSSL_AES_COUNTER */ + aes->rounds = keylen/4 + 6; ret = wolfSSL_CryptHwMutexLock(); if(ret == 0) { - cau_aes_set_key(userKey, keylen*8, rk); + MMCAU_AES_SetKey(userKey, keylen, rk); wolfSSL_CryptHwMutexUnLock(); ret = wc_AesSetIV(aes, iv); @@ -1905,6 +1948,64 @@ int wc_InitAes_h(Aes* aes, void* h) #elif defined(WOLFSSL_PIC32MZ_CRYPT) #error "PIC32MZ doesn't yet support AES direct" + #elif defined(FREESCALE_LTC) + /* Allow direct access to one block encrypt */ + void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in) + { + byte *key; + uint32_t keySize = 0; + + key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + LTC_AES_EncryptEcb( LTC_BASE, + in, + out, + 16, + key, + keySize); + } + + /* Allow direct access to one block decrypt */ + void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in) + { + byte *key; + uint32_t keySize = 0; + + key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + LTC_AES_DecryptEcb( LTC_BASE, + in, + out, + 16, + key, + keySize, + kLTC_EncryptKey); + } + #else /* Allow direct access to one block encrypt */ void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in) @@ -2257,6 +2358,73 @@ int wc_InitAes_h(Aes* aes, void* h) return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT)); } #endif /* HAVE_AES_DECRYPT */ + +#elif defined(FREESCALE_LTC) + int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + uint32_t keySize = 0; + status_t status; + byte *iv, *enc_key; + + iv = (byte*)aes->reg; + enc_key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + status = LTC_AES_EncryptCbc(LTC_BASE, + in, + out, + sz, + iv, + enc_key, + keySize); + return (status == kStatus_Success) ? 0 : -1; + } + + #ifdef HAVE_AES_DECRYPT + int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + uint32_t keySize = 0; + status_t status; + byte* iv, *dec_key; + + iv = (byte*)aes->reg; + dec_key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + status = LTC_AES_DecryptCbc(LTC_BASE, + in, + out, + sz, + iv, + dec_key, + keySize, + kLTC_EncryptKey); + return (status == kStatus_Success) ? 0 : -1; + } + #endif /* HAVE_AES_DECRYPT */ + #elif defined(FREESCALE_MMCAU) int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { @@ -2269,10 +2437,6 @@ int wc_InitAes_h(Aes* aes, void* h) iv = (byte*)aes->reg; - if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) { - WOLFSSL_MSG("Bad cau_aes_encrypt alignment"); - return BAD_ALIGN_E; - } while (len > 0) { @@ -2305,10 +2469,6 @@ int wc_InitAes_h(Aes* aes, void* h) iv = (byte*)aes->reg; - if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) { - WOLFSSL_MSG("Bad cau_aes_decrypt alignment"); - return BAD_ALIGN_E; - } while (len > 0) { @@ -2731,8 +2891,47 @@ int wc_InitAes_h(Aes* aes, void* h) #elif defined(HAVE_COLDFIRE_SEC) #error "Coldfire SEC doesn't currently support AES-CTR mode" - #elif defined(FREESCALE_MMCAU) - #error "Freescale mmCAU doesn't currently support AES-CTR mode" + #elif defined(FREESCALE_LTC) + void wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) + { + uint32_t keySize = 0; + byte *iv, *enc_key; + byte* tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; + + /* consume any unused bytes left in aes->tmp */ + while (aes->left && sz) { + *(out++) = *(in++) ^ *(tmp++); + aes->left--; + sz--; + } + + if (sz) { + iv = (byte*)aes->reg; + enc_key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + LTC_AES_CryptCtr( LTC_BASE, + in, + out, + sz, + iv, + enc_key, + keySize, + (byte*)aes->tmp, + (uint32_t*)&(aes->left)); + } + } #else /* Increment AES counter */ @@ -2816,7 +3015,7 @@ enum { CTR_SZ = 4 }; - +#if !defined(FREESCALE_LTC_AES_GCM) static INLINE void IncrementGcmCounter(byte* inOutCtr) { int i; @@ -2827,7 +3026,7 @@ static INLINE void IncrementGcmCounter(byte* inOutCtr) return; } } - +#endif /* !FREESCALE_LTC_AES_GCM */ #if defined(GCM_SMALL) || defined(GCM_TABLE) @@ -2911,12 +3110,14 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) return ret; #endif /* WOLFSSL_AESNI */ +#if !defined(FREESCALE_LTC_AES_GCM) if (ret == 0) { wc_AesEncrypt(aes, iv, aes->H); #ifdef GCM_TABLE GenerateM0(aes); #endif /* GCM_TABLE */ } +#endif /* FREESCALE_LTC_AES_GCM */ return ret; } @@ -3588,6 +3789,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz, /* end GCM_TABLE */ #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) +#if !defined(FREESCALE_LTC_AES_GCM) static void GMULT(word64* X, word64* Y) { word64 Z[2] = {0,0}; @@ -3623,7 +3825,6 @@ static void GMULT(word64* X, word64* Y) X[1] = Z[1]; } - static void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word32 cSz, byte* s, word32 sSz) { @@ -3708,6 +3909,7 @@ static void GHASH(Aes* aes, const byte* a, word32 aSz, #endif XMEMCPY(s, x, sSz); } +#endif /* !FREESCALE_LTC_AES_GCM */ /* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */ #else /* GCM_WORD32 */ @@ -3864,6 +4066,42 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { +#if defined(FREESCALE_LTC_AES_GCM) + byte *key; + uint32_t keySize = 0; + status_t status; + + key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + status = LTC_AES_EncryptTagGcm( LTC_BASE, + in, + out, + sz, + iv, + ivSz, + authIn, + authInSz, + key, + keySize, + authTag, + authTagSz); + + return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E; + +#else /* FREESCALE_LTC_AES_GCM */ + word32 blocks = sz / AES_BLOCK_SIZE; word32 partial = sz % AES_BLOCK_SIZE; const byte* p = in; @@ -3930,6 +4168,7 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, xorbuf(authTag, scratch, authTagSz); return 0; +#endif /* FREESCALE_LTC_AES_GCM */ } @@ -3939,6 +4178,42 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { +#if defined(FREESCALE_LTC_AES_GCM) + byte *key; + uint32_t keySize = 0; + status_t status; + + key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + status = LTC_AES_DecryptTagGcm( LTC_BASE, + in, + out, + sz, + iv, + ivSz, + authIn, + authInSz, + key, + keySize, + authTag, + authTagSz); + + return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E; + +#else /* FREESCALE_LTC_AES_GCM */ + word32 blocks = sz / AES_BLOCK_SIZE; word32 partial = sz % AES_BLOCK_SIZE; const byte* c = in; @@ -4015,6 +4290,7 @@ int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, XMEMCPY(p, scratch, partial); } return 0; +#endif /* FREESCALE_LTC_AES_GCM */ } #endif /* HAVE_AES_DECRYPT */ @@ -4058,6 +4334,7 @@ int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz) } +#ifndef FREESCALE_LTC static void roll_x(Aes* aes, const byte* in, word32 inSz, byte* out) { /* process the bulk of the data */ @@ -4130,7 +4407,7 @@ static INLINE void AesCcmCtrInc(byte* B, word32 lenSz) if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return; } } - +#endif /* !FREESCALE_LTC */ /* return 0 on success */ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, @@ -4138,6 +4415,43 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { +#ifdef FREESCALE_LTC + byte *key; + uint32_t keySize = 0; + status_t status; + + key = (byte*)aes->key; + + switch (aes->rounds) + { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + status = LTC_AES_EncryptTagCcm(LTC_BASE, + in, + out, + inSz, + nonce, + nonceSz, + authIn, + authInSz, + key, + keySize, + authTag, + authTagSz); + if (kStatus_Success == status) + return 0; + else + return BAD_FUNC_ARG; +#else byte A[AES_BLOCK_SIZE]; byte B[AES_BLOCK_SIZE]; byte lenSz; @@ -4196,6 +4510,7 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz, ForceZero(B, AES_BLOCK_SIZE); return 0; +#endif /* FREESCALE_LTC */ } #ifdef HAVE_AES_DECRYPT @@ -4204,6 +4519,47 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, const byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz) { +#ifdef FREESCALE_LTC + byte *key; + uint32_t keySize = 0; + status_t status; + + key = (byte*)aes->key; + + switch (aes->rounds) { + case 10: + keySize = 16; + break; + case 12: + keySize = 24; + break; + case 14: + keySize = 32; + break; + } + + status = LTC_AES_DecryptTagCcm( LTC_BASE, + in, + out, + inSz, + nonce, + nonceSz, + authIn, + authInSz, + key, + keySize, + authTag, + authTagSz); + + if (status == kStatus_Success) { + return 0; + } + else { + XMEMSET(out, 0, inSz); + return AES_CCM_AUTH_E; + } +#else /* FREESCALE_LTC */ + byte A[AES_BLOCK_SIZE]; byte B[AES_BLOCK_SIZE]; byte* o; @@ -4286,6 +4642,7 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, o = NULL; return result; +#endif /* FREESCALE_LTC */ } #endif /* HAVE_AES_DECRYPT */ #endif /* HAVE_AESCCM */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 92c725737..5b79f4298 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -127,9 +127,11 @@ ASN Options: #define XTIME(t1) mqx_time((t1)) #define HAVE_GMTIME_R -#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) +#elif defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) #include - #define XTIME(t1) ksdk_time((t1)) + #ifndef XTIME + #define XTIME(t1) 0 + #endif #define XGMTIME(c, t) gmtime((c)) #elif defined(USER_TIME) @@ -376,18 +378,8 @@ time_t mqx_time(time_t* timer) #if defined(FREESCALE_KSDK_BM) || defined(FREESCALE_FREE_RTOS) -#include "fsl_pit_driver.h" - -time_t ksdk_time(time_t* timer) -{ - time_t localTime; - - if (timer == NULL) - timer = &localTime; - - *timer = (PIT_DRV_ReadTimerUs(PIT_INSTANCE, PIT_CHANNEL)) / 1000000; - return *timer; -} +/* */ +//extern time_t ksdk_time(time_t* timer); #endif /* FREESCALE_KSDK_BM */ diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index 3e7b0f52a..2e90422e9 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -40,6 +40,10 @@ #include #endif +#if defined(FREESCALE_LTC_ECC) + #include "nxp/ksdk_port.h" +#endif + const curve25519_set_type curve25519_sets[] = { { 32, @@ -47,10 +51,13 @@ const curve25519_set_type curve25519_sets[] = { } }; - int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key) { - unsigned char basepoint[CURVE25519_KEYSIZE] = {9}; + #ifdef FREESCALE_LTC_ECC + ECPoint * basepoint = wc_curve25519_GetBasePoint(); + #else + unsigned char basepoint[CURVE25519_KEYSIZE] = {9}; + #endif int ret; if (key == NULL || rng == NULL) @@ -71,7 +78,11 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key) key->k.point[CURVE25519_KEYSIZE-1] |= 64; /* compute public key */ - ret = curve25519(key->p.point, key->k.point, basepoint); + #ifdef FREESCALE_LTC_ECC + ret = wc_curve25519(&key->p, key->k.point, basepoint, kLTC_Weierstrass /* input basepoint on Weierstrass curve */); + #else + ret = curve25519(key->p.point, key->k.point, basepoint); + #endif if (ret != 0) { ForceZero(key->k.point, keysize); ForceZero(key->p.point, keysize); @@ -95,21 +106,34 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key, curve25519_key* public_key, byte* out, word32* outlen, int endian) { - unsigned char o[CURVE25519_KEYSIZE]; + #ifdef FREESCALE_LTC_ECC + ECPoint o = {{0}}; + #else + unsigned char o[CURVE25519_KEYSIZE]; + #endif int ret = 0; /* sanity check */ if (private_key == NULL || public_key == NULL || out == NULL || outlen == NULL || *outlen < CURVE25519_KEYSIZE) return BAD_FUNC_ARG; - + /* avoid implementation fingerprinting */ if (public_key->p.point[CURVE25519_KEYSIZE-1] > 0x7F) return ECC_BAD_ARG_E; - ret = curve25519(o, private_key->k.point, public_key->p.point); + #ifdef FREESCALE_LTC_ECC + ret = wc_curve25519(&o, private_key->k.point, &public_key->p, kLTC_Curve25519 /* input point P on Curve25519 */); + #else + ret = curve25519(o, private_key->k.point, public_key->p.point); + #endif if (ret != 0) { - ForceZero(o, CURVE25519_KEYSIZE); + #ifdef FREESCALE_LTC_ECC + ForceZero(o.point, CURVE25519_KEYSIZE); + ForceZero(o.pointY, CURVE25519_KEYSIZE); + #else + ForceZero(o, CURVE25519_KEYSIZE); + #endif return ret; } @@ -117,14 +141,27 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key, int i; /* put shared secret key in Big Endian format */ for (i = 0; i < CURVE25519_KEYSIZE; i++) - out[i] = o[CURVE25519_KEYSIZE - i -1]; + #ifdef FREESCALE_LTC_ECC + out[i] = o.point[CURVE25519_KEYSIZE - i -1]; + #else + out[i] = o[CURVE25519_KEYSIZE - i -1]; + #endif } else /* put shared secret key in Little Endian format */ - XMEMCPY(out, o, CURVE25519_KEYSIZE); + #ifdef FREESCALE_LTC_ECC + XMEMCPY(out, o.point, CURVE25519_KEYSIZE); + #else + XMEMCPY(out, o, CURVE25519_KEYSIZE); + #endif *outlen = CURVE25519_KEYSIZE; - ForceZero(o, sizeof(o)); + #ifdef FREESCALE_LTC_ECC + ForceZero(o.point, CURVE25519_KEYSIZE); + ForceZero(o.pointY, CURVE25519_KEYSIZE); + #else + ForceZero(o, CURVE25519_KEYSIZE); + #endif return ret; } @@ -212,6 +249,15 @@ int wc_curve25519_import_public_ex(const byte* in, word32 inLen, XMEMCPY(key->p.point, in, inLen); key->dp = &curve25519_sets[0]; + + + /* LTC needs also Y coordinate - let's compute it */ + #ifdef FREESCALE_LTC_ECC + ltc_pkha_ecc_point_t ltcPoint; + ltcPoint.X = &key->p.point[0]; + ltcPoint.Y = &key->p.pointY[0]; + LTC_PKHA_Curve25519ComputeY(<cPoint); + #endif return 0; } @@ -378,9 +424,12 @@ int wc_curve25519_init(curve25519_key* key) /* currently the format for curve25519 */ key->dp = &curve25519_sets[0]; - XMEMSET(key->k.point, 0, key->dp->size); + XMEMSET(key->k.point, 0, key->dp->size); XMEMSET(key->p.point, 0, key->dp->size); - + #ifdef FREESCALE_LTC_ECC + XMEMSET(key->k.pointY, 0, key->dp->size); + XMEMSET(key->p.pointY, 0, key->dp->size); + #endif return 0; } @@ -394,6 +443,10 @@ void wc_curve25519_free(curve25519_key* key) key->dp = NULL; ForceZero(key->p.point, sizeof(key->p.point)); ForceZero(key->k.point, sizeof(key->k.point)); + #ifdef FREESCALE_LTC_ECC + ForceZero(key->p.point, sizeof(key->p.pointY)); + ForceZero(key->k.point, sizeof(key->k.pointY)); + #endif } diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 3f2147d88..cc27ab3c1 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -576,14 +576,99 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) return 0; } +#elif (defined FREESCALE_LTC_DES) + #include "fsl_ltc.h" + int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) + { + byte* dkey = (byte*)des->key; + + XMEMCPY(dkey, key, 8); + + wc_Des_SetIV(des, iv); + + return 0; + } + + int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) + { + int ret = 0; + byte* dkey1 = (byte*)des->key[0]; + byte* dkey2 = (byte*)des->key[1]; + byte* dkey3 = (byte*)des->key[2]; + + XMEMCPY(dkey1, key, 8); /* set key 1 */ + XMEMCPY(dkey2, key + 8, 8); /* set key 2 */ + XMEMCPY(dkey3, key + 16, 8); /* set key 3 */ + + ret = wc_Des3_SetIV(des, iv); + if (ret != 0) + return ret; + + return ret; + } + + int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) + { + status_t status; + status = LTC_DES_EncryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key); + if (status == kStatus_Success) + return 0; + else + return -1; + } + + int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) + { + status_t status; + status = LTC_DES_DecryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key); + if (status == kStatus_Success) + return 0; + else + return -1; + } + + int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) + { + status_t status; + status = LTC_DES3_EncryptCbc(LTC_BASE, + in, + out, + sz, + (byte*)des->reg, + (byte*)des->key[0], + (byte*)des->key[1], + (byte*)des->key[2]); + if (status == kStatus_Success) + return 0; + else + return -1; + } + + int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) + { + status_t status; + status = LTC_DES3_DecryptCbc(LTC_BASE, + in, + out, + sz, + (byte*)des->reg, + (byte*)des->key[0], + (byte*)des->key[1], + (byte*)des->key[2]); + if (status == kStatus_Success) + return 0; + else + return -1; + + } #elif defined FREESCALE_MMCAU /* * Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library. * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU * Software Library User Guide (See note in README). */ - #include "cau_api.h" + #include "fsl_mmcau.h" const unsigned char parityLookup[128] = { @@ -648,12 +733,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) byte temp_block[DES_BLOCK_SIZE]; iv = (byte*)des->reg; - - if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) { - WOLFSSL_MSG("Bad cau_des_encrypt alignment"); - return BAD_ALIGN_E; - } - + while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -666,7 +746,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) if(ret != 0) { return ret; } - cau_des_encrypt(temp_block, (byte*)des->key, out + offset); + MMCAU_DES_EncryptEcb(temp_block, (byte*)des->key, out + offset); wolfSSL_CryptHwMutexUnLock(); len -= DES_BLOCK_SIZE; @@ -690,11 +770,6 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) iv = (byte*)des->reg; - if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) { - WOLFSSL_MSG("Bad cau_des_decrypt alignment"); - return BAD_ALIGN_E; - } - while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -703,7 +778,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) if(ret != 0) { return ret; } - cau_des_decrypt(in + offset, (byte*)des->key, out + offset); + MMCAU_DES_DecryptEcb(in + offset, (byte*)des->key, out + offset); wolfSSL_CryptHwMutexUnLock(); /* XOR block with IV for CBC */ @@ -731,12 +806,7 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) byte temp_block[DES_BLOCK_SIZE]; iv = (byte*)des->reg; - - if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) { - WOLFSSL_MSG("Bad 3ede cau_des_encrypt alignment"); - return BAD_ALIGN_E; - } - + while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -749,9 +819,9 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) if(ret != 0) { return ret; } - cau_des_encrypt(temp_block , (byte*)des->key[0], out + offset); - cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset); - cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset); + MMCAU_DES_EncryptEcb(temp_block , (byte*)des->key[0], out + offset); + MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[1], out + offset); + MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[2], out + offset); wolfSSL_CryptHwMutexUnLock(); len -= DES_BLOCK_SIZE; @@ -776,11 +846,6 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) iv = (byte*)des->reg; - if ((wolfssl_word)out % WOLFSSL_MMCAU_ALIGNMENT) { - WOLFSSL_MSG("Bad 3ede cau_des_decrypt alignment"); - return BAD_ALIGN_E; - } - while (len > 0) { XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE); @@ -789,9 +854,9 @@ int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir) if(ret != 0) { return ret; } - cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset); - cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset); - cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset); + MMCAU_DES_DecryptEcb(in + offset , (byte*)des->key[2], out + offset); + MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[1], out + offset); + MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[0], out + offset); wolfSSL_CryptHwMutexUnLock(); /* XOR block with IV for CBC */ diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 1e339273a..d9ba8ac03 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -359,20 +359,26 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) byte* tmp = out; /* initial output pointer */ sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q)); - - /* generate k */ - ret = wc_RNG_GenerateBlock(rng, buffer, sz); - if (ret != 0) - return ret; - - buffer[0] |= 0x0C; - + if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) return MP_INIT_E; - if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) - ret = MP_READ_E; + do { + /* generate k */ + ret = wc_RNG_GenerateBlock(rng, buffer, sz); + if (ret != 0) + return ret; + buffer[0] |= 0x0C; + + if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) + ret = MP_READ_E; + + /* k is a random numnber and it should be less than q + * if k greater than repeat + */ + } while (mp_cmp(&k, &key->q) != MP_LT); + if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT) ret = MP_CMP_E; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 703f0f3df..bcfecf0dc 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -103,6 +103,10 @@ ECC Curve Sizes: #include #endif +#if defined(FREESCALE_LTC_ECC) + #include "nxp/ksdk_port.h" +#endif + #ifdef USE_FAST_MATH #define GEN_MEM_ERR FP_MEM #else @@ -979,6 +983,7 @@ static int get_digit_count(mp_int* a) } /* helper for either lib */ +#ifndef FREESCALE_LTC_ECC static mp_digit get_digit(mp_int* a, int n) { if (a == NULL) @@ -986,6 +991,7 @@ static mp_digit get_digit(mp_int* a, int n) return (n >= a->used || n < 0) ? 0 : a->dp[n]; } +#endif /* FREESCALE_LTC_ECC */ /** Add two ECC points @@ -1920,6 +1926,7 @@ int wc_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, (1==map, 0 == leave in projective) return MP_OKAY on success */ +#if !defined(FREESCALE_LTC_ECC) #ifdef FP_ECC static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap) @@ -2111,6 +2118,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, } return err; } +#endif /* FREESCALE_LTC_ECC */ #ifndef FP_ECC @@ -3363,6 +3371,15 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, if (err == MP_OKAY) err = mp_copy(key->pubkey.z, mQ->z); +#ifdef FREESCALE_LTC_ECC + /* use PKHA to compute u1*mG + u2*mQ */ + if (err == MP_OKAY) + err = wc_ecc_mulmod(&u1, mG, mG, &m, 0); + if (err == MP_OKAY) + err = wc_ecc_mulmod(&u2, mQ, mQ, &m, 0); + if (err == MP_OKAY) + err = wc_ecc_point_add(mG, mQ, mG, &m); +#else /* FREESCALE_LTC_ECC */ #ifndef ECC_SHAMIR { mp_digit mp; @@ -3390,7 +3407,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, if (err == MP_OKAY) err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &a, &modulus, key->heap); #endif /* ECC_SHAMIR */ - +#endif /* FREESCALE_LTC_ECC */ /* v = X_x1 mod n */ if (err == MP_OKAY) err = mp_mod(mG->x, &order, &v); diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 9eb86da23..17aa2db04 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -41,6 +41,10 @@ #include #endif +#ifdef FREESCALE_LTC_ECC + #include "nxp/ksdk_port.h" +#endif + /* generate an ed25519 key pair. * returns 0 on success */ @@ -48,7 +52,9 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) { byte az[ED25519_PRV_KEY_SIZE]; int ret; +#if !defined(FREESCALE_LTC_ECC) ge_p3 A; +#endif if (rng == NULL || key == NULL) return BAD_FUNC_ARG; @@ -71,9 +77,16 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */ az[31] |= 64; +#ifdef FREESCALE_LTC_ECC + ltc_pkha_ecc_point_t publicKey = {0}; + publicKey.X = key->pointX; + publicKey.Y = key->pointY; + LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), az, ED25519_KEY_SIZE, &publicKey, kLTC_Ed25519 /* result on Ed25519 */); + LTC_PKHA_Ed25519_Compress(&publicKey, key->p); +#else ge_scalarmult_base(&A, az); ge_p3_tobytes(key->p, &A); - +#endif /* put public key after private key, on the same buffer */ XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE); @@ -94,8 +107,12 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out, word32 *outLen, ed25519_key* key) { +#ifdef FREESCALE_LTC_ECC + byte tempBuf[ED25519_PRV_KEY_SIZE]; +#else ge_p3 R; - byte nonce[SHA512_DIGEST_SIZE]; +#endif + byte nonce[SHA512_DIGEST_SIZE]; byte hram[SHA512_DIGEST_SIZE]; byte az[ED25519_PRV_KEY_SIZE]; Sha512 sha; @@ -136,12 +153,21 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out, if (ret != 0) return ret; +#ifdef FREESCALE_LTC_ECC + ltc_pkha_ecc_point_t ltcPoint = {0}; + ltcPoint.X = &tempBuf[0]; + ltcPoint.Y = &tempBuf[32]; + LTC_PKHA_sc_reduce(nonce); + LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce, ED25519_KEY_SIZE, <cPoint, kLTC_Ed25519 /* result on Ed25519 */); + LTC_PKHA_Ed25519_Compress(<cPoint, out); +#else sc_reduce(nonce); /* step 2: computing R = rB where rB is the scalar multiplication of r and B */ ge_scalarmult_base(&R,nonce); ge_p3_tobytes(out,&R); +#endif /* step 3: hash R + public key + message getting H(R,A,M) then creating S = (r + H(R,A,M)a) mod l */ @@ -161,8 +187,13 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out, if (ret != 0) return ret; +#ifdef FREESCALE_LTC_ECC + LTC_PKHA_sc_reduce(hram); + LTC_PKHA_sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce); +#else sc_reduce(hram); sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce); +#endif return ret; } @@ -184,8 +215,10 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg, { byte rcheck[ED25519_KEY_SIZE]; byte h[SHA512_DIGEST_SIZE]; +#ifndef FREESCALE_LTC_ECC ge_p3 A; ge_p2 R; +#endif int ret; Sha512 sha; @@ -201,8 +234,10 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg, return BAD_FUNC_ARG; /* uncompress A (public key), test if valid, and negate it */ +#ifndef FREESCALE_LTC_ECC if (ge_frombytes_negate_vartime(&A, key->p) != 0) return BAD_FUNC_ARG; +#endif /* find H(R,A,M) and store it as h */ ret = wc_InitSha512(&sha); @@ -221,6 +256,10 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg, if (ret != 0) return ret; +#ifdef FREESCALE_LTC_ECC + LTC_PKHA_sc_reduce(h); + LTC_PKHA_SignatureForVerify(rcheck, h, sig + (ED25519_SIG_SIZE/2), key); +#else sc_reduce(h); /* @@ -232,6 +271,7 @@ int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg, return ret; ge_tobytes(rcheck, &R); +#endif /* FREESCALE_LTC_ECC */ /* comparison of R created to R in sig */ ret = ConstantCompare(rcheck, sig, ED25519_SIG_SIZE/2); @@ -319,14 +359,32 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key) if (in[0] == 0x40 && inLen > ED25519_PUB_KEY_SIZE) { /* key is stored in compressed format so just copy in */ XMEMCPY(key->p, (in + 1), ED25519_PUB_KEY_SIZE); +#ifdef FREESCALE_LTC_ECC + /* recover X coordinate */ + ltc_pkha_ecc_point_t pubKey; + pubKey.X = key->pointX; + pubKey.Y = key->pointY; + LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey); +#endif return 0; } /* importing uncompressed public key */ if (in[0] == 0x04 && inLen > 2*ED25519_PUB_KEY_SIZE) { +#ifdef FREESCALE_LTC_ECC + /* reverse bytes for little endian byte order */ + for (int i = 0; i < ED25519_KEY_SIZE; i++) + { + key->pointX[i] = *(in + ED25519_KEY_SIZE - i); + key->pointY[i] = *(in + 2*ED25519_KEY_SIZE - i); + } + XMEMCPY(key->p, key->pointY, ED25519_KEY_SIZE); + ret = 0; +#else /* pass in (x,y) and store compressed key */ ret = ge_compress_key(key->p, in+1, in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE); +#endif /* FREESCALE_LTC_ECC */ return ret; } @@ -334,6 +392,13 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key) if key size is equal to compressed key size copy in key */ if (inLen == ED25519_PUB_KEY_SIZE) { XMEMCPY(key->p, in, ED25519_PUB_KEY_SIZE); +#ifdef FREESCALE_LTC_ECC + /* recover X coordinate */ + ltc_pkha_ecc_point_t pubKey; + pubKey.X = key->pointX; + pubKey.Y = key->pointY; + LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey); +#endif return 0; } diff --git a/wolfcrypt/src/fe_low_mem.c b/wolfcrypt/src/fe_low_mem.c index 0fe6158a0..9caffa81f 100644 --- a/wolfcrypt/src/fe_low_mem.c +++ b/wolfcrypt/src/fe_low_mem.c @@ -130,7 +130,7 @@ static void xc_diffadd(byte *x5, byte *z5, fe_mul__distinct(z5, x1, b); } - +#ifndef FREESCALE_LTC_ECC int curve25519(byte *result, byte *e, byte *q) { /* Current point: P_m */ @@ -174,7 +174,7 @@ int curve25519(byte *result, byte *e, byte *q) fe_normalize(result); return 0; } - +#endif /* !FREESCALE_LTC_ECC */ static void raw_add(byte *x, const byte *p) { diff --git a/wolfcrypt/src/fe_operations.c b/wolfcrypt/src/fe_operations.c index 1a387ce37..9dfeab093 100644 --- a/wolfcrypt/src/fe_operations.c +++ b/wolfcrypt/src/fe_operations.c @@ -107,7 +107,7 @@ void fe_0(fe h) h[9] = 0; } - +#ifndef FREESCALE_LTC_ECC int curve25519(byte* q, byte* n, byte* p) { #if 0 @@ -183,7 +183,7 @@ int curve25519(byte* q, byte* n, byte* p) return 0; } - +#endif /* !FREESCALE_LTC_ECC */ /* h = f * f diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 111ad6331..25189119b 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -45,8 +45,9 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/ti/ti-ccm.c \ wolfcrypt/src/port/pic32/pic32mz-hash.c \ wolfcrypt/src/port/nrf51.c \ - wolfcrypt/src/port/arm/armv8-sha256.c \ wolfcrypt/src/port/arm/armv8-aes.c + wolfcrypt/src/port/arm/armv8-sha256.c \ + wolfssl/wolfcrypt/port/nxp/ksdk_port.c if BUILD_CAVIUM src_libwolfssl_la_SOURCES += wolfcrypt/src/port/cavium/cavium_nitrox.c diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 7e0c59820..ff7095bce 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4628,9 +4628,7 @@ LBL_U:mp_clear (&v); /* chars used in radix conversions */ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz+/"; -#endif -#ifdef HAVE_ECC /* read a string [ASCII] in a given radix */ int mp_read_radix (mp_int * a, const char *str, int radix) { @@ -4694,7 +4692,6 @@ int mp_read_radix (mp_int * a, const char *str, int radix) } return MP_OKAY; } -#endif /* HAVE_ECC */ #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ defined(WOLFSSL_DEBUG_MATH) diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index dfda77915..80ea23d8d 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -49,8 +49,8 @@ #include #endif -#ifdef FREESCALE_MMCAU - #include "cau_api.h" +#ifdef FREESCALE_MMCAU_SHA + #include "fsl_mmcau.h" #define XTRANSFORM(S,B) Transform((S), (B)) #else #define XTRANSFORM(S,B) Transform((S)) @@ -195,19 +195,19 @@ void wc_InitMd5(Md5* md5) md5->hiLen = 0; } -#ifdef FREESCALE_MMCAU +#ifdef FREESCALE_MMCAU_SHA static int Transform(Md5* md5, byte* data) { int ret = wolfSSL_CryptHwMutexLock(); if(ret == 0) { - cau_md5_hash_n(data, 1, (unsigned char*)md5->digest); + MMCAU_MD5_HashN(data, 1, (uint32_t*)(md5->digest)); wolfSSL_CryptHwMutexUnLock(); } return ret; } -#endif /* FREESCALE_MMCAU */ +#endif /* FREESCALE_MMCAU_SHA */ -#ifndef FREESCALE_MMCAU +#ifndef FREESCALE_MMCAU_SHA static void Transform(Md5* md5) { @@ -325,7 +325,7 @@ void wc_Md5Update(Md5* md5, const byte* data, word32 len) len -= add; if (md5->buffLen == MD5_BLOCK_SIZE) { - #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) + #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); #endif XTRANSFORM(md5, local); @@ -349,7 +349,7 @@ void wc_Md5Final(Md5* md5, byte* hash) XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen); md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen; - #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) + #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); #endif XTRANSFORM(md5, local); @@ -363,7 +363,7 @@ void wc_Md5Final(Md5* md5, byte* hash) md5->loLen = md5->loLen << 3; /* store lengths */ - #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) + #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); #endif /* ! length ordering dependent on digest endian type ! */ diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c new file mode 100755 index 000000000..b187e04b1 --- /dev/null +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -0,0 +1,1782 @@ +/* ksdk_port.c + * + * Copyright (C) 2006-2016 wolfSSL Inc. All rights reserved. + * + * This file is part of wolfSSL. + * + * Contact licensing@wolfssl.com with any questions or comments. + * + * http://www.wolfssl.com + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* in case user set USE_FAST_MATH there */ +#include +#ifdef NO_INLINE +#include +#else +#include +#endif + +#ifdef USE_FAST_MATH + +#include +#include +#include /* will define asm MACROS or C ones */ + +#if defined(FREESCALE_LTC_TFM) + +#include "nxp/ksdk_port.h" +#include "fsl_ltc.h" +#include + +/* Reverse array in memory (in place) */ +static void ltc_reverse_array(uint8_t *src, size_t src_len) +{ + int i; + + for (i = 0; i < src_len / 2; i++) + { + uint8_t tmp; + + tmp = src[i]; + src[i] = src[src_len - 1 - i]; + src[src_len - 1 - i] = tmp; + } +} + +/* same as fp_to_unsigned_bin() with fp_reverse() skipped */ +static void fp_to_unsigned_lsb_bin(fp_int *a, unsigned char *b) +{ + fp_int t; + + fp_init_copy(&t, a); + + (void)fp_to_unsigned_bin_at_pos(0, &t, b); +} + +static void ltc_get_lsb_bin_from_mp_int(uint8_t *dst, mp_int *A, uint16_t *psz) +{ + uint16_t sz; + + sz = mp_unsigned_bin_size(A); + fp_to_unsigned_lsb_bin(A, dst); /* result is lsbyte at lowest addr as required by LTC */ + *psz = sz; +} + +/* these function are used by wolfSSL upper layers (like RSA) */ + +/* c = a * b */ +void fp_mul(fp_int *A, fp_int *B, fp_int *C) +{ + int szA, szB; + szA = fp_unsigned_bin_size(A); + szB = fp_unsigned_bin_size(B); + + /* if unsigned mul can fit into LTC PKHA let's use it, otherwise call software mul */ + if ((szA <= LTC_MAX_INT_BYTES / 2) && (szB <= LTC_MAX_INT_BYTES / 2)) + { + int neg; + + neg = (A->sign == B->sign) ? FP_ZPOS : FP_NEG; + + /* unsigned multiply */ + uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + + if (ptrA && ptrB && ptrC) + { + uint16_t sizeA, sizeB; + + ltc_get_lsb_bin_from_mp_int(ptrA, A, &sizeA); + ltc_get_lsb_bin_from_mp_int(ptrB, B, &sizeB); + XMEMSET(ptrC, 0xFF, LTC_MAX_INT_BYTES); + + LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, LTC_MAX_INT_BYTES, ptrB, &sizeB, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + + ltc_reverse_array(ptrB, sizeB); + mp_read_unsigned_bin(C, ptrB, sizeB); + } + + /* fix sign */ + C->sign = neg; + if (ptrA) + { + XFREE(ptrA, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrB) + { + XFREE(ptrB, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrC) + { + XFREE(ptrC, 0, DYNAMIC_TYPE_BIGINT); + } + return; + } + else + { + wolfcrypt_fp_mul(A, B, C); + } +} + +/* c = a mod b, 0 <= c < b */ +int fp_mod(fp_int *a, fp_int *b, fp_int *c) +{ +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + int szA, szB; + szA = fp_unsigned_bin_size(a); + szB = fp_unsigned_bin_size(b); + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) + { +#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */ + int res = FP_OKAY; + int neg; + + uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + + /* get sign for the result */ + neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG; + + /* get remainder of unsigned a divided by unsigned b */ + if (ptrA && ptrB && ptrC) + { + uint16_t sizeA, sizeB, sizeC; + + ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); + ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); + + if (kStatus_Success == + LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith)) + { + ltc_reverse_array(ptrC, sizeC); + mp_read_unsigned_bin(c, ptrC, sizeC); + } + else + { + res = FP_VAL; + } + } + else + { + res = FP_MEM; + } + + /* fix sign */ + c->sign = neg; + + if (ptrA) + { + XFREE(ptrA, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrB) + { + XFREE(ptrB, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrC) + { + XFREE(ptrC, 0, DYNAMIC_TYPE_BIGINT); + } + return res; +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + } + else + { + return wolfcrypt_fp_mod(a, b, c); + } +#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */ +} + +/* c = 1/a (mod b) for odd b only */ +int fp_invmod(fp_int *a, fp_int *b, fp_int *c) +{ +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + int szA, szB; + szA = fp_unsigned_bin_size(a); + szB = fp_unsigned_bin_size(b); + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) + { +#endif + int res = FP_OKAY; + + uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + + if (ptrA && ptrB && ptrC) + { + uint16_t sizeA, sizeB, sizeC; + + ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); + ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); + + if (kStatus_Success == + LTC_PKHA_ModInv(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith)) + { + ltc_reverse_array(ptrC, sizeC); + mp_read_unsigned_bin(c, ptrC, sizeC); + } + else + { + res = FP_VAL; + } + } + else + { + res = FP_MEM; + } + + c->sign = a->sign; + if (ptrA) + { + XFREE(ptrA, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrB) + { + XFREE(ptrB, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrC) + { + XFREE(ptrC, 0, DYNAMIC_TYPE_BIGINT); + } + return res; +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + } + else + { + return wolfcrypt_fp_invmod(a, b, c); + } +#endif +} + +/* d = a * b (mod c) */ +int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) +{ +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + int szA, szB, szC; + szA = fp_unsigned_bin_size(a); + szB = fp_unsigned_bin_size(b); + szC = fp_unsigned_bin_size(c); + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) + { +#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */ + int res = FP_OKAY; + fp_int t; + + uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrD = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + + /* if A or B is negative, substracta abs(A) or abs(B) from modulus to get positive integer representation of the + * same number */ + fp_init(&t); + if (a->sign) + { + fp_add(a, c, &t); + fp_copy(&t, a); + } + if (b->sign) + { + fp_add(b, c, &t); + fp_copy(&t, b); + } + + if (ptrA && ptrB && ptrC && ptrD) + { + uint16_t sizeA, sizeB, sizeC, sizeD; + + ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); + ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); + ltc_get_lsb_bin_from_mp_int(ptrC, c, &sizeC); + + /* (A*B)mod C = ((A mod C) * (B mod C)) mod C */ + if (LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrC, sizeC) >= 0) + { + if (kStatus_Success != + LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrC, sizeC, ptrA, &sizeA, kLTC_PKHA_IntegerArith)) + { + res = FP_VAL; + } + } + if ((FP_OKAY == res) && (LTC_PKHA_CompareBigNum(ptrB, sizeB, ptrC, sizeC) >= 0)) + { + if (kStatus_Success != + LTC_PKHA_ModRed(LTC_BASE, ptrB, sizeB, ptrC, sizeC, ptrB, &sizeB, kLTC_PKHA_IntegerArith)) + { + res = FP_VAL; + } + } + + if (FP_OKAY == res) + { + if (kStatus_Success != LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, sizeC, ptrD, &sizeD, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized)) + { + res = FP_VAL; + } + } + + if (FP_OKAY == res) + { + ltc_reverse_array(ptrD, sizeD); + mp_read_unsigned_bin(d, ptrD, sizeD); + } + } + else + { + res = FP_MEM; + } + + if (ptrA) + { + XFREE(ptrA, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrB) + { + XFREE(ptrB, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrC) + { + XFREE(ptrC, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrD) + { + XFREE(ptrD, 0, DYNAMIC_TYPE_BIGINT); + } + return res; +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + } + else + { + return wolfcrypt_fp_mulmod(a, b, c, d); + } +#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */ +} + +/* Y = G^X mod P */ +int _fp_exptmod(fp_int *G, fp_int *X, fp_int *P, fp_int *Y) +{ +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + int szA, szB, szC; + szA = fp_unsigned_bin_size(G); + szB = fp_unsigned_bin_size(X); + szC = fp_unsigned_bin_size(P); + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) + { +#endif + int res = FP_OKAY; + fp_int t; + + uint16_t sizeG, sizeX, sizeP; + uint8_t *ptrG = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrX = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrP = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, 0, DYNAMIC_TYPE_BIGINT); + + /* if G is negative, add modulus to convert to positive number for LTC */ + fp_init(&t); + if (G->sign) + { + fp_add(G, P, &t); + fp_copy(&t, G); + } + + if (ptrG && ptrX && ptrP) + { + ltc_get_lsb_bin_from_mp_int(ptrG, G, &sizeG); + ltc_get_lsb_bin_from_mp_int(ptrX, X, &sizeX); + ltc_get_lsb_bin_from_mp_int(ptrP, P, &sizeP); + + /* if number if greater that modulo, we must first reduce due to LTC requirement on modular exponentiaton */ + /* it needs number less than modulus. */ + /* we can take advantage of modular arithmetic rule that: A^B mod C = ( (A mod C)^B ) mod C + and so we do first (A mod N) : LTC does not give size requirement on A versus N, + and then the modular exponentiation. + */ + /* if G >= P then */ + if (LTC_PKHA_CompareBigNum(ptrG, sizeG, ptrP, sizeP) >= 0) + { + res = (int)LTC_PKHA_ModRed(LTC_BASE, ptrG, sizeG, ptrP, sizeP, ptrG, &sizeG, kLTC_PKHA_IntegerArith); + + if (res != kStatus_Success) + { + res = FP_VAL; + } + } + + if (FP_OKAY == res) + { + res = (int)LTC_PKHA_ModExp(LTC_BASE, ptrG, sizeG, ptrP, sizeP, ptrX, sizeX, ptrP, &sizeP, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + + if (res != kStatus_Success) + { + res = FP_VAL; + } + else + { + ltc_reverse_array(ptrP, sizeP); + mp_read_unsigned_bin(Y, ptrP, sizeP); + } + } + } + else + { + res = FP_MEM; + } + + if (ptrG) + { + XFREE(ptrG, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrX) + { + XFREE(ptrX, 0, DYNAMIC_TYPE_BIGINT); + } + if (ptrP) + { + XFREE(ptrP, 0, DYNAMIC_TYPE_BIGINT); + } + return res; +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + } + else + { + return _wolfcrypt_fp_exptmod(G, X, P, Y); + } +#endif +} + +#ifndef NO_RSA +#include +#include +int wc_RsaFunction(const byte *in, word32 inLen, byte *out, word32 *outLen, int type, RsaKey *key) +{ +#define ERROR_OUT(x) \ + { \ + ret = (x); \ + goto done; \ + } + + mp_int tmp; + int ret = 0; + word32 keyLen, len; + + if (mp_init(&tmp) != MP_OKAY) + return MP_INIT_E; + + if (mp_read_unsigned_bin(&tmp, (byte *)in, inLen) != MP_OKAY) + ERROR_OUT(MP_READ_E); + + if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) + { +#define INNER_ERROR_OUT(x) \ + { \ + ret = (x); \ + goto inner_done; \ + } + + mp_int tmpa, tmpb; + + if (mp_init(&tmpa) != MP_OKAY) + ERROR_OUT(MP_INIT_E); + + if (mp_init(&tmpb) != MP_OKAY) + { + mp_clear(&tmpa); + ERROR_OUT(MP_INIT_E); + } + + /* tmpa = tmp^dP mod p */ + if (mp_mod(&tmp, &key->p, &tmpa) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); + if (mp_exptmod(&tmpa, &key->dP, &key->p, &tmpa) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); + + /* tmpb = tmp^dQ mod q */ + if (mp_mod(&tmp, &key->q, &tmpb) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); + if (mp_exptmod(&tmpb, &key->dQ, &key->q, &tmpb) != MP_OKAY) + INNER_ERROR_OUT(MP_EXPTMOD_E); + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_SUB_E); + + if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_MULMOD_E); + + /* tmp = tmpb + q * tmp */ + if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_MUL_E); + + if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT(MP_ADD_E); + + inner_done: + mp_clear(&tmpa); + mp_clear(&tmpb); + + if (ret != 0) + return ret; + } + else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) + { +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + /* use CRT even for public key operation due to size of integer arguments + * because up to 256 bytes results can be achieved by LTC_PKHA_2048 + */ + mp_int tmpa, tmpb; + mp_int dP; + mp_int dQ; +#define INNER_ERROR_OUT2(x) \ + { \ + ret = (x); \ + goto inner_done; \ + } + + if (mp_init(&tmpa) != MP_OKAY) + ERROR_OUT(MP_INIT_E); + + if (mp_init(&tmpb) != MP_OKAY) + { + mp_clear(&tmpa); + ERROR_OUT(MP_INIT_E); + } + + if (mp_init(&dP) != MP_OKAY) + { + mp_clear(&tmpa); + mp_clear(&tmpb); + ERROR_OUT(MP_INIT_E); + } + + if (mp_init(&dQ) != MP_OKAY) + { + mp_clear(&tmpa); + mp_clear(&tmpb); + mp_clear(&dP); + ERROR_OUT(MP_INIT_E); + } + + mp_sub_d(&key->p, 1, &dP); /* dP = p-1 */ + mp_mod(&key->e, &dP, &dP); /* dP = (e mod (p-1) */ + + mp_sub_d(&key->q, 1, &dQ); /* dQ = q-1 */ + mp_mod(&key->e, &dQ, &dQ); /* dQ = (e mod (q-1) */ + + /* tmpa = tmp^dP mod p */ + if (mp_mod(&tmp, &key->p, &tmpa) != MP_OKAY) + INNER_ERROR_OUT2(MP_EXPTMOD_E); + if (mp_exptmod(&tmpa, &dP, &key->p, &tmpa) != MP_OKAY) + INNER_ERROR_OUT2(MP_EXPTMOD_E); + + /* tmpb = tmp^dQ mod q */ + if (mp_mod(&tmp, &key->q, &tmpb) != MP_OKAY) + INNER_ERROR_OUT2(MP_EXPTMOD_E); + if (mp_exptmod(&tmpb, &dQ, &key->q, &tmpb) != MP_OKAY) + INNER_ERROR_OUT2(MP_EXPTMOD_E); + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT2(MP_SUB_E); + + if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY) + INNER_ERROR_OUT2(MP_MULMOD_E); + + /* tmp = tmpb + q * tmp */ + if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY) + INNER_ERROR_OUT2(MP_MUL_E); + + if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) + INNER_ERROR_OUT2(MP_ADD_E); + + inner_done2: + mp_clear(&tmpa); + mp_clear(&tmpb); + mp_clear(&dP); + mp_clear(&dQ); + + if (ret != 0) + return ret; +#else + if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY) + ERROR_OUT(MP_EXPTMOD_E); +#endif + } + else + ERROR_OUT(RSA_WRONG_TYPE_E); + + keyLen = mp_unsigned_bin_size(&key->n); + if (keyLen > *outLen) + ERROR_OUT(RSA_BUFFER_E); + + len = mp_unsigned_bin_size(&tmp); + + /* pad front w/ zeros to match key length */ + while (len < keyLen) + { + *out++ = 0x00; + len++; + } + + *outLen = keyLen; + + /* convert */ + if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) + ERROR_OUT(MP_TO_E); + +done: + mp_clear(&tmp); + if (ret == MP_EXPTMOD_E) + { + WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem"); + } + return ret; +} +#endif /* NO_RSA */ + +#endif /* FREESCALE_LTC_TFM */ +#endif /* USE_FAST_MATH */ + +#ifdef FREESCALE_LTC_ECC +#include +#include "fsl_ltc.h" +#include + +/* convert from mp_int to LTC integer, as array of bytes of size sz. + * if mp_int has less bytes than sz, add zero bytes at most significant byte positions. + * This is when for example modulus is 32 bytes (P-256 curve) + * and mp_int has only 31 bytes, we add leading zeroes + * so that result array has 32 bytes, same as modulus (sz). + */ +static void ltc_get_from_mp_int(uint8_t *dst, mp_int *a, int sz) +{ + int szbin; + int offset; + + /* check how many bytes are in the mp_int */ + szbin = mp_unsigned_bin_size(a); + + /* compute offset from dst */ + offset = sz - szbin; + if (offset < 0) + offset = 0; + if (offset > sz) + offset = sz; + + /* add leading zeroes */ + if (offset) + memset(dst, 0, offset); + + /* convert mp_int to array of bytes */ + mp_to_unsigned_bin(a, dst + offset); + + /* reverse array for LTC direct use */ + ltc_reverse_array(dst, sz); +} + +/* ECC specs in lsbyte at lowest address format for direct use by LTC PKHA driver functions */ +#if defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES) +#define ECC192 +#endif +#if defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES) +#define ECC224 +#endif +#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) +#define ECC256 +#endif +#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) +#define ECC384 +#endif + +/* P-256 */ +#ifdef ECC256 +const uint8_t ltc_ecc256_modulus[32] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; +const uint8_t ltc_ecc256_r2modn[32] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00}; +const uint8_t ltc_ecc256_aCurveParam[32] = {0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; +const uint8_t ltc_ecc256_bCurveParam[32] = {0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B, 0xF6, 0xB0, 0x53, + 0xCC, 0xB0, 0x06, 0x1D, 0x65, 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, + 0xEB, 0xB3, 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A}; +#endif + +#ifdef ECC192 +const uint8_t ltc_ecc192_modulus[24] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +const uint8_t ltc_ecc192_r2modn[24] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +const uint8_t ltc_ecc192_aCurveParam[24] = {0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +const uint8_t ltc_ecc192_bCurveParam[24] = {0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE, 0x49, 0x30, 0x24, 0x72, + 0xAB, 0xE9, 0xA7, 0x0F, 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64}; +#endif + +#ifdef ECC224 +const uint8_t ltc_ecc224_modulus[28] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +const uint8_t ltc_ecc224_r2modn[28] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; +const uint8_t ltc_ecc224_aCurveParam[28] = {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +const uint8_t ltc_ecc224_bCurveParam[28] = {0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27, 0xBA, 0xD8, + 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50, 0x56, 0x32, 0x41, 0xF5, + 0xAB, 0xB3, 0x04, 0x0C, 0x85, 0x0A, 0x05, 0xB4}; +#endif + +#ifdef ECC384 +const uint8_t ltc_ecc384_modulus[48] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +const uint8_t ltc_ecc384_r2modn[48] = {0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +const uint8_t ltc_ecc384_aCurveParam[48] = {0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +const uint8_t ltc_ecc384_bCurveParam[48] = {0xef, 0x2a, 0xec, 0xd3, 0xed, 0xc8, 0x85, 0x2a, 0x9d, 0xd1, 0x2e, 0x8a, + 0x8d, 0x39, 0x56, 0xc6, 0x5a, 0x87, 0x13, 0x50, 0x8f, 0x08, 0x14, 0x03, + 0x12, 0x41, 0x81, 0xfe, 0x6e, 0x9c, 0x1d, 0x18, 0x19, 0x2d, 0xf8, 0xe3, + 0x6b, 0x05, 0x8e, 0x98, 0xe4, 0xe7, 0x3e, 0xe2, 0xa7, 0x2f, 0x31, 0xb3}; +#endif + +static int ltc_get_ecc_specs( + const uint8_t **modulus, const uint8_t **r2modn, const uint8_t **aCurveParam, const uint8_t **bCurveParam, int size) +{ + if (32 == size) + { + *modulus = ltc_ecc256_modulus; + *r2modn = ltc_ecc256_r2modn; + *aCurveParam = ltc_ecc256_aCurveParam; + *bCurveParam = ltc_ecc256_bCurveParam; + } +#ifdef ECC224 + else if (28 == size) + { + *modulus = ltc_ecc224_modulus; + *r2modn = ltc_ecc224_r2modn; + *aCurveParam = ltc_ecc224_aCurveParam; + *bCurveParam = ltc_ecc224_bCurveParam; + } +#endif +#ifdef ECC192 + else if (24 == size) + { + *modulus = ltc_ecc192_modulus; + *r2modn = ltc_ecc192_r2modn; + *aCurveParam = ltc_ecc192_aCurveParam; + *bCurveParam = ltc_ecc192_bCurveParam; + } +#endif +#ifdef HAVE_ECC384 + else if (48 == size) + { + *modulus = ltc_ecc384_modulus; + *r2modn = ltc_ecc384_r2modn; + *aCurveParam = ltc_ecc384_aCurveParam; + *bCurveParam = ltc_ecc384_bCurveParam; + } +#endif + else + { + return -1; + } + return 0; +} + +/** + Perform a point multiplication (timing resistant) + k The scalar to multiply by + G The base point + R [out] Destination for kG + modulus The modulus of the field the ECC curve is in + map Boolean whether to map back to affine or not + (1==map, 0 == leave in projective) + return MP_OKAY on success +*/ +int wc_ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus, int map) +{ + ltc_pkha_ecc_point_t B; + uint8_t size; + int szModulus; + int szkbin; + bool point_of_infinity; + status_t status; + + uint8_t Gxbin[LTC_MAX_ECC_BITS / 8]; + uint8_t Gybin[LTC_MAX_ECC_BITS / 8]; + uint8_t kbin[LTC_MAX_INT_BYTES]; + + const uint8_t *modbin; + const uint8_t *aCurveParam; + const uint8_t *bCurveParam; + const uint8_t *r2modn; + + if (k == NULL || G == NULL || R == NULL || modulus == NULL) + return ECC_BAD_ARG_E; + + szModulus = mp_unsigned_bin_size(modulus); + szkbin = mp_unsigned_bin_size(k); + + ltc_get_from_mp_int(kbin, k, szkbin); + ltc_get_from_mp_int(Gxbin, G->x, szModulus); + ltc_get_from_mp_int(Gybin, G->y, szModulus); + + size = szModulus; + /* find LTC friendly parameters for the selected curve */ + if (0 != ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, size)) + { + return ECC_BAD_ARG_E; + } + + B.X = &Gxbin[0]; + B.Y = &Gybin[0]; + + status = LTC_PKHA_ECC_PointMul(LTC_BASE, &B, kbin, szkbin, modbin, r2modn, aCurveParam, bCurveParam, size, + kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, &B, &point_of_infinity); + if (status != kStatus_Success) + return FP_VAL; + + ltc_reverse_array(Gxbin, size); + ltc_reverse_array(Gybin, size); + mp_read_unsigned_bin(R->x, Gxbin, size); + mp_read_unsigned_bin(R->y, Gybin, size); + /* if k is negative, we compute the multiplication with abs(-k) + * with result (x, y) and modify the result to (x, -y) + */ + R->y->sign = k->sign; + mp_set(R->z, 1); + return MP_OKAY; +} + +int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m) +{ + int err; + ltc_pkha_ecc_point_t A, B; + int size; + status_t status; + + uint8_t Gxbin[LTC_MAX_ECC_BITS / 8]; + uint8_t Gybin[LTC_MAX_ECC_BITS / 8]; + uint8_t Qxbin[LTC_MAX_ECC_BITS / 8]; + uint8_t Qybin[LTC_MAX_ECC_BITS / 8]; + const uint8_t *modbin; + const uint8_t *aCurveParam; + const uint8_t *bCurveParam; + const uint8_t *r2modn; + + size = mp_unsigned_bin_size(m); + /* find LTC friendly parameters for the selected curve */ + if (0 != ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, size)) + { + err = ECC_BAD_ARG_E; + } + else + { + ltc_get_from_mp_int(Gxbin, mG->x, size); + ltc_get_from_mp_int(Gybin, mG->y, size); + ltc_get_from_mp_int(Qxbin, mQ->x, size); + ltc_get_from_mp_int(Qybin, mQ->y, size); + + A.X = Gxbin; + A.Y = Gybin; + + B.X = Qxbin; + B.Y = Qybin; + + status = LTC_PKHA_ECC_PointAdd(LTC_BASE, &A, &B, modbin, r2modn, aCurveParam, bCurveParam, size, + kLTC_PKHA_IntegerArith, &A); + if (status != kStatus_Success) + { + err = FP_VAL; + } + else + { + ltc_reverse_array(Gxbin, size); + ltc_reverse_array(Gybin, size); + mp_read_unsigned_bin(mR->x, Gxbin, size); + mp_read_unsigned_bin(mR->y, Gybin, size); + mp_set(mR->z, 1); + err = MP_OKAY; + } + } + return err; +} + +#if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) +/* Weierstrass parameters of prime 2^255 - 19 */ +static const uint8_t modbin[32] = {0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; + +static const uint8_t r2mod[32] = { + 0xa4, 0x05, +}; /* precomputed R2modN for the curve25519 */ + +/* invThree = ModInv(3,modbin) in LSB first */ +static const uint8_t invThree[32] = {0x49, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; + +/* + * + * finds square root in finite field when modulus congruent to 5 modulo 8 + * this is fixed to curve25519 modulus 2^255 - 19 which is congruent to 5 modulo 8 + * + * This function solves equation: res^2 = a mod (2^255 - 19) + * +p = prime +p % 8 must be 5 + +v = ModularArithmetic.powmod(2*a, (p-5)/8, p) +i = (2*a*v**2) % p +r1 = 1*a*v*(i - 1) % p +r2 = -1*a*v*(i - 1) % p +puts "Gy=0x#{r2.to_s(16)}" + */ +status_t LTC_PKHA_Prime25519SquareRootMod(const uint8_t *A, size_t sizeA, uint8_t *res, size_t *szRes, int sign) +{ + status_t status; + const uint8_t curve25519_param[] = {0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f}; + + uint8_t twoA[sizeof(modbin)] = {0}; + uint8_t V[sizeof(modbin)] = {0}; + uint8_t I[sizeof(modbin)] = {0}; + uint8_t VV[sizeof(modbin)] = {0}; + uint16_t szTwoA = 0; + uint16_t szV = 0; + uint16_t szVV = 0; + uint16_t szI = 0; + uint16_t szRes16 = 0; + uint8_t one = 1; + + /* twoA = 2*A % p */ + status = + LTC_PKHA_ModAdd(LTC_BASE, A, sizeA, A, sizeA, modbin, sizeof(modbin), twoA, &szTwoA, kLTC_PKHA_IntegerArith); + + /* V = ModularArithmetic.powmod(twoA, (p-5)/8, p) */ + if (status == kStatus_Success) + { + status = + LTC_PKHA_ModExp(LTC_BASE, twoA, szTwoA, modbin, sizeof(modbin), curve25519_param, sizeof(curve25519_param), + V, &szV, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + /* VV = V*V % p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, V, szV, V, szV, modbin, sizeof(modbin), VV, &szVV, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + /* I = twoA * VV = 2*A*V*V % p */ + if (status == kStatus_Success) + { + status = + LTC_PKHA_ModMul(LTC_BASE, twoA, szTwoA, VV, szVV, modbin, sizeof(modbin), I, &szI, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + /* I = I - 1 */ + memset(VV, 0xff, sizeof(VV)); /* just temp for maximum integer - for non-modular substract */ + if (0 <= LTC_PKHA_CompareBigNum(I, szI, &one, sizeof(one))) + { + if (status == kStatus_Success) + { + status = LTC_PKHA_ModSub1(LTC_BASE, I, szI, &one, sizeof(one), VV, sizeof(VV), I, &szI); + } + } + else + { + if (status == kStatus_Success) + { + status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), &one, sizeof(one), VV, sizeof(VV), I, &szI); + } + } + + /* res = a*v mod p */ + status = LTC_PKHA_ModMul(LTC_BASE, A, sizeA, V, szV, modbin, sizeof(modbin), res, &szRes16, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + + /* res = res * (i-1) mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, res, szRes16, I, szI, modbin, sizeof(modbin), res, &szRes16, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + /* if X mod 2 != X_0 then we need the -X + * + * X mod 2 get from LSB bit0 + */ + if ((status == kStatus_Success) && ((bool)sign != (bool)(res[0] & 0x01u))) + { + status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), res, szRes16, VV, sizeof(VV), res, + &szRes16); /* -a = p - a */ + } + + if (status == kStatus_Success) + { + *szRes = szRes16; + } + + return status; +} +#endif + +#ifdef HAVE_CURVE25519 + +/* for LTC we need Weierstrass format of curve25519 parameters + * these two are base point X and Y. + * in LSB first format (native for LTC) + */ +static ECPoint ecBasePoint = { + {0x5a, 0x24, 0xad, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a}, + {0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d, 0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, + 0x77, 0x2c, 0xdd, 0x1e, 0xe0, 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20}, +}; + +ECPoint *wc_curve25519_GetBasePoint(void) +{ + return &ecBasePoint; +} + +static const uint8_t aCurveParam[CURVE25519_KEYSIZE] = { + 0x44, 0xa1, 0x14, 0x49, 0x98, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a}; + +static const uint8_t bCurveParam[CURVE25519_KEYSIZE] = { + 0x64, 0xc8, 0x10, 0x77, 0x9c, 0x5e, 0x0b, 0x26, 0xb4, 0x97, 0xd0, 0x5e, 0x42, 0x7b, 0x09, 0xed, + 0x25, 0xb4, 0x97, 0xd0, 0x5e, 0x42, 0x7b, 0x09, 0xed, 0x25, 0xb4, 0x97, 0xd0, 0x5e, 0x42, 0x7b}; + +/* transform a point on Montgomery curve to a point on Weierstrass curve */ +status_t LTC_PKHA_Curve25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut) +{ + /* offset X point (in Montgomery) so that it becomes Weierstrass */ + const uint8_t offset[] = {0x51, 0x24, 0xad, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a}; + uint16_t sizeRes = 0; + status_t status; + status = LTC_PKHA_ModAdd(LTC_BASE, ltcPointIn->X, CURVE25519_KEYSIZE, offset, sizeof(offset), modbin, + CURVE25519_KEYSIZE, ltcPointOut->X, &sizeRes, kLTC_PKHA_IntegerArith); + + if (status == kStatus_Success) + { + if (ltcPointOut->Y != ltcPointIn->Y) + { + XMEMCPY(ltcPointOut->Y, ltcPointIn->Y, CURVE25519_KEYSIZE); + } + } + + return status; +} + +/* transform a point on Weierstrass curve to a point on Montgomery curve */ +status_t LTC_PKHA_WeierstrassToCurve25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut) +{ + status_t status; + uint16_t resultSize = 0; + uint8_t three = 0x03; + + status = LTC_PKHA_ModMul(LTC_BASE, &three, sizeof(three), ltcPointIn->X, CURVE25519_KEYSIZE, modbin, + CURVE25519_KEYSIZE, ltcPointOut->X, &resultSize, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + + if (status == kStatus_Success) + { + static const uint8_t A[] = {0x06, 0x6d, 0x07}; + if (LTC_PKHA_CompareBigNum(ltcPointOut->X, resultSize, A, sizeof(A))) + { + status = LTC_PKHA_ModSub1(LTC_BASE, ltcPointOut->X, resultSize, A, sizeof(A), modbin, CURVE25519_KEYSIZE, + ltcPointOut->X, &resultSize); + } + else + { + status = LTC_PKHA_ModSub2(LTC_BASE, ltcPointOut->X, resultSize, A, sizeof(A), modbin, CURVE25519_KEYSIZE, + ltcPointOut->X, &resultSize); + } + } + + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, invThree, CURVE25519_KEYSIZE, ltcPointOut->X, resultSize, modbin, + CURVE25519_KEYSIZE, ltcPointOut->X, &resultSize, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + if (status == kStatus_Success) + { + if (ltcPointOut->Y != ltcPointIn->Y) + { + XMEMCPY(ltcPointOut->Y, ltcPointIn->Y, CURVE25519_KEYSIZE); + } + } + + return status; +} + +/* Y = square root (X^3 + 486662*X^2 + X) */ +status_t LTC_PKHA_Curve25519ComputeY(ltc_pkha_ecc_point_t *ltcPoint) +{ + uint8_t three = 3; + uint8_t A[] = {0x06, 0x6d, 0x07}; + uint8_t U[CURVE25519_KEYSIZE] = {0}; + uint8_t X2[CURVE25519_KEYSIZE] = {0}; + uint16_t sizeU = 0; + uint16_t sizeX2 = 0; + size_t szRes = 0; + status_t status; + + /* X^3 */ + status = LTC_PKHA_ModExp(LTC_BASE, ltcPoint->X, CURVE25519_KEYSIZE, modbin, CURVE25519_KEYSIZE, &three, 1, U, + &sizeU, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + + /* X^2 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, ltcPoint->X, CURVE25519_KEYSIZE, ltcPoint->X, CURVE25519_KEYSIZE, modbin, + CURVE25519_KEYSIZE, X2, &sizeX2, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + /* 486662*X^2 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, A, sizeof(A), X2, sizeX2, modbin, CURVE25519_KEYSIZE, X2, &sizeX2, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + /* X^3 + 486662*X^2 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, U, sizeU, X2, sizeX2, modbin, CURVE25519_KEYSIZE, U, &sizeU, + kLTC_PKHA_IntegerArith); + } + + /* U = X^3 + 486662*X^2 + X */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, U, sizeU, ltcPoint->X, CURVE25519_KEYSIZE, modbin, CURVE25519_KEYSIZE, U, + &sizeU, kLTC_PKHA_IntegerArith); + } + + /* Y = modular square root of U (U is Y^2) */ + if (status == kStatus_Success) + { + status = LTC_PKHA_Prime25519SquareRootMod(U, sizeU, ltcPoint->Y, &szRes, 1); + } + + return status; +} + +/* Q = n*P */ +/* if type is set, the input point p is in Montgomery curve coordinates, so there is a map to Weierstrass curve */ +/* q output point is always in Montgomery curve coordinates */ +int wc_curve25519(ECPoint *q, byte *n, ECPoint *p, fsl_ltc_ecc_coordinate_system_t type) +{ + status_t status; + ltc_pkha_ecc_point_t ltcPoint; + ltc_pkha_ecc_point_t ltcPointOut; + ECPoint pIn = {{0}}; + + XMEMCPY(&pIn, p, sizeof(*p)); + ltcPoint.X = &pIn.point[0]; + ltcPoint.Y = &pIn.pointY[0]; + + /* if input point P is on Curve25519 Montgomery curve, transform it to Weierstrass equivalent */ + if (type == kLTC_Curve25519) + { + LTC_PKHA_Curve25519ToWeierstrass(<cPoint, <cPoint); + } + + ltcPointOut.X = &q->point[0]; + ltcPointOut.Y = &q->pointY[0]; + /* modbin, r2mod, aCurveParam, bCurveParam are Weierstrass equivalent with Curve25519 */ + status = LTC_PKHA_ECC_PointMul(LTC_BASE, <cPoint, n, CURVE25519_KEYSIZE, modbin, r2mod, aCurveParam, bCurveParam, + CURVE25519_KEYSIZE, kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, <cPointOut, + NULL); + + /* now need to map from Weierstrass form to Montgomery form */ + if (status == kStatus_Success) + { + status = LTC_PKHA_WeierstrassToCurve25519(<cPointOut, <cPointOut); + } + + if (status == kStatus_Success) + return 0; + else + return IS_POINT_E; +} + +#endif /* HAVE_CURVE25519 */ + +#ifdef HAVE_ED25519 +#include + +/* a and d are Edwards curve parameters -1 and -121665/121666 prime is 2^255 - 19. + * + * + * + * https://en.wikipedia.org/wiki/Montgomery_curve#Equivalence_with_Edward_curves + */ + +/* d parameter of ed25519 */ +static const uint8_t d_coefEd25519[] = {0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 0xab, 0xd8, 0x41, + 0x41, 0x4d, 0x0a, 0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, + 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52}; + +/* Montgomery curve parameter A for a Montgomery curve equivalent with ed25519 */ +static const uint8_t A_coefEd25519[] = {0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +/* Montgomery curve parameter B for a Montgomery curve equivalent with ed25519 */ +static const uint8_t B_coefEd25519[] = {0xe5, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; + +/* these are pre-computed constants used in computations */ + +/* = 3*B */ +static const uint8_t threeB_coefEd25519[] = {0xd5, 0xb8, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; + +/* = -A */ +static const uint8_t minus_A_coefEd25519[] = {0xe7, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; + +/* = 1/B */ +static const uint8_t invB_coefEd25519[] = {0xc4, 0xa1, 0x29, 0x7b, 0x8d, 0x2c, 0x85, 0x22, 0xd5, 0x89, 0xaf, + 0xaf, 0x6c, 0xfd, 0xe3, 0xff, 0xd9, 0x85, 0x21, 0xa2, 0xe1, 0x2f, + 0xce, 0x1c, 0x63, 0x00, 0x24, 0x75, 0xc4, 0x24, 0x7f, 0x6b}; + +/* = 1/(3*B) */ +static const uint8_t A_mul_invThreeB_coefEd25519[] = {0xb9, 0x3e, 0xe4, 0xad, 0xa1, 0x37, 0xa7, 0x93, 0x1c, 0xa4, 0x35, + 0xe0, 0x0c, 0x57, 0xbd, 0xaa, 0x6e, 0x51, 0x94, 0x3e, 0x14, 0xe0, + 0xcb, 0xec, 0xbd, 0xff, 0xe7, 0xb1, 0x27, 0x92, 0x00, 0x63}; + +/* Weierstrass curve parameter a for a Weierstrass curve equivalent with ed25519 */ +static const uint8_t a_coefEd25519[] = {0x2d, 0x17, 0xbc, 0xf8, 0x8e, 0xe1, 0x71, 0xac, 0xf7, 0x2a, 0xa5, + 0x0c, 0x5d, 0xb6, 0xb8, 0x6b, 0xd6, 0x3d, 0x7b, 0x61, 0x0d, 0xe1, + 0x97, 0x31, 0xe6, 0xbe, 0xb9, 0xa5, 0xd3, 0xac, 0x4e, 0x5d}; + +/* Weierstrass curve parameter b for a Weierstrass curve equivalent with ed25519 */ +static const uint8_t b_coefEd25519[] = {0xa4, 0xb2, 0x64, 0xf3, 0xc1, 0xeb, 0x04, 0x90, 0x32, 0xbc, 0x9f, + 0x6b, 0x97, 0x31, 0x48, 0xf5, 0xd5, 0x80, 0x57, 0x10, 0x06, 0xdb, + 0x0d, 0x55, 0xe0, 0xb3, 0xd0, 0xcf, 0x9b, 0xb2, 0x11, 0x1d}; + +/* Ed25519 basepoint B mapped to Weierstrass equivalent */ +static uint8_t Wx_Ed25519[ED25519_KEY_SIZE] = {0x35, 0xef, 0x5a, 0x02, 0x9b, 0xc8, 0x55, 0xca, 0x9a, 0x7c, 0x61, + 0x0d, 0xdf, 0x3f, 0xc1, 0xa9, 0x18, 0x06, 0xc2, 0xf1, 0x02, 0x8f, + 0x0b, 0xf0, 0x39, 0x03, 0x2c, 0xd0, 0x0f, 0xdd, 0x78, 0x2a}; +static uint8_t Wy_Ed25519[ED25519_KEY_SIZE] = {0x14, 0x1d, 0x2c, 0xf6, 0xf3, 0x30, 0x78, 0x9b, 0x65, 0x31, 0x71, + 0x80, 0x61, 0xd0, 0x6f, 0xcf, 0x23, 0x83, 0x79, 0x63, 0xa5, 0x3b, + 0x48, 0xbe, 0x2e, 0xa2, 0x1d, 0xc7, 0xa5, 0x44, 0xc6, 0x29}; + +static const ltc_pkha_ecc_point_t basepointEd25519 = { + Wx_Ed25519, Wy_Ed25519, +}; + +const ltc_pkha_ecc_point_t *LTC_PKHA_Ed25519_BasePoint(void) +{ + return &basepointEd25519; +} + +/* input point is on Weierstrass curve, typeOut determines the coordinates system of output point (either Weierstrass or + * Ed25519) */ +status_t LTC_PKHA_Ed25519_PointMul(const ltc_pkha_ecc_point_t *ltcPointIn, + const uint8_t *N, + size_t sizeN, + ltc_pkha_ecc_point_t *ltcPointOut, + fsl_ltc_ecc_coordinate_system_t typeOut) +{ + uint16_t szN = (uint16_t)sizeN; + status_t status; + /* input on W, output in W, W parameters of ECC curve are Ed25519 curve parameters mapped to Weierstrass curve */ + status = + LTC_PKHA_ECC_PointMul(LTC_BASE, ltcPointIn, N, szN, modbin, r2mod, a_coefEd25519, b_coefEd25519, + ED25519_KEY_SIZE, kLTC_PKHA_TimingEqualized, kLTC_PKHA_IntegerArith, ltcPointOut, NULL); + + /* Weierstrass coordinates to Ed25519 coordinates */ + if ((status == kStatus_Success) && (typeOut == kLTC_Ed25519)) + { + status = LTC_PKHA_WeierstrassToEd25519(ltcPointOut, ltcPointOut); + } + return status; +} + +status_t LTC_PKHA_Ed25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut) +{ + status_t status; + uint8_t Mx[ED25519_KEY_SIZE] = {0}; + uint8_t My[ED25519_KEY_SIZE] = {0}; + uint8_t temp[ED25519_KEY_SIZE] = {0}; + uint8_t temp2[ED25519_KEY_SIZE] = {0}; + uint8_t max[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const uint8_t *Ex; + const uint8_t *Ey; + uint8_t *Gx; + uint8_t *Gy; + uint16_t szMx = 0; + uint16_t szGx = 0; + uint16_t szMy = 0; + uint16_t szGy = 0; + uint16_t szTemp = 0; + uint16_t szTemp2 = 0; + uint8_t one = 1; + + Ex = ltcPointIn->X; + Ey = ltcPointIn->Y; + Gx = ltcPointOut->X; + Gy = ltcPointOut->Y; + /* # (Ex, Ey) on Ed (a_ed, d) to (x, y) on M (A,B) + Mx = (1 + Ey) * ModularArithmetic.invert(1 - Ey, prime) % prime + My = (1 + Ey) * ModularArithmetic.invert((1 - Ey)*Ex, prime) % prime */ + + /* Gx = ((Mx * ModularArithmetic.invert(B, prime)) + (A * ModularArithmetic.invert(3*B, prime))) % prime + Gy = (My * ModularArithmetic.invert(B, prime)) % prime */ + + /* temp = 1 + Ey */ + status = LTC_PKHA_ModAdd(LTC_BASE, Ey, ED25519_KEY_SIZE, &one, sizeof(one), modbin, sizeof(modbin), temp, &szTemp, + kLTC_PKHA_IntegerArith); + + /* temp2 = 1 - Ey = 1 + (p - Ey) */ + if (status == kStatus_Success) + { + status = + LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), Ey, ED25519_KEY_SIZE, max, sizeof(max), temp2, &szTemp2); + } + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, temp2, szTemp2, &one, sizeof(one), modbin, sizeof(modbin), temp2, &szTemp2, + kLTC_PKHA_IntegerArith); + } + + /* Mx = ModInv(temp2,prime) */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModInv(LTC_BASE, temp2, szTemp2, modbin, sizeof(modbin), Mx, &szMx, kLTC_PKHA_IntegerArith); + } + + /* Mx = Mx * temp */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, Mx, szMx, temp, szTemp, modbin, ED25519_KEY_SIZE, Mx, &szMx, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + /* My = temp2 * Ex */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, Ex, ED25519_KEY_SIZE, temp2, szTemp2, modbin, ED25519_KEY_SIZE, My, &szMy, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + /* My = ModInv(My, prime) */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModInv(LTC_BASE, My, szMy, modbin, sizeof(modbin), My, &szMy, kLTC_PKHA_IntegerArith); + } + /* My = My * temp */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, My, szMy, temp, szTemp, modbin, ED25519_KEY_SIZE, My, &szMy, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + /* Gx = Mx * invB_coefEd25519 + A_mul_invThreeB_coefEd25519 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, Mx, szMx, invB_coefEd25519, sizeof(invB_coefEd25519), modbin, + ED25519_KEY_SIZE, Gx, &szGx, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, Gx, szGx, A_mul_invThreeB_coefEd25519, sizeof(A_mul_invThreeB_coefEd25519), + modbin, sizeof(modbin), Gx, &szGx, kLTC_PKHA_IntegerArith); + } + + /* Gy = My * invB_coefEd25519 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, My, szMy, invB_coefEd25519, sizeof(invB_coefEd25519), modbin, + ED25519_KEY_SIZE, Gy, &szGy, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + return status; +} + +/* +# (Gx, Gy) on W to (Ex, Ey) on E +My = (B*Gy) % prime +Mx = ((3*B*Gx-A)*ModularArithmetic.invert(3, prime)) % prime +Ex = Mx*ModularArithmetic.invert(My, prime) % prime +Ey = (Mx - 1)*ModularArithmetic.invert(Mx + 1, prime) % prime +*/ +status_t LTC_PKHA_WeierstrassToEd25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut) +{ + status_t status; + uint8_t Mx[ED25519_KEY_SIZE] = {0}; + uint8_t My[ED25519_KEY_SIZE] = {0}; + uint8_t temp[ED25519_KEY_SIZE] = {0}; + const uint8_t *Gx; + const uint8_t *Gy; + uint8_t *Ex; + uint8_t *Ey; + uint16_t szMx = 0; + uint16_t szEx = 0; + uint16_t szMy = 0; + uint16_t szEy = 0; + uint16_t szTemp = 0; + uint8_t one = 1; + + Gx = ltcPointIn->X; + Gy = ltcPointIn->Y; + Ex = ltcPointOut->X; + Ey = ltcPointOut->Y; + + /* My = (B*Gy) % prime */ + status = LTC_PKHA_ModMul(LTC_BASE, B_coefEd25519, sizeof(B_coefEd25519), Gy, ED25519_KEY_SIZE, modbin, + ED25519_KEY_SIZE, My, &szMy, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + + /* temp = 3*B*Gx mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, threeB_coefEd25519, sizeof(threeB_coefEd25519), Gx, ED25519_KEY_SIZE, modbin, + ED25519_KEY_SIZE, temp, &szTemp, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + /* temp = (temp - A) mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, temp, szTemp, minus_A_coefEd25519, sizeof(minus_A_coefEd25519), modbin, + sizeof(modbin), temp, &szTemp, kLTC_PKHA_IntegerArith); + } + /* Mx = (temp/3) mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, temp, szTemp, invThree, sizeof(invThree), modbin, sizeof(modbin), Mx, &szMx, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + /* temp = 1/My mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModInv(LTC_BASE, My, szMy, modbin, sizeof(modbin), temp, &szTemp, kLTC_PKHA_IntegerArith); + } + /* Ex = Mx * temp mod p */ + if (status == kStatus_Success) + { + status = + LTC_PKHA_ModMul(LTC_BASE, temp, szTemp, Mx, szMx, modbin, sizeof(modbin), Ex, &szEx, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + /* temp = Mx + 1 mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, Mx, szMx, &one, sizeof(one), modbin, sizeof(modbin), temp, &szTemp, + kLTC_PKHA_IntegerArith); + } + /* temp = 1/temp mod p */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModInv(LTC_BASE, temp, szTemp, modbin, sizeof(modbin), temp, &szTemp, kLTC_PKHA_IntegerArith); + } + /* Mx = (Mx - 1) mod p */ + if (status == kStatus_Success) + { + if (LTC_PKHA_CompareBigNum(Mx, szMx, &one, sizeof(one)) >= 0) + { + status = LTC_PKHA_ModSub1(LTC_BASE, Mx, szMx, &one, sizeof(one), modbin, sizeof(modbin), Mx, &szMx); + } + else + { + /* Mx is zero, so it is modulus, thus we do modulus - 1 */ + XMEMCPY(Mx, modbin, sizeof(modbin)); + Mx[0]--; + } + } + /* Ey = Mx * temp mod p */ + if (status == kStatus_Success) + { + status = + LTC_PKHA_ModMul(LTC_BASE, temp, szTemp, Mx, szMx, modbin, sizeof(modbin), Ey, &szEy, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + return status; +} + +status_t LTC_PKHA_Ed25519_PointDecompress(const uint8_t *pubkey, size_t pubKeySize, ltc_pkha_ecc_point_t *ltcPointOut) +{ + status_t status; + uint8_t one = 1; + + /* pubkey contains the Y coordinate and a sign of X + */ + + /* x^2 = ((y^2 - 1) / (d*y^2 +1)) mod p */ + + /* decode Y from pubkey */ + XMEMCPY(ltcPointOut->Y, pubkey, pubKeySize); + ltcPointOut->Y[pubKeySize - 1] &= ~0x80u; + int sign = (int)(bool)(pubkey[pubKeySize - 1] & 0x80u); + + uint8_t U[ED25519_KEY_SIZE] = {0}; + uint8_t V[ED25519_KEY_SIZE] = {0}; + uint8_t *X = ltcPointOut->X; + uint8_t *Y = ltcPointOut->Y; + uint16_t szU = 0; + uint16_t szV = 0; + size_t szRes = 0; + + /* decode X from pubkey */ + + /* U = y * y mod p */ + status = LTC_PKHA_ModMul(LTC_BASE, Y, ED25519_KEY_SIZE, Y, ED25519_KEY_SIZE, modbin, ED25519_KEY_SIZE, U, &szU, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + XMEMCPY(V, U, szU); + szV = szU; + + /* U = U - 1 = y^2 - 1 */ + if (status == kStatus_Success) + { + if (LTC_PKHA_CompareBigNum(U, szU, &one, sizeof(one)) >= 0) + { + status = LTC_PKHA_ModSub1(LTC_BASE, U, szU, &one, sizeof(one), modbin, sizeof(modbin), U, &szU); + } + else + { + /* U is zero, so it is modulus, thus we do modulus - 1 */ + XMEMCPY(U, modbin, sizeof(modbin)); + U[0]--; + } + } + + /* V = d*y*y + 1 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, V, szV, d_coefEd25519, ED25519_KEY_SIZE, modbin, ED25519_KEY_SIZE, V, &szV, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, V, szV, &one, sizeof(one), modbin, sizeof(modbin), V, &szV, + kLTC_PKHA_IntegerArith); + } + + /* U = U / V (mod p) */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModInv(LTC_BASE, V, szV, modbin, sizeof(modbin), V, &szV, kLTC_PKHA_IntegerArith); + } + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, V, szV, U, szU, modbin, ED25519_KEY_SIZE, U, &szU, kLTC_PKHA_IntegerArith, + kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + } + + /* get square root */ + if (status == kStatus_Success) + { + status = LTC_PKHA_Prime25519SquareRootMod(U, szU, X, &szRes, sign); + } + + return status; +} + +/* LSByte first of Ed25519 parameter l = 2^252 + 27742317777372353535851937790883648493 */ +static const uint8_t l_coefEdDSA[] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; + +/* +Input: + s[0]+256*s[1]+...+256^63*s[63] = s + +Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. +*/ +status_t LTC_PKHA_sc_reduce(uint8_t *a) +{ + uint16_t szA = 0; + return LTC_PKHA_ModRed(LTC_BASE, a, 64, l_coefEdDSA, sizeof(l_coefEdDSA), a, &szA, kLTC_PKHA_IntegerArith); +} + +/* +Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + c[0]+256*c[1]+...+256^31*c[31] = c + +Output: + s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + where l = 2^252 + 27742317777372353535851937790883648493. +*/ +status_t LTC_PKHA_sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, const uint8_t *c) +{ + uint16_t szS = 0; + uint16_t szB = 0; + uint8_t tempB[32] = {0}; + status_t status; + + /* Assume only b can be larger than modulus. It is called durind wc_ed25519_sign_msg() where hram (=a) and nonce(=c) + * have been reduced by LTC_PKHA_sc_reduce() + * Thus reducing b only. + */ + status = LTC_PKHA_ModRed(LTC_BASE, b, 32, l_coefEdDSA, sizeof(l_coefEdDSA), tempB, &szB, kLTC_PKHA_IntegerArith); + + if (status == kStatus_Success) + { + status = LTC_PKHA_ModMul(LTC_BASE, a, 32, tempB, szB, l_coefEdDSA, sizeof(l_coefEdDSA), s, &szS, + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + } + + if (status == kStatus_Success) + { + status = LTC_PKHA_ModAdd(LTC_BASE, s, szS, c, 32, l_coefEdDSA, 32, s, &szS, kLTC_PKHA_IntegerArith); + } + + return status; +} + +/* +r = a * A + b * B +where A is public key point, B is basepoint +where a = a[0]+256*a[1]+...+256^31 a[31]. +and b = b[0]+256*b[1]+...+256^31 b[31]. +B is the Ed25519 base point (x,4/5) with x positive. +*/ +status_t LTC_PKHA_SignatureForVerify(uint8_t *rcheck, const unsigned char *a, const unsigned char *b, ed25519_key *key) +{ + /* To verify a signature on a message M, first split the signature + into two 32-octet halves. Decode the first half as a point R, + and the second half as an integer s, in the range 0 <= s < q. If + the decoding fails, the signature is invalid. */ + + /* Check the group equation 8s B = 8 R + 8k A. */ + + /* + Uses a fast single-signature verification SB = R + H(R,A,M)A becomes + SB - H(R,A,M)A saving decompression of R + */ + uint8_t X0[ED25519_PUB_KEY_SIZE] = {0}; + uint8_t X1[ED25519_PUB_KEY_SIZE] = {0}; + uint8_t Y0[ED25519_PUB_KEY_SIZE] = {0}; + uint8_t Y1[ED25519_PUB_KEY_SIZE] = {0}; + uint8_t max[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + ltc_pkha_ecc_point_t ltc0; + ltc_pkha_ecc_point_t ltc1; + ltc_pkha_ecc_point_t pubKey; + status_t status; + + ltc0.X = X0; + ltc1.X = X1; + ltc0.Y = Y0; + ltc1.Y = Y1; + pubKey.X = key->pointX; + pubKey.Y = key->pointY; + + /* ltc0 = b*B */ + status = LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), b, ED25519_KEY_SIZE, <c0, + kLTC_Weierstrass /* result in W */); + + /* ltc1 = a*A */ + if (status == kStatus_Success) + { + status = LTC_PKHA_Ed25519ToWeierstrass(&pubKey, <c1); + } + if (status == kStatus_Success) + { + status = LTC_PKHA_Ed25519_PointMul(<c1, a, ED25519_KEY_SIZE, <c1, kLTC_Weierstrass /* result in W */); + } + + /* The equality for the negative of a point P, in affine coordinates, is -P = -(x,y) = (x, -y) */ + uint16_t szY = 32; + + /* R = b*B - a*A */ + if (status == kStatus_Success) + { + status = LTC_PKHA_ModSub1(LTC_BASE, modbin, sizeof(modbin), ltc1.Y, szY, max, sizeof(max), ltc1.Y, &szY); + } + if (status == kStatus_Success) + { + status = LTC_PKHA_ECC_PointAdd(LTC_BASE, <c0, <c1, modbin, r2mod, a_coefEd25519, b_coefEd25519, + ED25519_KEY_SIZE, kLTC_PKHA_IntegerArith, <c0); + } + /* map to Ed25519 */ + if (status == kStatus_Success) + { + status = LTC_PKHA_WeierstrassToEd25519(<c0, <c0); + } + if (((uint32_t)ltc0.X[0]) & 0x01u) + { + ltc0.Y[ED25519_KEY_SIZE - 1] |= 0x80u; + } + + XMEMCPY(rcheck, ltc0.Y, ED25519_KEY_SIZE); + return status; +} + +status_t LTC_PKHA_Ed25519_Compress(const ltc_pkha_ecc_point_t *ltcPointIn, uint8_t *p) +{ + /* compress */ + /* get sign of X per https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02 + * To form the encoding of the point, copy the least + significant bit of the x-coordinate to the most significant bit of + the final octet + */ + XMEMCPY(p, ltcPointIn->Y, ED25519_KEY_SIZE); + if (((uint32_t)ltcPointIn->X[0]) & 0x01u) + { + p[ED25519_KEY_SIZE - 1] |= 0x80u; + } + return kStatus_Success; +} + +#endif + +#endif /* FREESCALE_LTC_ECC */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index bddbe80c4..b953e2dd7 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -157,6 +157,10 @@ int wc_FreeRng(WC_RNG* rng) #ifndef EBSNET #include #endif + #elif defined(FREESCALE_KSDK_2_0_TRNG) + #include "fsl_trng.h" + #elif defined(FREESCALE_KSDK_2_0_RNGA) + #include "fsl_rnga.h" #else /* include headers that may be needed to get good seed */ #endif @@ -1356,12 +1360,36 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return 0; } - #elif defined(FREESCALE_TRNG) + #elif defined(FREESCALE_KSDK_2_0_TRNG) int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { - TRNG_DRV_GetRandomData(TRNG_INSTANCE, output, sz); - return 0; + status_t status; + status = TRNG_GetRandomData(TRNG0, output, sz); + if (status == kStatus_Success) + { + return(0); + } + else + { + return RAN_BLOCK_E; + } + } + + #elif defined(FREESCALE_KSDK_2_0_RNGA) + + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + status_t status; + status = RNGA_GetRandomData(RNG, output, sz); + if (status == kStatus_Success) + { + return(0); + } + else + { + return RAN_BLOCK_E; + } } diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 29ab190b8..6365b9e84 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -153,6 +153,10 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, static int FreeAsyncRsaKey(RsaKey* key); #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef FREESCALE_LTC_TFM + #include +#endif + enum { RSA_STATE_NONE = 0, @@ -1125,6 +1129,7 @@ static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out, } #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifndef FREESCALE_LTC_TFM int wc_RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng) { @@ -1151,6 +1156,7 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out, } return ret; } +#endif /* !FREESCALE_LTC_TFM */ /* Internal Wrappers */ @@ -1161,7 +1167,7 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out, outLen: length of encrypted output buffer key : wolfSSL initialized RSA key struct rng : wolfSSL initialized random number struct - rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, + rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2 pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD @@ -1256,7 +1262,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, outLen: length of decrypted message in bytes outPtr: optional inline output pointer (if provided doing inline) key : wolfSSL initialized RSA key struct - rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, + rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2 pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD @@ -1403,7 +1409,7 @@ int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) #ifdef WC_RSA_BLINDING rng = key->rng; #endif - return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, + return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } @@ -1418,7 +1424,7 @@ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out, #ifdef WC_RSA_BLINDING rng = key->rng; #endif - return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, + return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, rng); } @@ -1461,7 +1467,7 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) #ifdef WC_RSA_BLINDING rng = key->rng; #endif - return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, + return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } @@ -1473,7 +1479,7 @@ int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, #ifdef WC_RSA_BLINDING rng = key->rng; #endif - return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, + return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng); } @@ -1619,16 +1625,16 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) err = mp_copy(&q, &key->q); if (err == MP_OKAY) - key->type = RSA_PRIVATE; + key->type = RSA_PRIVATE; - mp_clear(&tmp3); - mp_clear(&tmp2); - mp_clear(&tmp1); - mp_clear(&q); + mp_clear(&tmp3); + mp_clear(&tmp2); + mp_clear(&tmp1); + mp_clear(&q); mp_clear(&p); if (err != MP_OKAY) { - wc_FreeRsaKey(key); + wc_FreeRsaKey(key); return err; } diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 9de702a45..f91a0fda3 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -72,8 +72,8 @@ #endif -#ifdef FREESCALE_MMCAU - #include "cau_api.h" +#ifdef FREESCALE_MMCAU_SHA + #include "fsl_mmcau.h" #define XTRANSFORM(S,B) Transform((S), (B)) #else #define XTRANSFORM(S,B) Transform((S)) @@ -209,16 +209,22 @@ int wc_ShaFinal(Sha* sha, byte* hash) #endif /* WOLFSSL_HAVE_MIN */ - +#ifdef FREESCALE_LTC_SHA +int wc_InitSha(Sha* sha) +{ + LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0); + return 0; +} +#else /* FREESCALE_LTC_SHA */ int wc_InitSha(Sha* sha) { int ret = 0; -#ifdef FREESCALE_MMCAU +#ifdef FREESCALE_MMCAU_SHA ret = wolfSSL_CryptHwMutexLock(); if(ret != 0) { return ret; } - cau_sha1_initialize_output(sha->digest); + MMCAU_SHA1_InitializeOutput((uint32_t*)sha->digest); wolfSSL_CryptHwMutexUnLock(); #else sha->digest[0] = 0x67452301L; @@ -234,20 +240,21 @@ int wc_InitSha(Sha* sha) return ret; } +#endif /* FREESCALE_LTC_SHA */ -#ifdef FREESCALE_MMCAU +#ifdef FREESCALE_MMCAU_SHA static int Transform(Sha* sha, byte* data) { int ret = wolfSSL_CryptHwMutexLock(); if(ret == 0) { - cau_sha1_hash_n(data, 1, sha->digest); + MMCAU_SHA1_HashN(data, 1, (uint32_t*)sha->digest); wolfSSL_CryptHwMutexUnLock(); } return ret; } -#endif /* FREESCALE_MMCAU */ +#endif /* FREESCALE_MMCAU_SHA */ -#ifndef FREESCALE_MMCAU +#if !(defined(FREESCALE_MMCAU_SHA) || defined(FREESCALE_LTC_SHA)) #define blk0(i) (W[i] = sha->buffer[i]) #define blk1(i) (W[(i)&15] = \ @@ -345,9 +352,15 @@ static void Transform(Sha* sha) sha->digest[4] += e; } -#endif /* FREESCALE_MMCAU */ - +#endif /* FREESCALE_MMCAU_SHA */ +#ifdef FREESCALE_LTC_SHA +int wc_ShaUpdate(Sha* sha, const byte* data, word32 len) +{ + LTC_HASH_Update(&sha->ctx, data, len); + return 0; +} +#else /* FREESCALE_LTC_SHA */ static INLINE void AddLength(Sha* sha, word32 len) { word32 tmp = sha->loLen; @@ -370,7 +383,7 @@ int wc_ShaUpdate(Sha* sha, const byte* data, word32 len) len -= add; if (sha->buffLen == SHA_BLOCK_SIZE) { -#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) +#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE); #endif XTRANSFORM(sha, local); @@ -381,8 +394,16 @@ int wc_ShaUpdate(Sha* sha, const byte* data, word32 len) return 0; } +#endif /* FREESCALE_LTC_SHA */ - +#ifdef FREESCALE_LTC_SHA +int wc_ShaFinal(Sha* sha, byte* hash) +{ + uint32_t hashlen = SHA_DIGEST_SIZE; + LTC_HASH_Finish(&sha->ctx, hash, &hashlen); + return wc_InitSha(sha); /* reset state */ +} +#else /* FREESCALE_LTC_SHA */ int wc_ShaFinal(Sha* sha, byte* hash) { byte* local = (byte*)sha->buffer; @@ -396,7 +417,7 @@ int wc_ShaFinal(Sha* sha, byte* hash) XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen); sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen; -#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) +#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE); #endif XTRANSFORM(sha, local); @@ -410,14 +431,14 @@ int wc_ShaFinal(Sha* sha, byte* hash) sha->loLen = sha->loLen << 3; /* store lengths */ -#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) +#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE); #endif /* ! length ordering dependent on digest endian type ! */ XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); -#ifdef FREESCALE_MMCAU +#ifdef FREESCALE_MMCAU_SHA /* Kinetis requires only these bytes reversed */ ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)], &sha->buffer[SHA_PAD_SIZE/sizeof(word32)], @@ -432,6 +453,7 @@ int wc_ShaFinal(Sha* sha, byte* hash) return wc_InitSha(sha); /* reset state */ } +#endif /* FREESCALE_LTC_SHA */ #endif /* STM32F2_HASH */ diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 715b97176..abe8c1d51 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -250,7 +250,7 @@ static void set_Transform(void) { } #else - #if defined(FREESCALE_MMCAU) + #if defined(FREESCALE_MMCAU_SHA) #define XTRANSFORM(sha256, B) Transform(sha256, B) #else #define XTRANSFORM(sha256, B) Transform(sha256) @@ -285,8 +285,8 @@ static void set_Transform(void) { #include #endif -#ifdef FREESCALE_MMCAU - #include "cau_api.h" +#ifdef FREESCALE_MMCAU_SHA + #include "fsl_mmcau.h" #endif #ifndef WOLFSSL_HAVE_MIN @@ -299,16 +299,22 @@ static void set_Transform(void) { #endif /* WOLFSSL_HAVE_MIN */ - +#ifdef FREESCALE_LTC_SHA +int wc_InitSha256(Sha256* sha256) +{ + LTC_HASH_Init(LTC_BASE, &sha256->ctx, kLTC_Sha256, NULL, 0); + return 0; +} +#else int wc_InitSha256(Sha256* sha256) { int ret = 0; - #ifdef FREESCALE_MMCAU + #ifdef FREESCALE_MMCAU_SHA ret = wolfSSL_CryptHwMutexLock(); if(ret != 0) { return ret; } - cau_sha256_initialize_output(sha256->digest); + MMCAU_SHA256_InitializeOutput((uint32_t*)sha256->digest); wolfSSL_CryptHwMutexUnLock(); #else sha256->digest[0] = 0x6A09E667L; @@ -331,9 +337,10 @@ int wc_InitSha256(Sha256* sha256) return ret; } +#endif /* FREESCALE_LTC_SHA */ - -#if !defined(FREESCALE_MMCAU) +#if !defined(FREESCALE_LTC_SHA) +#if !defined(FREESCALE_MMCAU_SHA) static const ALIGN32 word32 K[64] = { 0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL, 0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L, @@ -352,19 +359,19 @@ static const ALIGN32 word32 K[64] = { #endif -#if defined(FREESCALE_MMCAU) +#if defined(FREESCALE_MMCAU_SHA) static int Transform(Sha256* sha256, byte* buf) { int ret = wolfSSL_CryptHwMutexLock(); if(ret == 0) { - cau_sha256_hash_n(buf, 1, sha256->digest); + MMCAU_SHA256_HashN(buf, 1, (uint32_t*)sha256->digest); wolfSSL_CryptHwMutexUnLock(); } return ret; } -#endif /* FREESCALE_MMCAU */ +#endif /* FREESCALE_MMCAU_SHA */ #define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y))) @@ -382,7 +389,7 @@ static int Transform(Sha256* sha256, byte* buf) (d) += t0; \ (h) = t0 + t1; -#if !defined(FREESCALE_MMCAU) +#if !defined(FREESCALE_MMCAU_SHA) static int Transform(Sha256* sha256) { word32 S[8], t0, t1; @@ -431,7 +438,7 @@ static int Transform(Sha256* sha256) return 0; } -#endif /* #if !defined(FREESCALE_MMCAU) */ +#endif /* #if !defined(FREESCALE_MMCAU_SHA) */ static INLINE void AddLength(Sha256* sha256, word32 len) { @@ -439,8 +446,16 @@ static INLINE void AddLength(Sha256* sha256, word32 len) if ( (sha256->loLen += len) < tmp) sha256->hiLen++; /* carry low to high */ } +#endif /* FREESCALE_LTC_SHA */ -static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len) +#ifdef FREESCALE_LTC_SHA +int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) +{ + LTC_HASH_Update(&sha256->ctx, data, len); + return 0; +} +#else +int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) { /* do block size increments */ @@ -459,7 +474,7 @@ static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len) if (sha256->buffLen == SHA256_BLOCK_SIZE) { int ret; - #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) #endif @@ -477,13 +492,17 @@ static INLINE int Sha256Update(Sha256* sha256, const byte* data, word32 len) return 0; } +#endif /* FREESCALE_LTC_SHA */ -int wc_Sha256Update(Sha256* sha256, const byte* data, word32 len) +#ifdef FREESCALE_LTC_SHA +int wc_Sha256Final(Sha256* sha256, byte* hash) { - return Sha256Update(sha256, data, len); + uint32_t hashlen = SHA256_DIGEST_SIZE; + LTC_HASH_Finish(&sha256->ctx, hash, &hashlen); + return wc_InitSha256(sha256); /* reset state */ } - -static INLINE int Sha256Final(Sha256* sha256) +#else +int wc_Sha256Final(Sha256* sha256, byte* hash) { byte* local = (byte*)sha256->buffer; int ret; @@ -499,7 +518,7 @@ static INLINE int Sha256Final(Sha256* sha256) XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen); sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen; - #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) #endif @@ -520,7 +539,7 @@ static INLINE int Sha256Final(Sha256* sha256) sha256->loLen = sha256->loLen << 3; /* store lengths */ - #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) + #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) if(!IS_INTEL_AVX1 && !IS_INTEL_AVX2) #endif @@ -531,7 +550,7 @@ static INLINE int Sha256Final(Sha256* sha256) XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, sizeof(word32)); - #if defined(FREESCALE_MMCAU) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(FREESCALE_MMCAU_SHA) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) /* Kinetis requires only these bytes reversed */ #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) if(IS_INTEL_AVX1 || IS_INTEL_AVX2) @@ -559,6 +578,8 @@ int wc_Sha256Final(Sha256* sha256, byte* hash) return wc_InitSha256(sha256); /* reset state */ } +#endif /* FREESCALE_LTC_SHA */ + #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 59b809316..80d304cac 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -50,6 +50,9 @@ #include #include /* will define asm MACROS or C ones */ +#if defined(FREESCALE_LTC_TFM) + #include "nxp/ksdk_port.h" +#endif #ifdef WOLFSSL_DEBUG_MATH #include #endif @@ -194,7 +197,11 @@ void s_fp_sub(fp_int *a, fp_int *b, fp_int *c) } /* c = a * b */ +#if defined(FREESCALE_LTC_TFM) +void wolfcrypt_fp_mul(fp_int *A, fp_int *B, fp_int *C) +#else void fp_mul(fp_int *A, fp_int *B, fp_int *C) +#endif { int y, yy, oldused; @@ -736,7 +743,11 @@ void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d) } /* c = a mod b, 0 <= c < b */ +#if defined(FREESCALE_LTC_TFM) +int wolfcrypt_fp_mod(fp_int *a, fp_int *b, fp_int *c) +#else int fp_mod(fp_int *a, fp_int *b, fp_int *c) +#endif { fp_int t; int err; @@ -886,9 +897,12 @@ top: return FP_OKAY; } - /* c = 1/a (mod b) for odd b only */ +#if defined(FREESCALE_LTC_TFM) +int wolfcrypt_fp_invmod(fp_int *a, fp_int *b, fp_int *c) +#else int fp_invmod(fp_int *a, fp_int *b, fp_int *c) +#endif { fp_int x, y, u, v, B, D; int neg; @@ -980,7 +994,11 @@ top: } /* d = a * b (mod c) */ +#if defined(FREESCALE_LTC_TFM) +int wolfcrypt_fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) +#else int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) +#endif { int err; fp_int t; @@ -1059,7 +1077,11 @@ const wolfssl_word wc_off_on_addr[2] = Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002 */ +#if defined(FREESCALE_LTC_TFM) +int _wolfcrypt_fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +#else static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +#endif { #ifdef WC_NO_CACHE_RESISTANT fp_int R[2]; @@ -1929,6 +1951,15 @@ void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c) fp_clamp (a); } +int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b) +{ + while (fp_iszero (t) == FP_NO) { + b[x++] = (unsigned char) (t->dp[0] & 255); + fp_div_2d (t, 8, t, NULL); + } + return x; +} + void fp_to_unsigned_bin(fp_int *a, unsigned char *b) { int x; @@ -1936,11 +1967,7 @@ void fp_to_unsigned_bin(fp_int *a, unsigned char *b) fp_init_copy(&t, a); - x = 0; - while (fp_iszero (&t) == FP_NO) { - b[x++] = (unsigned char) (t.dp[0] & 255); - fp_div_2d (&t, 8, &t, NULL); - } + x = fp_to_unsigned_bin_at_pos(0, &t, b); fp_reverse (b, x); } diff --git a/wolfssl/wolfcrypt/curve25519.h b/wolfssl/wolfcrypt/curve25519.h index d775877bf..d3a39eafc 100644 --- a/wolfssl/wolfcrypt/curve25519.h +++ b/wolfssl/wolfcrypt/curve25519.h @@ -47,6 +47,9 @@ typedef struct { * the mathematical functions used the endianess */ typedef struct { byte point[CURVE25519_KEYSIZE]; + #ifdef FREESCALE_LTC_ECC + byte pointY[CURVE25519_KEYSIZE]; + #endif }ECPoint; /* A CURVE25519 Key */ diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index 103a06599..ea88603a3 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -58,6 +58,11 @@ typedef struct { byte p[ED25519_PUB_KEY_SIZE]; /* compressed public key */ byte k[ED25519_PRV_KEY_SIZE]; /* private key : 32 secret -- 32 public */ +#ifdef FREESCALE_LTC_ECC + /* uncompressed point coordinates */ + byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */ + byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */ +#endif } ed25519_key; diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h index 1d0a801ef..ae15dab1f 100644 --- a/wolfssl/wolfcrypt/fe_operations.h +++ b/wolfssl/wolfcrypt/fe_operations.h @@ -47,7 +47,9 @@ Bounds on each t[i] vary depending on context. typedef int32_t fe[10]; #endif +#if! defined FREESCALE_LTC_ECC WOLFSSL_LOCAL int curve25519(byte * q, byte * n, byte * p); +#endif WOLFSSL_LOCAL void fe_copy(fe, const fe); WOLFSSL_LOCAL void fe_add(fe, const fe, const fe); WOLFSSL_LOCAL void fe_neg(fe,const fe); diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index bc94891a4..4dddbc687 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -64,7 +64,8 @@ noinst_HEADERS+= \ wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \ wolfssl/wolfcrypt/port/ti/ti-hash.h \ wolfssl/wolfcrypt/port/ti/ti-ccm.h \ - wolfssl/wolfcrypt/port/nrf51.h + wolfssl/wolfcrypt/port/nrf51.h \ + wolfssl/wolfcrypt/port/nxp/ksdk_port.h if BUILD_CAVIUM noinst_HEADERS+= wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h diff --git a/wolfssl/wolfcrypt/port/nxp/ksdk_port.h b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h new file mode 100755 index 000000000..703bf692b --- /dev/null +++ b/wolfssl/wolfcrypt/port/nxp/ksdk_port.h @@ -0,0 +1,75 @@ +/* ksdk_port.h + * + * Copyright (C) 2006-2016 wolfSSL Inc. All rights reserved. + * + * This file is part of wolfSSL. + * + * Contact licensing@wolfssl.com with any questions or comments. + * + * http://www.wolfssl.com + */ + +#ifndef _KSDK_PORT_H_ +#define _KSDK_PORT_H_ + +#include +#include +#include +#include +#include + +/* software algorithm, by wolfcrypt */ +#if defined(FREESCALE_LTC_TFM) + void wolfcrypt_fp_mul(fp_int *A, fp_int *B, fp_int *C); + int wolfcrypt_fp_mod(fp_int *a, fp_int *b, fp_int *c); + int wolfcrypt_fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); + int wolfcrypt_fp_mod(fp_int *a, fp_int *b, fp_int *c); + 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); + #endif +#endif /* FREESCALE_LTC_TFM */ + +#if defined(FREESCALE_LTC_ECC) + + #include "fsl_ltc.h" + + typedef enum _fsl_ltc_ecc_coordinate_system + { + kLTC_Weierstrass = 0U, /*!< Point coordinates on an elliptic curve in Weierstrass form */ + kLTC_Curve25519 = 1U, /*!< Point coordinates on an Curve25519 elliptic curve in Montgomery form */ + kLTC_Ed25519 = 2U, /*!< Point coordinates on an Ed25519 elliptic curve in twisted Edwards form */ + } fsl_ltc_ecc_coordinate_system_t; + + int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m); + + #ifdef HAVE_CURVE25519 + int wc_curve25519(ECPoint *q, byte *n, ECPoint *p, fsl_ltc_ecc_coordinate_system_t type); + ECPoint *wc_curve25519_GetBasePoint(void); + status_t LTC_PKHA_Curve25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_WeierstrassToCurve25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_Curve25519ComputeY(ltc_pkha_ecc_point_t *ltcPoint); + #endif + + #ifdef HAVE_ED25519 + status_t LTC_PKHA_Ed25519ToWeierstrass(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_WeierstrassToEd25519(const ltc_pkha_ecc_point_t *ltcPointIn, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_Ed25519_PointMul(const ltc_pkha_ecc_point_t *ltcPointIn, + const uint8_t *N, + size_t sizeN, + ltc_pkha_ecc_point_t *ltcPointOut, + fsl_ltc_ecc_coordinate_system_t typeOut); + const ltc_pkha_ecc_point_t *LTC_PKHA_Ed25519_BasePoint(void); + status_t LTC_PKHA_Ed25519_PointDecompress(const uint8_t *pubkey, size_t pubKeySize, ltc_pkha_ecc_point_t *ltcPointOut); + status_t LTC_PKHA_sc_reduce(uint8_t *a); + status_t LTC_PKHA_sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, const uint8_t *c); + status_t LTC_PKHA_SignatureForVerify(uint8_t *rcheck, const unsigned char *a, const unsigned char *b, ed25519_key *key); + status_t LTC_PKHA_Ed25519_Compress(const ltc_pkha_ecc_point_t *ltcPointIn, uint8_t *p); + #endif + +#endif /* FREESCALE_LTC_ECC */ + +#endif /* _KSDK_PORT_H_ */ diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 9db159ce0..d7f5ccaf9 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -76,6 +76,7 @@ enum { RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */ }; + /* RSA */ typedef struct RsaKey { mp_int n, e, d, p, q, dP, dQ, u; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index cc5283fac..97ff1ff3c 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -85,8 +85,8 @@ /* Uncomment next line if building for Freescale KSDK Bare Metal */ /* #define FREESCALE_KSDK_BM */ -/* Uncomment next line if building for Freescale FreeRTOS */ -/* #define FREESCALE_FREE_RTOS */ +/* Uncomment next line if building for Freescale KSDK FreeRTOS (old name FREESCALE_FREE_RTOS) */ +/* #define FREESCALE_KSDK_FREERTOS */ /* Uncomment next line if using STM32F2 */ /* #define WOLFSSL_STM32F2 */ @@ -704,76 +704,207 @@ static char *fgets(char *buff, int sz, FILE *fp) #define MQX_FILE_PTR FILE * #define IO_SEEK_SET SEEK_SET #define IO_SEEK_END SEEK_END -#endif +#endif /* FREESCALE_KSDK_MQX */ + +#if defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS) + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + #define NO_FILESYSTEM + #define WOLFSSL_CRYPT_HW_MUTEX 1 + + #if !defined(XMALLOC_USER) && !defined(NO_WOLFSSL_MEMORY) + #define XMALLOC(s, h, type) pvPortMalloc((s)) + #define XFREE(p, h, type) vPortFree((p)) + #endif + + //#define USER_TICKS + /* Allows use of DH with fixed points if uncommented and NO_DH is removed */ + /* WOLFSSL_DH_CONST */ + #define WOLFSSL_LWIP + #define FREERTOS_TCP + + #define FREESCALE_FREE_RTOS + #define FREERTOS_SOCKET_ERROR ( -1 ) + #define FREERTOS_EWOULDBLOCK ( -2 ) + #define FREERTOS_EINVAL ( -4 ) + #define FREERTOS_EADDRNOTAVAIL ( -5 ) + #define FREERTOS_EADDRINUSE ( -6 ) + #define FREERTOS_ENOBUFS ( -7 ) + #define FREERTOS_ENOPROTOOPT ( -8 ) +#endif /* FREESCALE_FREE_RTOS || FREESCALE_KSDK_FREERTOS */ #ifdef FREESCALE_KSDK_BM #define FREESCALE_COMMON #define WOLFSSL_USER_IO #define SINGLE_THREADED #define NO_FILESYSTEM - #define USE_WOLFSSL_MEMORY -#endif - -#ifdef FREESCALE_FREE_RTOS - #define FREESCALE_COMMON - #define NO_FILESYSTEM - #define NO_MAIN_DRIVER - #define XMALLOC(s, h, t) OSA_MemAlloc(s);(void)h;(void)t; - #define XFREE(p, h, t) {void* xp = (p); if((xp)) OSA_MemFree((xp));} - #ifdef FREESCALE_KSDK_BM - #error Baremetal and FreeRTOS cannot be both enabled at the same time! - #endif - #ifndef SINGLE_THREADED - #include "FreeRTOS.h" - #include "semphr.h" - #endif -#endif + #define USER_TICKS +#endif /* FREESCALE_KSDK_BM */ #ifdef FREESCALE_COMMON #define SIZEOF_LONG_LONG 8 /* disable features */ + #undef NO_WRITEV #define NO_WRITEV + #undef NO_DEV_RANDOM #define NO_DEV_RANDOM + #undef NO_RABBIT #define NO_RABBIT + #undef NO_WOLFSSL_DIR #define NO_WOLFSSL_DIR + #undef NO_RC4 + #define NO_RC4 /* enable features */ + #undef USE_FAST_MATH #define USE_FAST_MATH - #define HAVE_ECC - #define HAVE_AESGCM - /* memory reduction */ + #define USE_CERT_BUFFERS_2048 + #define BENCH_EMBEDDED + #define TFM_TIMING_RESISTANT #define ECC_TIMING_RESISTANT - #define ALT_ECC_SIZE + //#define ALT_ECC_SIZE - /* setting for PIT timer */ - #define PIT_INSTANCE 0 - #define PIT_CHANNEL 0 + #undef HAVE_ECC + #define HAVE_ECC + #undef HAVE_AESCCM + #define HAVE_AESCCM + #undef HAVE_AESGCM + #define HAVE_AESGCM + #undef WOLFSSL_AES_COUNTER + #define WOLFSSL_AES_COUNTER + #undef WOLFSSL_AES_DIRECT + #define WOLFSSL_AES_DIRECT - #if defined(FREESCALE_KSDK_MQX) || defined(FREESCALE_KSDK_BM) || \ - defined(FREESCALE_FREE_RTOS) - #include "fsl_device_registers.h" - #endif + #include "fsl_common.h" /* random seed */ #define NO_OLD_RNGNAME - #if (FSL_FEATURE_SOC_TRNG_COUNT > 0) - #define FREESCALE_TRNG - #define TRNG_INSTANCE (0) - #elif (FSL_FEATURE_SOC_RNG_COUNT > 0) - #include "fsl_rnga_driver.h" + #if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) + #define FREESCALE_KSDK_2_0_TRNG + #elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) + #define FREESCALE_KSDK_2_0_RNGA + #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS) && !defined(FREESCALE_KSDK_FREERTOS) #define FREESCALE_RNGA #define RNGA_INSTANCE (0) - #elif !defined(FREESCALE_KSDK_BM) && !defined(FREESCALE_FREE_RTOS) /* defaulting to K70 RNGA, user should change if different */ /* #define FREESCALE_K53_RNGB */ #define FREESCALE_K70_RNGA #endif /* HW crypto */ - /* #define FREESCALE_MMCAU */ + /* automatic enable based on Kinetis feature */ + /* if case manual selection is required, for example for benchmarking purposes, + * just define FREESCALE_USE_MMCAU or FREESCALE_USE_LTC or none of these two macros (for software only) + * both can be enabled simultaneously as LTC has priority over MMCAU in source code. + */ + /* #define FSL_HW_CRYPTO_MANUAL_SELECTION */ + #ifndef FSL_HW_CRYPTO_MANUAL_SELECTION + #if defined(FSL_FEATURE_SOC_MMCAU_COUNT) && FSL_FEATURE_SOC_MMCAU_COUNT + #define FREESCALE_USE_MMCAU + #endif + + #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT + #define FREESCALE_USE_LTC + #endif + #else + /* #define FREESCALE_USE_MMCAU */ + /* #define FREESCALE_USE_LTC */ + #endif +#endif /* FREESCALE_COMMON */ + +#ifdef FREESCALE_USE_MMCAU + /* AES and DES */ + #define FREESCALE_MMCAU + /* MD5, SHA-1 and SHA-256 */ + #define FREESCALE_MMCAU_SHA +#endif /* FREESCALE_USE_MMCAU */ + +#ifdef FREESCALE_USE_LTC + #if defined(FSL_FEATURE_SOC_LTC_COUNT) && FSL_FEATURE_SOC_LTC_COUNT + #define FREESCALE_LTC + #define LTC_BASE LTC0 + + #if defined(FSL_FEATURE_LTC_HAS_DES) && FSL_FEATURE_LTC_HAS_DES + #define FREESCALE_LTC_DES + #endif + + #if defined(FSL_FEATURE_LTC_HAS_GCM) && FSL_FEATURE_LTC_HAS_GCM + #define FREESCALE_LTC_AES_GCM + #endif + + #if defined(FSL_FEATURE_LTC_HAS_SHA) && FSL_FEATURE_LTC_HAS_SHA + #define FREESCALE_LTC_SHA + #endif + + #if defined(FSL_FEATURE_LTC_HAS_PKHA) && FSL_FEATURE_LTC_HAS_PKHA + #define FREESCALE_LTC_ECC + #define FREESCALE_LTC_TFM + + /* the LTC PKHA hardware limit is 2048 bits (256 bytes) for integer arithmetic. + the LTC_MAX_INT_BYTES defines the size of local variables that hold big integers. */ + #define LTC_MAX_INT_BYTES (256) + + /* This FREESCALE_LTC_TFM_RSA_4096_ENABLE macro can be defined. + * In such a case both software and hardware algorithm + * for TFM is linked in. The decision for which algorithm is used is determined at runtime + * from size of inputs. If inputs and result can fit into LTC (see LTC_MAX_INT_BYTES) + * then we call hardware algorithm, otherwise we call software algorithm. + * + * Chinese reminder theorem is used to break RSA 4096 exponentiations (both public and prive key) + * into several computations with 2048-bit modulus and exponents. + */ + /* #define FREESCALE_LTC_TFM_RSA_4096_ENABLE */ + + /* ECC-384, ECC-256, ECC-224 and ECC-192 have been enabled with LTC PKHA acceleration */ + #ifdef HAVE_ECC + #undef ECC_TIMING_RESISTANT + #define ECC_TIMING_RESISTANT + + /* the LTC PKHA hardware limit is 512 bits (64 bytes) for ECC. + the LTC_MAX_ECC_BITS defines the size of local variables that hold ECC parameters + and point coordinates */ + #define LTC_MAX_ECC_BITS (384) + + /* Enable curves up to 384 bits */ + #define ECC_USER_CURVES + #define HAVE_ECC192 + #define HAVE_ECC224 + #undef NO_ECC256 + #define HAVE_ECC384 + + /* enable features */ + #undef HAVE_CURVE25519 + #define HAVE_CURVE25519 + #undef HAVE_ED25519 + #define HAVE_ED25519 + #undef WOLFSSL_SHA512 + #define WOLFSSL_SHA512 + #endif + #endif + #endif +#endif /* FREESCALE_USE_LTC */ + +#ifdef FREESCALE_LTC_TFM_RSA_4096_ENABLE + #undef USE_CERT_BUFFERS_2048 + #define USE_CERT_BUFFERS_4096 + #define FP_MAX_BITS (8192) + + #undef NO_DH + #define NO_DH + #undef NO_DSA + #define NO_DSA +#endif /* FREESCALE_LTC_TFM_RSA_4096_ENABLE */ + +/* if LTC has AES engine but doesn't have GCM, use software with LTC AES ECB mode */ +#if defined(FREESCALE_USE_LTC) && !defined(FREESCALE_LTC_AES_GCM) + #define GCM_TABLE #endif #ifdef WOLFSSL_STM32F2 @@ -1035,9 +1166,10 @@ static char *fgets(char *buff, int sz, FILE *fp) #endif -/* FreeScale MMCAU hardware crypto has 4 byte alignment */ +/* FreeScale MMCAU hardware crypto has 4 byte alignment. + However, fsl_mmcau.h gives API with no alignment requirements (4 byte alignment is managed internally by fsl_mmcau.c) */ #ifdef FREESCALE_MMCAU - #define WOLFSSL_MMCAU_ALIGNMENT 4 + #define WOLFSSL_MMCAU_ALIGNMENT 0 #endif /* if using hardware crypto and have alignment requirements, specify the diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index c65b0e52c..b107f08b5 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -32,6 +32,10 @@ #include #endif +#ifdef FREESCALE_LTC_SHA + #include "fsl_ltc.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -56,16 +60,20 @@ enum { /* Sha digest */ typedef struct Sha { - word32 buffLen; /* in bytes */ - word32 loLen; /* length in bytes */ - word32 hiLen; /* length in bytes */ - word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)]; - #ifndef WOLFSSL_PIC32MZ_HASH - word32 digest[SHA_DIGEST_SIZE / sizeof(word32)]; + #ifdef FREESCALE_LTC_SHA + ltc_hash_ctx_t ctx; #else - word32 digest[PIC32_HASH_SIZE / sizeof(word32)]; - pic32mz_desc desc; /* Crypt Engine descriptor */ - #endif + word32 buffLen; /* in bytes */ + word32 loLen; /* length in bytes */ + word32 hiLen; /* length in bytes */ + word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)]; + #ifndef WOLFSSL_PIC32MZ_HASH + word32 digest[SHA_DIGEST_SIZE / sizeof(word32)]; + #else + word32 digest[PIC32_HASH_SIZE / sizeof(word32)]; + pic32mz_desc desc; /* Crypt Engine descriptor */ + #endif + #endif /* FREESCALE_LTC_SHA */ } Sha; #else /* WOLFSSL_TI_HASH */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index f0109c4ea..790d87c94 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -34,6 +34,10 @@ #include #endif +#ifdef FREESCALE_LTC_SHA + #include "fsl_ltc.h" +#endif + #ifdef __cplusplus extern "C" { @@ -56,6 +60,9 @@ enum { /* Sha256 digest */ typedef struct Sha256 { +#ifdef FREESCALE_LTC_SHA + ltc_hash_ctx_t ctx; +#else word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ word32 hiLen; /* length in bytes */ @@ -64,6 +71,7 @@ typedef struct Sha256 { #ifdef WOLFSSL_PIC32MZ_HASH pic32mz_desc desc ; /* Crypt Engine descriptor */ #endif +#endif /* FREESCALE_LTC_SHA */ } Sha256; #else /* WOLFSSL_TI_HASH */ diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 79de9bc72..c7cf9fa06 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -547,6 +547,7 @@ int fp_leading_bit(fp_int *a); int fp_unsigned_bin_size(fp_int *a); void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c); void fp_to_unsigned_bin(fp_int *a, unsigned char *b); +int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b); /*int fp_signed_bin_size(fp_int *a);*/ /*void fp_read_signed_bin(fp_int *a, const unsigned char *b, int c);*/