From 8e64d564dca42f78f943829c4cb2ff2c645b43e1 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 10 Jun 2016 15:46:35 -0700 Subject: [PATCH 01/10] 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);*/ From a6b96b17ff5e2641d990dfc10fedbf2aa772ce41 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 15 Jun 2016 14:34:59 -0700 Subject: [PATCH 02/10] Fixes to include path for NXP ksdk_port. Fixes for time USER/OVERRIDES so their #ifdef's are checked first. Fix to initialize LTC via new "ksdk_port_init" function. Cleanup of the ksdk_port.c for formatting, macros, statics and line length. Cleanup of the AES code for key size. Cleanup of the wolfCrypt sha.c for readability. Added support for the KSDK bare metal drivers to the IDE Rowley CrossWorks example. Updated the settings.h to allow for overrides in Freescale section. Updated README with info for using LTC. --- .../Kinetis_MemoryMap.xml | 11 - IDE/ROWLEY-CROSSWORKS-ARM/README.md | 8 + IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c | 179 ++- IDE/ROWLEY-CROSSWORKS-ARM/include.am | 2 +- IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c | 98 +- IDE/ROWLEY-CROSSWORKS-ARM/retarget.c | 11 + IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h | 16 +- IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp | 25 +- IDE/ROWLEY-CROSSWORKS-ARM/wolfssl_ltc.hzp | 626 +++++++++ src/internal.c | 58 +- wolfcrypt/src/aes.c | 293 ++-- wolfcrypt/src/asn.c | 40 +- wolfcrypt/src/curve25519.c | 14 +- wolfcrypt/src/ecc.c | 25 +- wolfcrypt/src/ed25519.c | 2 +- wolfcrypt/src/integer.c | 3 + wolfcrypt/src/port/nxp/ksdk_port.c | 1230 +++++++++-------- wolfcrypt/src/rsa.c | 2 +- wolfcrypt/src/sha.c | 592 ++++---- wolfcrypt/src/tfm.c | 2 +- wolfcrypt/src/wc_port.c | 8 + wolfssl/wolfcrypt/aes.h | 2 + wolfssl/wolfcrypt/port/nxp/ksdk_port.h | 25 +- wolfssl/wolfcrypt/settings.h | 49 +- 24 files changed, 2047 insertions(+), 1274 deletions(-) delete mode 100644 IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml create mode 100644 IDE/ROWLEY-CROSSWORKS-ARM/wolfssl_ltc.hzp diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml b/IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml deleted file mode 100644 index 562fdb70f..000000000 --- a/IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/README.md b/IDE/ROWLEY-CROSSWORKS-ARM/README.md index 9fa89a27b..4a652d7eb 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/README.md +++ b/IDE/ROWLEY-CROSSWORKS-ARM/README.md @@ -34,6 +34,14 @@ To enable Freescale MMCAU: 3. Enable the `FREESCALE_MMCAU` define in `user_settings.h` and make sure its value is `1`. 4. Add the `lib_mmcau.a` file to `Source Files` in the application project. +To enable the NXP LTC: + +1. [Download the NXP KSDK 2.0](https://nxp.flexnetoperations.com/control/frse/download?agree=Accept&element=7353807) +2. Copy the following folders into IDE/ROWLEY-CROSSWORKS-ARM: drivers, mmcau_2.0.0 and CMSIS. +3. Copy the following files into IDE/ROWLEY-CROSSWORKS-ARM: clock_config.c, clock_config.h, fsl_debug_console.c, fsl_debug_console.h, fsl_device_registers.h, system_MK82F25615.c, system_MK82F25615.h, MK82F25615.h and MK82F25615_features.h. +4. Open the wolfssl_ltc.hzp CrossWorks project +5. Build and run + # Project Files * `arm_startup.c`: Handles startup from `reset_handler`. Disabled watchdog, initializes sections, initializes heap, starts harware and starts main. diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c b/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c index 358c0f2d7..28cdce3ea 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c @@ -84,6 +84,8 @@ void reset_handler(void) // Vector Exception/Interrupt Handlers static void Default_Handler(void) { + /* If we get here then need to implement real IRQ handler */ + while(1); } void HardFault_HandlerC( uint32_t *hardfault_args ) @@ -93,48 +95,48 @@ void HardFault_HandlerC( uint32_t *hardfault_args ) values of the variables, make them global my moving their declaration outside of this function. */ volatile uint32_t stacked_r0; - volatile uint32_t stacked_r1; - volatile uint32_t stacked_r2; - volatile uint32_t stacked_r3; - volatile uint32_t stacked_r12; - volatile uint32_t stacked_lr; + volatile uint32_t stacked_r1; + volatile uint32_t stacked_r2; + volatile uint32_t stacked_r3; + volatile uint32_t stacked_r12; + volatile uint32_t stacked_lr; volatile uint32_t stacked_pc; - volatile uint32_t stacked_psr; - volatile uint32_t _CFSR; - volatile uint32_t _HFSR; - volatile uint32_t _DFSR; - volatile uint32_t _AFSR; - volatile uint32_t _BFAR; - volatile uint32_t _MMAR; + volatile uint32_t stacked_psr; + volatile uint32_t _CFSR; + volatile uint32_t _HFSR; + volatile uint32_t _DFSR; + volatile uint32_t _AFSR; + volatile uint32_t _BFAR; + volatile uint32_t _MMAR; - stacked_r0 = ((uint32_t)hardfault_args[0]); - stacked_r1 = ((uint32_t)hardfault_args[1]); - stacked_r2 = ((uint32_t)hardfault_args[2]); - stacked_r3 = ((uint32_t)hardfault_args[3]); - stacked_r12 = ((uint32_t)hardfault_args[4]); - stacked_lr = ((uint32_t)hardfault_args[5]); - stacked_pc = ((uint32_t)hardfault_args[6]); - stacked_psr = ((uint32_t)hardfault_args[7]); + stacked_r0 = ((uint32_t)hardfault_args[0]); + stacked_r1 = ((uint32_t)hardfault_args[1]); + stacked_r2 = ((uint32_t)hardfault_args[2]); + stacked_r3 = ((uint32_t)hardfault_args[3]); + stacked_r12 = ((uint32_t)hardfault_args[4]); + stacked_lr = ((uint32_t)hardfault_args[5]); + stacked_pc = ((uint32_t)hardfault_args[6]); + stacked_psr = ((uint32_t)hardfault_args[7]); // Configurable Fault Status Register // Consists of MMSR, BFSR and UFSR - _CFSR = (*((volatile uint32_t *)(0xE000ED28))); - - // Hard Fault Status Register - _HFSR = (*((volatile uint32_t *)(0xE000ED2C))); + _CFSR = (*((volatile uint32_t *)(0xE000ED28))); + + // Hard Fault Status Register + _HFSR = (*((volatile uint32_t *)(0xE000ED2C))); - // Debug Fault Status Register - _DFSR = (*((volatile uint32_t *)(0xE000ED30))); + // Debug Fault Status Register + _DFSR = (*((volatile uint32_t *)(0xE000ED30))); - // Auxiliary Fault Status Register - _AFSR = (*((volatile uint32_t *)(0xE000ED3C))); + // Auxiliary Fault Status Register + _AFSR = (*((volatile uint32_t *)(0xE000ED3C))); - // Read the Fault Address Registers. These may not contain valid values. - // Check BFARVALID/MMARVALID to see if they are valid values - // MemManage Fault Address Register - _MMAR = (*((volatile uint32_t *)(0xE000ED34))); - // Bus Fault Address Register - _BFAR = (*((volatile uint32_t *)(0xE000ED38))); + // Read the Fault Address Registers. These may not contain valid values. + // Check BFARVALID/MMARVALID to see if they are valid values + // MemManage Fault Address Register + _MMAR = (*((volatile uint32_t *)(0xE000ED34))); + // Bus Fault Address Register + _BFAR = (*((volatile uint32_t *)(0xE000ED38))); printf ("\n\nHard fault handler (all numbers in hex):\n"); printf ("R0 = %x\n", stacked_r0); @@ -195,5 +197,114 @@ const vector_entry vectors[] __attribute__ ((section(".vectors"),used)) = Default_Handler, // 0x0000_0038 14 - ARM core Pendable request for system service (PendableSrvReq) Default_Handler, // 0x0000_003C 15 - ARM core System tick timer (SysTick) +#ifdef CPU_MK82FN256VLL15 // Add specific driver interrupt handlers below + Default_Handler, /* DMA0_DMA16_IRQn = 0, /**< DMA channel 0,16 transfer complete */ + Default_Handler, /* DMA1_DMA17_IRQn = 1, /**< DMA channel 1,17 transfer complete */ + Default_Handler, /* DMA2_DMA18_IRQn = 2, /**< DMA channel 2,18 transfer complete */ + Default_Handler, /* DMA3_DMA19_IRQn = 3, /**< DMA channel 3,19 transfer complete */ + Default_Handler, /* DMA4_DMA20_IRQn = 4, /**< DMA channel 4,20 transfer complete */ + Default_Handler, /* DMA5_DMA21_IRQn = 5, /**< DMA channel 5,21 transfer complete */ + Default_Handler, /* DMA6_DMA22_IRQn = 6, /**< DMA channel 6,22 transfer complete */ + Default_Handler, /* DMA7_DMA23_IRQn = 7, /**< DMA channel 7,23 transfer complete */ + Default_Handler, /* DMA8_DMA24_IRQn = 8, /**< DMA channel 8,24 transfer complete */ + Default_Handler, /* DMA9_DMA25_IRQn = 9, /**< DMA channel 9,25 transfer complete */ + Default_Handler, /* DMA10_DMA26_IRQn = 10, /**< DMA channel 10,26 transfer complete */ + Default_Handler, /* DMA11_DMA27_IRQn = 11, /**< DMA channel 11,27 transfer complete */ + Default_Handler, /* DMA12_DMA28_IRQn = 12, /**< DMA channel 12,28 transfer complete */ + Default_Handler, /* DMA13_DMA29_IRQn = 13, /**< DMA channel 13,29 transfer complete */ + Default_Handler, /* DMA14_DMA30_IRQn = 14, /**< DMA channel 14,30 transfer complete */ + Default_Handler, /* DMA15_DMA31_IRQn = 15, /**< DMA channel 15,31 transfer complete */ + Default_Handler, /* DMA_Error_IRQn = 16, /**< DMA channel 0 - 31 error */ + Default_Handler, /* MCM_IRQn = 17, /**< MCM normal interrupt */ + Default_Handler, /* FTFA_IRQn = 18, /**< FTFA command complete */ + Default_Handler, /* Read_Collision_IRQn = 19, /**< FTFA read collision */ + Default_Handler, /* LVD_LVW_IRQn = 20, /**< PMC controller low-voltage detect, low-voltage warning */ + Default_Handler, /* LLWU_IRQn = 21, /**< Low leakage wakeup unit */ + Default_Handler, /* WDOG_EWM_IRQn = 22, /**< Single interrupt vector for WDOG and EWM */ + Default_Handler, /* TRNG0_IRQn = 23, /**< True randon number generator */ + Default_Handler, /* I2C0_IRQn = 24, /**< Inter-integrated circuit 0 */ + Default_Handler, /* I2C1_IRQn = 25, /**< Inter-integrated circuit 1 */ + Default_Handler, /* SPI0_IRQn = 26, /**< Serial peripheral Interface 0 */ + Default_Handler, /* SPI1_IRQn = 27, /**< Serial peripheral Interface 1 */ + Default_Handler, /* I2S0_Tx_IRQn = 28, /**< Integrated interchip sound 0 transmit interrupt */ + Default_Handler, /* I2S0_Rx_IRQn = 29, /**< Integrated interchip sound 0 receive interrupt */ + Default_Handler, /* LPUART0_IRQn = 30, /**< LPUART0 receive/transmit/error interrupt */ + Default_Handler, /* LPUART1_IRQn = 31, /**< LPUART1 receive/transmit/error interrupt */ + Default_Handler, /* LPUART2_IRQn = 32, /**< LPUART2 receive/transmit/error interrupt */ + Default_Handler, /* LPUART3_IRQn = 33, /**< LPUART3 receive/transmit/error interrupt */ + Default_Handler, /* LPUART4_IRQn = 34, /**< LPUART4 receive/transmit/error interrupt */ + Default_Handler, /* Reserved51_IRQn = 35, /**< Reserved interrupt */ + Default_Handler, /* Reserved52_IRQn = 36, /**< Reserved interrupt */ + Default_Handler, /* EMVSIM0_IRQn = 37, /**< EMVSIM0 common interrupt */ + Default_Handler, /* EMVSIM1_IRQn = 38, /**< EMVSIM1 common interrupt */ + Default_Handler, /* ADC0_IRQn = 39, /**< Analog-to-digital converter 0 */ + Default_Handler, /* CMP0_IRQn = 40, /**< Comparator 0 */ + Default_Handler, /* CMP1_IRQn = 41, /**< Comparator 1 */ + Default_Handler, /* FTM0_IRQn = 42, /**< FlexTimer module 0 fault, overflow and channels interrupt */ + Default_Handler, /* FTM1_IRQn = 43, /**< FlexTimer module 1 fault, overflow and channels interrupt */ + Default_Handler, /* FTM2_IRQn = 44, /**< FlexTimer module 2 fault, overflow and channels interrupt */ + Default_Handler, /* CMT_IRQn = 45, /**< Carrier modulator transmitter */ + Default_Handler, /* RTC_IRQn = 46, /**< Real time clock */ + Default_Handler, /* RTC_Seconds_IRQn = 47, /**< Real time clock seconds */ + Default_Handler, /* PIT0CH0_IRQn = 48, /**< Periodic interrupt timer 0 channel 0 */ + Default_Handler, /* PIT0CH1_IRQn = 49, /**< Periodic interrupt timer 0 channel 1 */ + Default_Handler, /* PIT0CH2_IRQn = 50, /**< Periodic interrupt timer 0 channel 2 */ + Default_Handler, /* PIT0CH3_IRQn = 51, /**< Periodic interrupt timer 0 channel 3 */ + Default_Handler, /* PDB0_IRQn = 52, /**< Programmable delay block */ + Default_Handler, /* USB0_IRQn = 53, /**< USB OTG interrupt */ + Default_Handler, /* USBDCD_IRQn = 54, /**< USB charger detect */ + Default_Handler, /* Reserved71_IRQn = 55, /**< Reserved interrupt */ + Default_Handler, /* DAC0_IRQn = 56, /**< Digital-to-analog converter 0 */ + Default_Handler, /* MCG_IRQn = 57, /**< Multipurpose clock generator */ + Default_Handler, /* LPTMR0_LPTMR1_IRQn = 58, /**< Single interrupt vector for Low Power Timer 0 and 1 */ + Default_Handler, /* PORTA_IRQn = 59, /**< Port A pin detect interrupt */ + Default_Handler, /* PORTB_IRQn = 60, /**< Port B pin detect interrupt */ + Default_Handler, /* PORTC_IRQn = 61, /**< Port C pin detect interrupt */ + Default_Handler, /* PORTD_IRQn = 62, /**< Port D pin detect interrupt */ + Default_Handler, /* PORTE_IRQn = 63, /**< Port E pin detect interrupt */ + Default_Handler, /* SWI_IRQn = 64, /**< Software interrupt */ + Default_Handler, /* SPI2_IRQn = 65, /**< Serial peripheral Interface 2 */ + Default_Handler, /* Reserved82_IRQn = 66, /**< Reserved interrupt */ + Default_Handler, /* Reserved83_IRQn = 67, /**< Reserved interrupt */ + Default_Handler, /* Reserved84_IRQn = 68, /**< Reserved interrupt */ + Default_Handler, /* Reserved85_IRQn = 69, /**< Reserved interrupt */ + Default_Handler, /* FLEXIO0_IRQn = 70, /**< FLEXIO0 */ + Default_Handler, /* FTM3_IRQn = 71, /**< FlexTimer module 3 fault, overflow and channels interrupt */ + Default_Handler, /* Reserved88_IRQn = 72, /**< Reserved interrupt */ + Default_Handler, /* Reserved89_IRQn = 73, /**< Reserved interrupt */ + Default_Handler, /* I2C2_IRQn = 74, /**< Inter-integrated circuit 2 */ + Default_Handler, /* Reserved91_IRQn = 75, /**< Reserved interrupt */ + Default_Handler, /* Reserved92_IRQn = 76, /**< Reserved interrupt */ + Default_Handler, /* Reserved93_IRQn = 77, /**< Reserved interrupt */ + Default_Handler, /* Reserved94_IRQn = 78, /**< Reserved interrupt */ + Default_Handler, /* Reserved95_IRQn = 79, /**< Reserved interrupt */ + Default_Handler, /* Reserved96_IRQn = 80, /**< Reserved interrupt */ + Default_Handler, /* SDHC_IRQn = 81, /**< Secured digital host controller */ + Default_Handler, /* Reserved98_IRQn = 82, /**< Reserved interrupt */ + Default_Handler, /* Reserved99_IRQn = 83, /**< Reserved interrupt */ + Default_Handler, /* Reserved100_IRQn = 84, /**< Reserved interrupt */ + Default_Handler, /* Reserved101_IRQn = 85, /**< Reserved interrupt */ + Default_Handler, /* Reserved102_IRQn = 86, /**< Reserved interrupt */ + Default_Handler, /* TSI0_IRQn = 87, /**< Touch Sensing Input */ + Default_Handler, /* TPM1_IRQn = 88, /**< TPM1 single interrupt vector for all sources */ + Default_Handler, /* TPM2_IRQn = 89, /**< TPM2 single interrupt vector for all sources */ + Default_Handler, /* Reserved106_IRQn = 90, /**< Reserved interrupt */ + Default_Handler, /* I2C3_IRQn = 91, /**< Inter-integrated circuit 3 */ + Default_Handler, /* Reserved108_IRQn = 92, /**< Reserved interrupt */ + Default_Handler, /* Reserved109_IRQn = 93, /**< Reserved interrupt */ + Default_Handler, /* Reserved110_IRQn = 94, /**< Reserved interrupt */ + Default_Handler, /* Reserved111_IRQn = 95, /**< Reserved interrupt */ + Default_Handler, /* Reserved112_IRQn = 96, /**< Reserved interrupt */ + Default_Handler, /* Reserved113_IRQn = 97, /**< Reserved interrupt */ + Default_Handler, /* Reserved114_IRQn = 98, /**< Reserved interrupt */ + Default_Handler, /* Reserved115_IRQn = 99, /**< Reserved interrupt */ + Default_Handler, /* QuadSPI0_IRQn = 100, /**< qspi */ + Default_Handler, /* Reserved117_IRQn = 101, /**< Reserved interrupt */ + Default_Handler, /* Reserved118_IRQn = 102, /**< Reserved interrupt */ + Default_Handler, /* Reserved119_IRQn = 103, /**< Reserved interrupt */ + Default_Handler, /* LTC0_IRQn = 104, /**< LP Trusted Cryptography */ + Default_Handler, /* Reserved121_IRQn = 105, /**< Reserved interrupt */ + Default_Handler, /* Reserved122_IRQn = 106 /**< Reserved interrupt */ +#endif /* CPU_MK82FN256VLL15 */ }; diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/include.am b/IDE/ROWLEY-CROSSWORKS-ARM/include.am index e812cc7e6..c58c76192 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/include.am +++ b/IDE/ROWLEY-CROSSWORKS-ARM/include.am @@ -6,10 +6,10 @@ EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/arm_startup.c EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/benchmark_main.c EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/hw.h EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c -EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_MemoryMap.xml EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/Kinetis_FlashPlacement.xml EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/README.md EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/test_main.c EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/retarget.c EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp +EXTRA_DIST+= IDE/ROWLEY-CROSSWORKS-ARM/wolfssl_ltc.hzp diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c index 961e181d8..35b62fd41 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c @@ -21,10 +21,10 @@ #include "hw.h" +#include "user_settings.h" #if defined(FREESCALE) && defined(K_SERIES) - /********************************************** * NOTE: Customize for actual hardware **********************************************/ @@ -33,27 +33,53 @@ // $(TargetsDir) location: // On Mac OS/X: Users/USERNAME/Library/Rowley Associates Limited/CrossWorks for ARM/packages/targets/ // On Windows: C:/Users/USERNAME/Application Data/Local/Rowley Associates Limited/CrossWorks for ARM/packages/targets/ -#include // Located in $(TargetsDir)/Kinetis/CMSIS/ + +// Located in $(TargetsDir)/Kinetis/CMSIS/ +#ifdef FREESCALE_KSDK_BM + #include "fsl_common.h" + #include "fsl_debug_console.h" + #include "fsl_rtc.h" + #include "fsl_trng.h" + #include "fsl_lpuart.h" + #include "fsl_port.h" + #include "clock_config.h" +#else + #include // Located in $(TargetsDir)/Kinetis/CMSIS/ +#endif + // System clock -#define SYS_CLK_KHZ 96000ul /* Core system clock in KHz */ -#define SYS_CLK_DRS MCG_C4_DRST_DRS(0x03) /* DRS 0=24MHz, 1=48MHz, 2=72MHz, 3=96MHz */ -#define SYS_CLK_DMX MCG_C4_DMX32_MASK /* 0=Disable DMX32 (lower actual speed), MCG_C4_DMX32_MASK=Enable DMX32 */ -#define SYS_CLK_DIV 1 /* System clock divisor */ -#define BUS_CLK_DIV 2 /* Bus clock divisor */ -#define BUS_CLK_KHZ (SYS_CLK_KHZ/BUS_CLK_DIV) /* Helper to calculate bus speed for UART */ -#define FLASH_CLK_DIV 4 /* Flash clock divisor */ +#ifdef FREESCALE_KSDK_BM + #define SYS_CLK_HZ SystemCoreClock +#else + #define SYS_CLK_HZ 96000000ul /* Core system clock in Hz */ + #define SYS_CLK_DRS MCG_C4_DRST_DRS(0x03) /* DRS 0=24MHz, 1=48MHz, 2=72MHz, 3=96MHz */ + #define SYS_CLK_DMX MCG_C4_DMX32_MASK /* 0=Disable DMX32 (lower actual speed), MCG_C4_DMX32_MASK=Enable DMX32 */ + #define SYS_CLK_DIV 1 /* System clock divisor */ + #define BUS_CLK_DIV 2 /* Bus clock divisor */ + #define BUS_CLK_KHZ (SYS_CLK_HZ/BUS_CLK_DIV) /* Helper to calculate bus speed for UART */ + #define FLASH_CLK_DIV 4 /* Flash clock divisor */ +#endif // UART TX Port, Pin, Mux and Baud -#define UART_PORT UART4 /* UART Port */ -#define UART_TX_PORT PORTE /* UART TX Port */ -#define UART_TX_PIN 24 /* UART TX Pin */ -#define UART_TX_MUX 0x3 /* Kinetis UART pin mux */ -#define UART_BAUD 115200 /* UART Baud Rate */ +#ifdef FREESCALE_KSDK_BM + #define UART_PORT LPUART0 /* UART Port */ + #define UART_TX_PORT PORTA /* UART TX Port */ + #define UART_TX_PIN 2U /* UART TX Pin */ + #define UART_TX_MUX kPORT_MuxAlt2 /* Kinetis UART pin mux */ +#else + #define UART_PORT UART4 /* UART Port */ + #define UART_TX_PORT PORTE /* UART TX Port */ + #define UART_TX_PIN 24U /* UART TX Pin */ + #define UART_TX_MUX 0x3 /* Kinetis UART pin mux */ +#endif +#define UART_BAUD 115200 /* UART Baud Rate */ + /* Note: You will also need to update the UART clock gate in hw_uart_init (SIM_SCGC1_UART5_MASK) */ /* Note: TWR-K60 is UART3, PTC17 */ /* Note: FRDM-K64 is UART4, PTE24 */ /* Note: TWR-K64 is UART5, PTE8 */ +/* Note: FRDM-K82F is LPUART0 A2, LPUART4 PTC15 */ /***********************************************/ @@ -70,6 +96,9 @@ static void delay_nop(uint32_t count) static void hw_mcg_init(void) { +#ifdef FREESCALE_KSDK_BM + BOARD_BootClockHSRUN(); +#else /* Adjust clock dividers (core/system=div/1, bus=div/2, flex bus=div/2, flash=div/4) */ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(SYS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV2(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV3(BUS_CLK_DIV-1) | SIM_CLKDIV1_OUTDIV4(FLASH_CLK_DIV-1); @@ -77,10 +106,18 @@ static void hw_mcg_init(void) /* Configure FEI internal clock speed */ MCG->C4 = (SYS_CLK_DMX | SYS_CLK_DRS); while((MCG->C4 & (MCG_C4_DRST_DRS_MASK | MCG_C4_DMX32_MASK)) != (SYS_CLK_DMX | SYS_CLK_DRS)); +#endif } static void hw_gpio_init(void) { +#ifdef FREESCALE_KSDK_BM + CLOCK_EnableClock(kCLOCK_PortA); + CLOCK_EnableClock(kCLOCK_PortB); + CLOCK_EnableClock(kCLOCK_PortC); + CLOCK_EnableClock(kCLOCK_PortD); + CLOCK_EnableClock(kCLOCK_PortE); +#else /* Enable clocks to all GPIO ports */ SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK #ifdef SIM_SCGC5_PORTC_MASK @@ -93,6 +130,7 @@ static void hw_gpio_init(void) | SIM_SCGC5_PORTE_MASK #endif ); +#endif } static void hw_uart_init(void) @@ -100,7 +138,13 @@ static void hw_uart_init(void) register uint16_t sbr, brfa; uint8_t temp; +#ifdef FREESCALE_KSDK_BM + PORT_SetPinMux(UART_TX_PORT, UART_TX_PIN, UART_TX_MUX); + CLOCK_SetLpuartClock(1); /* MCGPLLCLK */ + DbgConsole_Init((uint32_t)UART_PORT, UART_BAUD, DEBUG_CONSOLE_DEVICE_TYPE_LPUART, SYS_CLK_HZ); +#else /* Enable UART core clock */ + /* Note: Remember to update me if UART_PORT changes */ SIM->SCGC1 |= SIM_SCGC1_UART4_MASK; /* Configure UART TX pin */ @@ -125,12 +169,13 @@ static void hw_uart_init(void) /* Enable receiver and transmitter */ UART_PORT->C2 |= (UART_C2_TE_MASK | UART_C2_RE_MASK); +#endif } static void hw_rtc_init(void) { /* Init nop delay */ - mDelayCyclesPerUs = (SYS_CLK_KHZ / 1000 / NOP_FOR_LOOP_INSTRUCTION_COUNT); + mDelayCyclesPerUs = (SYS_CLK_HZ / 1000000 / NOP_FOR_LOOP_INSTRUCTION_COUNT); /* Enable RTC clock and oscillator */ SIM->SCGC6 |= SIM_SCGC6_RTC_MASK; @@ -145,7 +190,7 @@ static void hw_rtc_init(void) } /* Disable RTC Interrupts */ - RTC_IER = 0; + RTC->IER = 0; /* Enable OSC */ if ((RTC->CR & RTC_CR_OSCE_MASK) == 0) { @@ -164,6 +209,14 @@ static void hw_rtc_init(void) static void hw_rand_init(void) { +#ifdef FREESCALE_KSDK_BM + trng_config_t trngConfig; + TRNG_GetDefaultConfig(&trngConfig); + /* Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.*/ + trngConfig.sampleMode = kTRNG_SampleModeVonNeumann; + /* Initialize TRNG */ + TRNG_Init(TRNG0, &trngConfig); +#else /* Enable RNG clocks */ SIM->SCGC6 |= SIM_SCGC6_RNGA_MASK; SIM->SCGC3 |= SIM_SCGC3_RNGA_MASK; @@ -176,6 +229,7 @@ static void hw_rand_init(void) /* Enable RNG generation to RANDOUT FIFO */ RNG->CR |= RNG_CR_GO_MASK; +#endif } @@ -204,14 +258,24 @@ uint32_t hw_get_time_msec(void) void hw_uart_printchar(int c) { +#ifdef FREESCALE_KSDK_BM + LPUART_WriteBlocking(UART_PORT, (const uint8_t*)&c, 1); /* Send the character */ +#else while(!(UART_PORT->S1 & UART_S1_TDRE_MASK)); /* Wait until space is available in the FIFO */ UART_PORT->D = (uint8_t)c; /* Send the character */ +#endif } uint32_t hw_rand(void) { + uint32_t rng; +#ifdef FREESCALE_KSDK_BM + TRNG_GetRandomData(TRNG0, &rng, sizeof(rng)); +#else while((RNG->SR & RNG_SR_OREG_LVL(0xF)) == 0) {}; /* Wait until FIFO has a value available */ - return RNG->OR; /* Return next value in FIFO output register */ + rng = RNG->OR; /* Return next value in FIFO output register */ +#endif + return rng; } void delay_us(uint32_t microseconds) diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c b/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c index 6a4dac38f..958316381 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/retarget.c @@ -22,6 +22,17 @@ #include "hw.h" #include "user_settings.h" +#include + +void __assert(const char *__expression, const char *__filename, int __line) +{ + printf("Assert: %s, File %s (%d)\n", __expression, __filename, __line); +} + +unsigned int LowResTimer(void) +{ + return hw_get_time_sec(); +} double current_time(int reset) { diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h b/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h index f8d751ff0..048de56d5 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h +++ b/IDE/ROWLEY-CROSSWORKS-ARM/user_settings.h @@ -140,7 +140,7 @@ extern "C" { /* Ed25519 / Curve25519 */ #undef HAVE_CURVE25519 #undef HAVE_ED25519 -#if 0 +#if 1 #define HAVE_CURVE25519 #define HAVE_ED25519 @@ -196,7 +196,18 @@ extern "C" { /* HW Crypto Acceleration */ /* ------------------------------------------------------------------------- */ // See README.md for instructions -//#define FREESCALE_MMCAU 1 +#if 0 + #define FREESCALE_MMCAU 1 +#endif + +/* NXP LTC Support (See README.md for instructions) */ +#if 0 + #define FSL_HW_CRYPTO_MANUAL_SELECTION + #define FREESCALE_USE_MMCAU + #define FREESCALE_USE_LTC + #define LTC_MAX_ECC_BITS (512) + #define LTC_MAX_INT_BYTES (256) +#endif /* ------------------------------------------------------------------------- */ @@ -243,6 +254,7 @@ extern "C" { /* Override Current Time */ /* Allows custom "custom_time()" function to be used for benchmark */ #define WOLFSSL_USER_CURRTIME +#define USER_TICKS /* ------------------------------------------------------------------------- */ diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp b/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp index 74a4eeaff..ad5c68af8 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp +++ b/IDE/ROWLEY-CROSSWORKS-ARM/wolfssl.hzp @@ -83,6 +83,9 @@ + @@ -140,6 +143,8 @@ arm_target_loader_default_loader="Flash" c_preprocessor_definitions="WOLFSSL_ROWLEY_ARM;WOLFSSL_USER_SETTINGS" c_user_include_directories=".;../;../../;$(TargetsDir);$(TargetsDir)/Kinetis;$(TargetsDir)/Kinetis/CMSIS;$(TargetsDir)/Kinetis/CMSIS/include;$(TargetsDir)/CMSIS_3/CMSIS/include" + debug_register_definition_file="$(TargetsDir)/Kinetis/MK64F12_Peripherals.xml" + linker_memory_map_file="$(TargetsDir)/Kinetis/MK64FN1M0xxx12_MemoryMap.xml" linker_memory_map_macros="FLASHSIZE=0x80000;SRAMSIZE=0x20000" linker_output_format="bin" project_dependencies="libwolfssl" @@ -161,7 +166,6 @@ - @@ -169,16 +173,21 @@ Name="Common" Placement="Flash" Target="MK64FN1M0xxx12" + arm_architecture="v7EM" + arm_core_type="Cortex-M4" + arm_fpu_type="FPv4-SP-D16" arm_linker_fiq_stack_size="0" arm_linker_heap_size="91136" arm_linker_irq_stack_size="0" arm_linker_stack_size="30720" arm_simulator_memory_simulation_filename="$(TargetsDir)/Kinetis/KinetisSimulatorMemory.dll" - arm_simulator_memory_simulation_parameter="MK64FN1M0xxx12;0x100000;0x0;0x0;0x40000" + arm_simulator_memory_simulation_parameter="MK64FN1M0xxx12;0x100000;0x0;0x0;0x40000;4" arm_target_loader_applicable_loaders="Flash" arm_target_loader_default_loader="Flash" c_preprocessor_definitions="WOLFSSL_ROWLEY_ARM;WOLFSSL_USER_SETTINGS" c_user_include_directories=".;../;../../;$(TargetsDir);$(TargetsDir)/Kinetis;$(TargetsDir)/Kinetis/CMSIS;$(TargetsDir)/Kinetis/CMSIS/include;$(TargetsDir)/CMSIS_3/CMSIS/include" + debug_register_definition_file="$(TargetsDir)/Kinetis/MK64F12_Peripherals.xml" + linker_memory_map_file="$(TargetsDir)/Kinetis/MK64FN1M0xxx12_MemoryMap.xml" linker_memory_map_macros="FLASHSIZE=0x80000;SRAMSIZE=0x20000" linker_output_format="bin" project_dependencies="libwolfssl" @@ -200,8 +209,11 @@ - +