From 64ae0a827cfd05bd0b3b85639e39ad8c4cf06eb1 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 16 Apr 2021 11:29:03 -0700 Subject: [PATCH 1/8] Fixes for RSA with NXP LTC. The invmod function must reduce if A > B. Added RSA Key Generation acceleration. --- wolfcrypt/src/integer.c | 2 +- wolfcrypt/src/port/nxp/ksdk_port.c | 178 +++++++++++++++++++++-------- wolfcrypt/src/rsa.c | 4 +- wolfcrypt/src/tfm.c | 15 ++- wolfcrypt/test/test.c | 3 +- 5 files changed, 151 insertions(+), 51 deletions(-) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 5dd9e15fc..852ff5969 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -1450,7 +1450,7 @@ int mp_is_bit_set (mp_int *a, mp_digit b) mp_digit s = b % DIGIT_BIT; /* bit index */ if ((mp_digit)a->used <= i) { - /* no words avaialable at that bit count */ + /* no words available at that bit count */ return 0; } diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index be8cbe1de..4daf3d92f 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -129,9 +129,9 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) #endif /* unsigned multiply */ - uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); if (ptrA && ptrB && ptrC) { uint16_t sizeA, sizeB; @@ -142,9 +142,10 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) if (res == MP_OKAY) { 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_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); res = mp_read_unsigned_bin(C, ptrB, sizeB); @@ -185,9 +186,9 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) { int neg = 0; - uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); #ifndef WOLFSSL_SP_MATH /* get sign for the result */ @@ -203,7 +204,8 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) res = ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); if (res == MP_OKAY) { if (kStatus_Success == - LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith)) + LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, + &sizeC, kLTC_PKHA_IntegerArith)) { ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(c, ptrC, sizeC); @@ -251,9 +253,9 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) { - uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); if (ptrA && ptrB && ptrC) { uint16_t sizeA, sizeB, sizeC; @@ -261,10 +263,18 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) res = ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); if (res == MP_OKAY) res = ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); + + /* if a >= b then reduce */ + if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrB, + sizeB) >= 0) { + if (LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, + ptrA, &sizeA, kLTC_PKHA_IntegerArith) != kStatus_Success) { + res = MP_VAL; + } + } if (res == MP_OKAY) { - if (kStatus_Success == - LTC_PKHA_ModInv(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, &sizeC, kLTC_PKHA_IntegerArith)) - { + if (LTC_PKHA_ModInv(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, + &sizeC, kLTC_PKHA_IntegerArith) == kStatus_Success) { ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(c, ptrC, sizeC); } @@ -308,13 +318,15 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); szC = mp_unsigned_bin_size(c); - if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && + (szC <= LTC_MAX_INT_BYTES)) + { mp_int t; - uint8_t *ptrA = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrD = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrD = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); /* if A or B is negative, subtract abs(A) or abs(B) from modulus to get * positive integer representation of the same number */ @@ -344,7 +356,8 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) res = ltc_get_lsb_bin_from_mp_int(ptrC, c, &sizeC); /* (A*B)mod C = ((A mod C) * (B mod C)) mod C */ - if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrC, sizeC) >= 0) { + if (res == MP_OKAY && 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)) @@ -352,8 +365,8 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) res = MP_VAL; } } - if (res == MP_OKAY && (LTC_PKHA_CompareBigNum(ptrB, sizeB, ptrC, sizeC) >= 0)) - { + if (res == MP_OKAY && (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)) @@ -413,7 +426,9 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) { int res = MP_OKAY; int szA, szB, szC; +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) mp_int tmp; +#endif /* if G cannot fit into LTC_PKHA, reduce it */ szA = mp_unsigned_bin_size(G); @@ -432,15 +447,16 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) szB = mp_unsigned_bin_size(X); szC = mp_unsigned_bin_size(P); - if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && + if ((szA <= LTC_MAX_INT_BYTES) && + (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { mp_int t; uint16_t sizeG, sizeX, sizeP; - uint8_t *ptrG = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrX = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrP = (uint8_t *)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrG = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrX = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrP = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); /* if G is negative, add modulus to convert to positive number for LTC */ res = mp_init(&t); @@ -460,29 +476,27 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) if (res == MP_OKAY) res = 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 exponentiation */ + /* if number if greater that modulo, we must first reduce due to LTC + requirement on modular exponentiation */ /* 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. + /* 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 (res == MP_OKAY && 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) { + /* if G >= P then reduce */ + if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrG, sizeG, ptrP, + sizeP) >= 0) { + if (LTC_PKHA_ModRed(LTC_BASE, ptrG, sizeG, ptrP, sizeP, + ptrG, &sizeG, kLTC_PKHA_IntegerArith) != kStatus_Success) { res = MP_VAL; } } if (res == MP_OKAY) { - 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) { + if (LTC_PKHA_ModExp(LTC_BASE, ptrG, sizeG, ptrP, sizeP, ptrX, sizeX, + ptrP, &sizeP, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized) != kStatus_Success) { res = MP_VAL; } else { @@ -524,6 +538,79 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) return res; } +int mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + /* use hardware implementation even for non-constant time operations */ + return mp_exptmod(G, X, P, Y); +} + +#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || \ + defined(WOLFSSL_KEY_GEN) +int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) +{ + int res = MP_OKAY; + int szA; + + szA = mp_unsigned_bin_size(a); + if (szA <= LTC_MAX_INT_BYTES) { + uint16_t sizeA, sizeB; + uint8_t *ptrA, *ptrB; + + sizeB = mp_count_bits(a); + /* The base size is the number of bits / 8. One is added if the number + * of bits isn't an even 8. */ + sizeB = (sizeB / 8) + ((sizeB % 8) ? 1 : 0); + + ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + ptrB = (uint8_t*)XMALLOC(sizeB, NULL, DYNAMIC_TYPE_BIGINT); + if (ptrA == NULL || ptrB == NULL) { + res = MEMORY_E; + } + + #ifndef WC_NO_RNG + if (res == MP_OKAY && rng != NULL) { + res = wc_RNG_GenerateBlock(rng, ptrB, sizeB); + } + #else + res = NOT_COMPILED_IN; + #endif + + if (res == MP_OKAY) { + res = ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); + } + if (res == MP_OKAY) { + if (LTC_PKHA_PrimalityTest(LTC_BASE, + ptrB, sizeB, /* seed */ + (uint8_t*)&t, sizeof(t), /* trials */ + ptrA, sizeA, /* candidate */ + (bool*)result) != kStatus_Success) { + res = MP_MEM; + } + } + + if (ptrB) { + XFREE(ptrB, NULL, DYNAMIC_TYPE_BIGINT); + } + if (ptrA) { + XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT); + } + } + else { +#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) + res = mp_prime_is_prime_ex(a, t, result, rng); +#else + res = NOT_COMPILED_IN; +#endif + } + return res; +} + +int mp_prime_is_prime(mp_int* a, int t, int* result) +{ + return mp_prime_is_prime_ex(a, t, result, NULL); +} +#endif /* !NO_RSA || !NO_DSA || !NO_DH || WOLFSSL_KEY_GEN */ + #endif /* FREESCALE_LTC_TFM */ @@ -567,7 +654,8 @@ static int ltc_get_from_mp_int(uint8_t *dst, mp_int *a, int sz) return res; } -/* ECC specs in lsbyte at lowest address format for direct use by LTC PKHA driver functions */ +/* 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 diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 87ba82770..76f84dfa3 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -397,7 +397,7 @@ int wc_InitRsaKey_Label(RsaKey* key, const char* label, void* heap, int devId) */ int wc_InitRsaHw(RsaKey* key) { - unsigned char* m; /* RSA modulous */ + unsigned char* m; /* RSA modulus */ word32 e = 0; /* RSA public exponent */ int mSz; int eSz; @@ -673,7 +673,7 @@ int wc_CheckRsaKey(RsaKey* key) break; #endif /* WOLFSSL_SP_4096 */ default: - /* If using only single precsision math then issue key size + /* If using only single precision math then issue key size * error, otherwise fall-back to multi-precision math * calculation */ #if defined(WOLFSSL_SP_MATH) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 300b777ba..f30957088 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -4275,7 +4275,11 @@ int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y) return fp_exptmod_ex(G, X, digits, P, Y); } +#if defined(FREESCALE_LTC_TFM) +int wolfcrypt_mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +#else int mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +#endif { return fp_exptmod_nct(G, X, P, Y); } @@ -4724,8 +4728,11 @@ int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c) static int fp_isprime_ex(fp_int *a, int t, int* result); - +#if defined(FREESCALE_LTC_TFM) +int wolfcrypt_mp_prime_is_prime(mp_int* a, int t, int* result) +#else int mp_prime_is_prime(mp_int* a, int t, int* result) +#endif { return fp_isprime_ex(a, t, result); } @@ -4960,7 +4967,11 @@ int fp_isprime_ex(fp_int *a, int t, int* result) } +#if defined(FREESCALE_LTC_TFM) +int wolfcrypt_mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) +#else int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) +#endif { int ret = FP_YES; fp_digit d; @@ -5370,7 +5381,7 @@ int mp_add_d(fp_int *a, fp_digit b, fp_int *c) /* chars used in radix conversions */ static wcchar fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz+/"; + "abcdefghijklmnopqrstuvwxyz+/"; #endif #if !defined(NO_DSA) || defined(HAVE_ECC) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index efa3c430f..94d0e93d8 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -14705,7 +14705,8 @@ static int rsa_keygen_test(WC_RNG* rng) #if !defined(HAVE_FAST_RSA) && !defined(HAVE_USER_RSA) && \ (!defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) && \ - !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) + !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) \ + && !defined(WOLFSSL_NO_RSA_KEY_CHECK) ret = wc_CheckRsaKey(genKey); if (ret != 0) { ERROR_OUT(-7872, exit_rsa); From 9453f83d28df0300df366e74867fc1f0118352ae Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 30 Apr 2021 14:37:25 -0700 Subject: [PATCH 2/8] Fix bad logic flow in `WC_NO_RNG` case. --- wolfcrypt/src/port/nxp/ksdk_port.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index 4daf3d92f..492308a8d 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -560,20 +560,21 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) /* The base size is the number of bits / 8. One is added if the number * of bits isn't an even 8. */ sizeB = (sizeB / 8) + ((sizeB % 8) ? 1 : 0); - + ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); ptrB = (uint8_t*)XMALLOC(sizeB, NULL, DYNAMIC_TYPE_BIGINT); if (ptrA == NULL || ptrB == NULL) { res = MEMORY_E; } - #ifndef WC_NO_RNG - if (res == MP_OKAY && rng != NULL) { + if (res == MP_OKAY) { + #ifndef WC_NO_RNG + /* A NULL rng will return as bad function arg */ res = wc_RNG_GenerateBlock(rng, ptrB, sizeB); + #else + res = NOT_COMPILED_IN; + #endif } - #else - res = NOT_COMPILED_IN; - #endif if (res == MP_OKAY) { res = ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); From 63ac9decfce682d5d61d0791cbad14232f9a4a30 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 13 May 2021 15:13:11 -0700 Subject: [PATCH 3/8] Added error response checking for NXP LTC `LTC_PKHA_ModMul`. Isolated the result C to it's own variable. --- wolfcrypt/src/port/nxp/ksdk_port.c | 46 ++++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index 492308a8d..4c029a1c4 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -116,6 +116,7 @@ static int ltc_get_lsb_bin_from_mp_int(uint8_t *dst, mp_int *A, uint16_t *psz) int mp_mul(mp_int *A, mp_int *B, mp_int *C) { int res = MP_OKAY; + status_t status; int szA, szB; szA = mp_unsigned_bin_size(A); szB = mp_unsigned_bin_size(B); @@ -131,24 +132,29 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) /* unsigned multiply */ uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrN = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - if (ptrA && ptrB && ptrC) { - uint16_t sizeA, sizeB; + if (ptrA && ptrB && ptrN && ptrC) { + uint16_t sizeA, sizeB, sizeC = 0; res = ltc_get_lsb_bin_from_mp_int(ptrA, A, &sizeA); if (res == MP_OKAY) res = ltc_get_lsb_bin_from_mp_int(ptrB, B, &sizeB); if (res == MP_OKAY) { - XMEMSET(ptrC, 0xFF, LTC_MAX_INT_BYTES); + XMEMSET(ptrN, 0xFF, LTC_MAX_INT_BYTES); - LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrC, - LTC_MAX_INT_BYTES, ptrB, &sizeB, kLTC_PKHA_IntegerArith, + status = LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrN, + LTC_MAX_INT_BYTES, ptrC, &sizeC, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); - - ltc_reverse_array(ptrB, sizeB); - res = mp_read_unsigned_bin(C, ptrB, sizeB); + if (status == kStatus_Success) { + ltc_reverse_array(ptrC, sizeC); + res = mp_read_unsigned_bin(C, ptrC, sizeC); + } + else { + res = MP_VAL; + } } } @@ -162,6 +168,9 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) if (ptrB) { XFREE(ptrB, NULL, DYNAMIC_TYPE_BIGINT); } + if (ptrN) { + XFREE(ptrN, NULL, DYNAMIC_TYPE_BIGINT); + } if (ptrC) { XFREE(ptrC, NULL, DYNAMIC_TYPE_BIGINT); } @@ -314,6 +323,7 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) { int res = MP_OKAY; + status_t status; int szA, szB, szC; szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); @@ -358,29 +368,27 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) /* (A*B)mod C = ((A mod C) * (B mod C)) mod C */ if (res == MP_OKAY && 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)) - { + status = LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrC, sizeC, + ptrA, &sizeA, kLTC_PKHA_IntegerArith); + if (status != kStatus_Success) { res = MP_VAL; } } if (res == MP_OKAY && (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)) - { + status = LTC_PKHA_ModRed(LTC_BASE, ptrB, sizeB, ptrC, sizeC, + ptrB, &sizeB, kLTC_PKHA_IntegerArith); + if (status != kStatus_Success) { res = MP_VAL; } } if (res == MP_OKAY) { - if (kStatus_Success != LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, + status = 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)) - { + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); + if (status != kStatus_Success) { res = MP_VAL; } } From c59349c7a7783403f5bfb0e72e8d1c2425535122 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 25 May 2021 15:57:08 -0700 Subject: [PATCH 4/8] Fix for ecc_map, which is handled in hardware. Fix for NXP LTC mp_mul N value. Fix for MMCAU cast warnings. --- wolfcrypt/src/ecc.c | 7 ++---- wolfcrypt/src/md5.c | 6 ++--- wolfcrypt/src/port/nxp/ksdk_port.c | 40 +++++++++++++++++++----------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 17fcd06b5..e6e1bacee 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2278,7 +2278,7 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, #endif } - +#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) /** Map a projective Jacobian point back to affine space P [in/out] The point to map @@ -2497,6 +2497,7 @@ done: return ECC_BAD_ARG_E; #endif } +#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) { @@ -4463,14 +4464,10 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, err = MEMORY_E; } } -#ifndef FREESCALE_LTC_ECC /* this is done in hardware */ if (err == MP_OKAY) { /* Use constant time map if compiled in */ err = ecc_map_ex(pub, curve->prime, mp, 1); } -#else - (void)mp; -#endif wc_ecc_del_point_ex(base, key->heap); } diff --git a/wolfcrypt/src/md5.c b/wolfcrypt/src/md5.c index 22774d54d..a0fcf9380 100644 --- a/wolfcrypt/src/md5.c +++ b/wolfcrypt/src/md5.c @@ -127,7 +127,7 @@ static int Transform(wc_Md5* md5, const byte* data) #ifdef FREESCALE_MMCAU_CLASSIC_SHA cau_md5_hash_n((byte*)data, 1, (unsigned char*)md5->digest); #else - MMCAU_MD5_HashN((byte*)data, 1, (word32*)md5->digest); + MMCAU_MD5_HashN((byte*)data, 1, (uint32_t*)md5->digest); #endif wolfSSL_CryptHwMutexUnLock(); } @@ -148,7 +148,7 @@ static int Transform_Len(wc_Md5* md5, const byte* data, word32 len) #ifdef FREESCALE_MMCAU_CLASSIC_SHA cau_md5_hash_n(local, 1, (unsigned char*)md5->digest); #else - MMCAU_MD5_HashN(local, 1, (word32*)md5->digest); + MMCAU_MD5_HashN(local, 1, (uint32_t*)md5->digest); #endif data += WC_MD5_BLOCK_SIZE; len -= WC_MD5_BLOCK_SIZE; @@ -162,7 +162,7 @@ static int Transform_Len(wc_Md5* md5, const byte* data, word32 len) (unsigned char*)md5->digest); #else MMCAU_MD5_HashN((byte*)data, len / WC_MD5_BLOCK_SIZE, - (word32*)md5->digest); + (uint32_t*)md5->digest); #endif } wolfSSL_CryptHwMutexUnLock(); diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index 4c029a1c4..424c0e5c4 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -136,21 +136,28 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); if (ptrA && ptrB && ptrN && ptrC) { - uint16_t sizeA, sizeB, sizeC = 0; + uint16_t sizeA, sizeB, sizeN, sizeC = 0; res = ltc_get_lsb_bin_from_mp_int(ptrA, A, &sizeA); if (res == MP_OKAY) res = ltc_get_lsb_bin_from_mp_int(ptrB, B, &sizeB); if (res == MP_OKAY) { - XMEMSET(ptrN, 0xFF, LTC_MAX_INT_BYTES); + sizeN = sizeA + sizeB; + XMEMSET(ptrN, 0xFF, sizeN); + XMEMSET(ptrC, 0, LTC_MAX_INT_BYTES); - status = LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrN, - LTC_MAX_INT_BYTES, ptrC, &sizeC, kLTC_PKHA_IntegerArith, + status = LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, + ptrN, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); if (status == kStatus_Success) { ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(C, ptrC, sizeC); + + #ifndef WOLFSSL_SP_MATH + /* fix sign */ + C->sign = neg; + #endif } else { res = MP_VAL; @@ -158,10 +165,6 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) } } -#ifndef WOLFSSL_SP_MATH - /* fix sign */ - C->sign = neg; -#endif if (ptrA) { XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT); } @@ -388,15 +391,14 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) ptrB, sizeB, ptrC, sizeC, ptrD, &sizeD, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); - if (status != kStatus_Success) { + if (status == kStatus_Success) { + ltc_reverse_array(ptrD, sizeD); + res = mp_read_unsigned_bin(d, ptrD, sizeD); + } + else { res = MP_VAL; } } - - if (res == MP_OKAY) { - ltc_reverse_array(ptrD, sizeD); - res = mp_read_unsigned_bin(d, ptrD, sizeD); - } } else { res = MP_MEM; @@ -892,6 +894,16 @@ int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, heap); } +int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) +{ + /* this is handled in hardware, so no projective mapping needed */ + (void)P; + (void)modulus; + (void)mp; + (void)ct; + return MP_OKAY; +} + int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m) { int res; From 0d3530b45ded435b7f08e3186de37567f7022dec Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 25 May 2021 16:49:58 -0700 Subject: [PATCH 5/8] Cleanup NXP LTC logic. --- wolfcrypt/src/port/nxp/ksdk_port.c | 46 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index 424c0e5c4..cc71a6121 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -124,17 +124,16 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) /* 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 = 0; - -#ifndef WOLFSSL_SP_MATH - neg = (A->sign == B->sign) ? MP_ZPOS : MP_NEG; -#endif - - /* unsigned multiply */ uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrN = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + /* unsigned multiply */ +#ifndef WOLFSSL_SP_MATH + neg = (A->sign == B->sign) ? MP_ZPOS : MP_NEG; +#endif + if (ptrA && ptrB && ptrN && ptrC) { uint16_t sizeA, sizeB, sizeN, sizeC = 0; @@ -328,34 +327,38 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) int res = MP_OKAY; status_t status; int szA, szB, szC; + szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); szC = mp_unsigned_bin_size(c); + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { - mp_int t; - uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrD = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); +#ifndef WOLFSSL_SP_MATH /* if A or B is negative, subtract abs(A) or abs(B) from modulus to get * positive integer representation of the same number */ + mp_int t; res = mp_init(&t); -#ifndef WOLFSSL_SP_MATH - if (a->sign) { - if (res == MP_OKAY) - res = mp_add(a, c, &t); - if (res == MP_OKAY) - res = mp_copy(&t, a); - } - if (b->sign) { - if (res == MP_OKAY) - res = mp_add(b, c, &t); - if (res == MP_OKAY) - res = mp_copy(&t, b); + if (res == MP_OKAY) { + if (a->sign) { + if (res == MP_OKAY) + res = mp_add(a, c, &t); + if (res == MP_OKAY) + res = mp_copy(&t, a); + } + if (b->sign) { + if (res == MP_OKAY) + res = mp_add(b, c, &t); + if (res == MP_OKAY) + res = mp_copy(&t, b); + } + mp_clear(&t); } #endif @@ -416,9 +419,6 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) if (ptrD) { XFREE(ptrD, NULL, DYNAMIC_TYPE_BIGINT); } - #ifndef USE_FAST_MATH - mp_clear(&t); - #endif } else { #if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) From 8bf2cbf55e13d06ac6e83622d2e47601c2ac1f39 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 26 May 2021 10:30:47 -0700 Subject: [PATCH 6/8] Fix for NXP LTC to not modify incoming math variables (use temp). Added build option for testing/validation of the LTC math operation. --- wolfcrypt/src/port/nxp/ksdk_port.c | 214 ++++++++++++++++++++++------- 1 file changed, 166 insertions(+), 48 deletions(-) diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index cc71a6121..c8da8ba7a 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -42,6 +42,8 @@ #define ERROR_OUT(res) { ret = (res); goto done; } +/* For debugging only - Enable this to do software tests of each operation */ +/* #define ENABLE_NXPLTC_TESTS */ int ksdk_port_init(void) { @@ -118,6 +120,13 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) int res = MP_OKAY; status_t status; int szA, szB; + +#ifdef ENABLE_NXPLTC_TESTS + mp_int t; + mp_init(&t); + wolfcrypt_mp_mul(A, B, &t); +#endif + szA = mp_unsigned_bin_size(A); szB = mp_unsigned_bin_size(B); @@ -184,6 +193,18 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) res = wolfcrypt_mp_mul(A, B, C); #endif } + +#ifdef ENABLE_NXPLTC_TESTS + /* compare hardware vs software */ + if (mp_cmp(&t, C) != MP_EQ) { + printf("mp_mul test fail!\n"); + + mp_dump("C", C, 0); + mp_dump("C soft", &t, 0); + } + mp_clear(&t); +#endif + return res; } @@ -192,10 +213,16 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) { int res = MP_OKAY; int szA, szB; + +#ifdef ENABLE_NXPLTC_TESTS + mp_int t; + mp_init(&t); + wolfcrypt_mp_mod(a, b, &t); +#endif + szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); - if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) - { + if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) { int neg = 0; uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); @@ -220,6 +247,11 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) { ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(c, ptrC, sizeC); + + #ifndef WOLFSSL_SP_MATH + /* fix sign */ + c->sign = neg; + #endif } else { res = MP_VAL; @@ -230,11 +262,6 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) res = MP_MEM; } -#ifndef WOLFSSL_SP_MATH - /* fix sign */ - c->sign = neg; -#endif - if (ptrA) { XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT); } @@ -253,6 +280,17 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) #endif } +#ifdef ENABLE_NXPLTC_TESTS + /* compare hardware vs software */ + if (mp_cmp(&t, c) != MP_EQ) { + printf("mp_mod test fail!\n"); + + mp_dump("C", c, 0); + mp_dump("C soft", &t, 0); + } + mp_clear(&t); +#endif + return res; } @@ -261,6 +299,13 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) { int res = MP_OKAY; int szA, szB; + +#ifdef ENABLE_NXPLTC_TESTS + mp_int t; + mp_init(&t); + wolfcrypt_mp_invmod(a, b, &t); +#endif + szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) { @@ -288,6 +333,10 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) &sizeC, kLTC_PKHA_IntegerArith) == kStatus_Success) { ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(c, ptrC, sizeC); + + #ifndef WOLFSSL_SP_MATH + c->sign = a->sign; + #endif } else { res = MP_VAL; @@ -298,9 +347,6 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) res = MP_MEM; } -#ifndef WOLFSSL_SP_MATH - c->sign = a->sign; -#endif if (ptrA) { XFREE(ptrA, NULL, DYNAMIC_TYPE_BIGINT); } @@ -318,6 +364,18 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) res = NOT_COMPILED_IN; #endif } + +#ifdef ENABLE_NXPLTC_TESTS + /* compare hardware vs software */ + if (mp_cmp(&t, c) != MP_EQ) { + printf("mp_invmod test fail!\n"); + + mp_dump("C", c, 0); + mp_dump("C soft", &t, 0); + } + mp_clear(&t); +#endif + return res; } @@ -327,6 +385,12 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) int res = MP_OKAY; status_t status; int szA, szB, szC; + +#ifdef ENABLE_NXPLTC_TESTS + mp_int t; + mp_init(&t); + wolfcrypt_mp_mulmod(a, b, c, &t); +#endif szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); @@ -335,39 +399,44 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { - uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrD = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA, *ptrB, *ptrC, *ptrD; #ifndef WOLFSSL_SP_MATH /* if A or B is negative, subtract abs(A) or abs(B) from modulus to get * positive integer representation of the same number */ - mp_int t; - res = mp_init(&t); + mp_int aabs, babs; + res = mp_init_multi(&aabs, &babs, NULL, NULL, NULL, NULL); + if (res != MP_OKAY) { + return res; + } + if (a->sign) + res = mp_add(a, c, &aabs); + else + res = mp_copy(a, &aabs); if (res == MP_OKAY) { - if (a->sign) { - if (res == MP_OKAY) - res = mp_add(a, c, &t); - if (res == MP_OKAY) - res = mp_copy(&t, a); - } - if (b->sign) { - if (res == MP_OKAY) - res = mp_add(b, c, &t); - if (res == MP_OKAY) - res = mp_copy(&t, b); - } - mp_clear(&t); + if (b->sign) + res = mp_add(b, c, &babs); + else + res = mp_copy(b, &babs); + } + if (res != MP_OKAY) { + mp_clear(&aabs); + mp_clear(&babs); + return res; } #endif - if (res == MP_OKAY && ptrA && ptrB && ptrC && ptrD) { + ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + ptrD = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + + if (ptrA && ptrB && ptrC && ptrD) { uint16_t sizeA, sizeB, sizeC, sizeD; - res = ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); + res = ltc_get_lsb_bin_from_mp_int(ptrA, &aabs, &sizeA); if (res == MP_OKAY) - res = ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); + res = ltc_get_lsb_bin_from_mp_int(ptrB, &babs, &sizeB); if (res == MP_OKAY) res = ltc_get_lsb_bin_from_mp_int(ptrC, c, &sizeC); @@ -419,6 +488,11 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) if (ptrD) { XFREE(ptrD, NULL, DYNAMIC_TYPE_BIGINT); } + + #ifndef WOLFSSL_SP_MATH + mp_clear(&aabs); + mp_clear(&babs); + #endif } else { #if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) @@ -428,6 +502,17 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) #endif } +#ifdef ENABLE_NXPLTC_TESTS + /* compare hardware vs software */ + if (mp_cmp(&t, d) != MP_EQ) { + printf("mp_mulmod test fail!\n"); + + mp_dump("D", d, 0); + mp_dump("D soft", &t, 0); + } + mp_clear(&t); +#endif + return res; } @@ -440,6 +525,12 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) mp_int tmp; #endif +#ifdef ENABLE_NXPLTC_TESTS + mp_int t; + mp_init(&t); + res = wolfcrypt_mp_exptmod(G, X, P, Y); +#endif + /* if G cannot fit into LTC_PKHA, reduce it */ szA = mp_unsigned_bin_size(G); #if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) @@ -448,6 +539,7 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) if (res != MP_OKAY) return res; if ((res = mp_mod(G, P, &tmp)) != MP_OKAY) { + mp_clear(&tmp); return res; } G = &tmp; @@ -461,26 +553,28 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { - mp_int t; - uint16_t sizeG, sizeX, sizeP; - uint8_t *ptrG = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrX = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrP = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrG, *ptrX, *ptrP; /* if G is negative, add modulus to convert to positive number for LTC */ - res = mp_init(&t); #ifndef WOLFSSL_SP_MATH - if (G->sign) { - if (res == MP_OKAY) - res = mp_add(G, P, &t); - if (res == MP_OKAY) - res = mp_copy(&t, G); + mp_int gabs; + res = mp_init(&gabs); + if (G->sign) + res = mp_add(G, P, &gabs); + else + res = mp_copy(G, &gabs); + if (res != MP_OKAY) { + mp_clear(&gabs); + return res; } #endif - if (res == MP_OKAY && ptrG && ptrX && ptrP) { - res = ltc_get_lsb_bin_from_mp_int(ptrG, G, &sizeG); + ptrG = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + ptrX = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + ptrP = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + if (ptrG && ptrX && ptrP) { + res = ltc_get_lsb_bin_from_mp_int(ptrG, &gabs, &sizeG); if (res == MP_OKAY) res = ltc_get_lsb_bin_from_mp_int(ptrX, X, &sizeX); if (res == MP_OKAY) @@ -528,8 +622,8 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) if (ptrP) { XFREE(ptrP, NULL, DYNAMIC_TYPE_BIGINT); } - #ifndef USE_FAST_MATH - mp_clear(&t); + #ifndef WOLFSSL_SP_MATH + mp_clear(&gabs); #endif } else { @@ -540,6 +634,17 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) #endif } +#ifdef ENABLE_NXPLTC_TESTS + /* compare hardware vs software */ + if (mp_cmp(&t, Y) != MP_EQ) { + printf("mp_exptmod test fail!\n"); + + mp_dump("Y", Y, 0); + mp_dump("Y soft", &t, 0); + } + mp_clear(&t); +#endif + #ifndef USE_FAST_MATH if (szA > LTC_MAX_INT_BYTES) mp_clear(&tmp); @@ -548,7 +653,7 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) return res; } -int mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +int mp_exptmod_nct(mp_int * G, mp_int * X, mp_int * P, mp_int * Y) { /* use hardware implementation even for non-constant time operations */ return mp_exptmod(G, X, P, Y); @@ -561,6 +666,11 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) int res = MP_OKAY; int szA; +#ifdef ENABLE_NXPLTC_TESTS + int result_soft = 0; + res = mp_prime_is_prime_ex(a, t, &result_soft, rng); +#endif + szA = mp_unsigned_bin_size(a); if (szA <= LTC_MAX_INT_BYTES) { uint16_t sizeA, sizeB; @@ -613,6 +723,14 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) res = NOT_COMPILED_IN; #endif } + +#ifdef ENABLE_NXPLTC_TESTS + /* compare hardware vs software */ + if (*result != result_soft) { + printf("Fail! mp_prime_is_prime_ex %d != %d\n", *result, result_soft); + } +#endif + return res; } From eb63ab19e2579c4ddab6f603f34819c16b96d5f0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 1 Jun 2021 16:33:58 -0700 Subject: [PATCH 7/8] Fix for `mp_mulmod` with NXP LTC. --- wolfcrypt/src/port/nxp/ksdk_port.c | 274 ++++++++++++----------------- 1 file changed, 113 insertions(+), 161 deletions(-) diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index c8da8ba7a..0ef8b12f5 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -44,6 +44,9 @@ /* For debugging only - Enable this to do software tests of each operation */ /* #define ENABLE_NXPLTC_TESTS */ +#ifdef ENABLE_NXPLTC_TESTS +static int doLtcTest = 0; +#endif int ksdk_port_init(void) { @@ -111,7 +114,6 @@ static int ltc_get_lsb_bin_from_mp_int(uint8_t *dst, mp_int *A, uint16_t *psz) /* LTC TFM */ #if defined(FREESCALE_LTC_TFM) - /* these function are used by wolfSSL upper layers (like RSA) */ /* c = a * b */ @@ -124,7 +126,8 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) #ifdef ENABLE_NXPLTC_TESTS mp_int t; mp_init(&t); - wolfcrypt_mp_mul(A, B, &t); + if (doLtcTest) + wolfcrypt_mp_mul(A, B, &t); #endif szA = mp_unsigned_bin_size(A); @@ -154,10 +157,13 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) XMEMSET(ptrN, 0xFF, sizeN); XMEMSET(ptrC, 0, LTC_MAX_INT_BYTES); - status = LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, ptrB, sizeB, - ptrN, sizeN, ptrC, &sizeC, kLTC_PKHA_IntegerArith, - kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, - kLTC_PKHA_TimingEqualized); + status = LTC_PKHA_ModMul(LTC_BASE, + ptrA, sizeA, /* first integer */ + ptrB, sizeB, /* second integer */ + ptrN, sizeN, /* modulus */ + ptrC, &sizeC, /* out */ + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); if (status == kStatus_Success) { ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(C, ptrC, sizeC); @@ -196,7 +202,7 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) #ifdef ENABLE_NXPLTC_TESTS /* compare hardware vs software */ - if (mp_cmp(&t, C) != MP_EQ) { + if (doLtcTest && mp_cmp(&t, C) != MP_EQ) { printf("mp_mul test fail!\n"); mp_dump("C", C, 0); @@ -217,7 +223,8 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) #ifdef ENABLE_NXPLTC_TESTS mp_int t; mp_init(&t); - wolfcrypt_mp_mod(a, b, &t); + if (doLtcTest) + wolfcrypt_mp_mod(a, b, &t); #endif szA = mp_unsigned_bin_size(a); @@ -282,7 +289,7 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) #ifdef ENABLE_NXPLTC_TESTS /* compare hardware vs software */ - if (mp_cmp(&t, c) != MP_EQ) { + if (doLtcTest && mp_cmp(&t, c) != MP_EQ) { printf("mp_mod test fail!\n"); mp_dump("C", c, 0); @@ -303,7 +310,8 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) #ifdef ENABLE_NXPLTC_TESTS mp_int t; mp_init(&t); - wolfcrypt_mp_invmod(a, b, &t); + if (doLtcTest) + wolfcrypt_mp_invmod(a, b, &t); #endif szA = mp_unsigned_bin_size(a); @@ -321,8 +329,8 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) res = ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); /* if a >= b then reduce */ - if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrB, - sizeB) >= 0) { + if (res == MP_OKAY && + LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrB, sizeB) >= 0) { if (LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, ptrA, &sizeA, kLTC_PKHA_IntegerArith) != kStatus_Success) { res = MP_VAL; @@ -367,7 +375,7 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) #ifdef ENABLE_NXPLTC_TESTS /* compare hardware vs software */ - if (mp_cmp(&t, c) != MP_EQ) { + if (doLtcTest && mp_cmp(&t, c) != MP_EQ) { printf("mp_invmod test fail!\n"); mp_dump("C", c, 0); @@ -389,7 +397,8 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) #ifdef ENABLE_NXPLTC_TESTS mp_int t; mp_init(&t); - wolfcrypt_mp_mulmod(a, b, c, &t); + if (doLtcTest) + wolfcrypt_mp_mulmod(a, b, c, &t); #endif szA = mp_unsigned_bin_size(a); @@ -399,77 +408,63 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { + int neg = 0; uint8_t *ptrA, *ptrB, *ptrC, *ptrD; -#ifndef WOLFSSL_SP_MATH - /* if A or B is negative, subtract abs(A) or abs(B) from modulus to get - * positive integer representation of the same number */ - mp_int aabs, babs; - res = mp_init_multi(&aabs, &babs, NULL, NULL, NULL, NULL); - if (res != MP_OKAY) { - return res; - } - if (a->sign) - res = mp_add(a, c, &aabs); - else - res = mp_copy(a, &aabs); - if (res == MP_OKAY) { - if (b->sign) - res = mp_add(b, c, &babs); - else - res = mp_copy(b, &babs); - } - if (res != MP_OKAY) { - mp_clear(&aabs); - mp_clear(&babs); - return res; - } -#endif - ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); ptrD = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + /* unsigned multiply */ +#ifndef WOLFSSL_SP_MATH + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; +#endif + if (ptrA && ptrB && ptrC && ptrD) { - uint16_t sizeA, sizeB, sizeC, sizeD; + uint16_t sizeA, sizeB, sizeC, sizeD = 0; - res = ltc_get_lsb_bin_from_mp_int(ptrA, &aabs, &sizeA); + /* Multiply A * B = D */ + res = ltc_get_lsb_bin_from_mp_int(ptrA, a, &sizeA); if (res == MP_OKAY) - res = ltc_get_lsb_bin_from_mp_int(ptrB, &babs, &sizeB); - if (res == MP_OKAY) - res = ltc_get_lsb_bin_from_mp_int(ptrC, c, &sizeC); - - /* (A*B)mod C = ((A mod C) * (B mod C)) mod C */ - if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrC, - sizeC) >= 0) { - status = LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrC, sizeC, - ptrA, &sizeA, kLTC_PKHA_IntegerArith); - if (status != kStatus_Success) { - res = MP_VAL; - } - } - if (res == MP_OKAY && (LTC_PKHA_CompareBigNum(ptrB, sizeB, ptrC, - sizeC) >= 0)) { - status = LTC_PKHA_ModRed(LTC_BASE, ptrB, sizeB, ptrC, sizeC, - ptrB, &sizeB, kLTC_PKHA_IntegerArith); - if (status != kStatus_Success) { - res = MP_VAL; - } - } - + res = ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); if (res == MP_OKAY) { - status = LTC_PKHA_ModMul(LTC_BASE, ptrA, sizeA, - ptrB, sizeB, ptrC, sizeC, ptrD, &sizeD, + /* modulus C is all F's for integer multiply */ + sizeC = sizeA + sizeB; + XMEMSET(ptrC, 0xFF, sizeC); + XMEMSET(ptrD, 0, LTC_MAX_INT_BYTES); + + status = LTC_PKHA_ModMul(LTC_BASE, + ptrA, sizeA, /* first integer */ + ptrB, sizeB, /* second integer */ + ptrC, sizeC, /* modulus */ + ptrD, &sizeD, /* out */ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, kLTC_PKHA_NormalValue, kLTC_PKHA_TimingEqualized); - if (status == kStatus_Success) { - ltc_reverse_array(ptrD, sizeD); - res = mp_read_unsigned_bin(d, ptrD, sizeD); - } - else { + if (status != kStatus_Success) res = MP_VAL; - } + } + /* load modulus */ + if (res == MP_OKAY) + res = ltc_get_lsb_bin_from_mp_int(ptrC, c, &sizeC); + /* perform D mod C = D */ + if (res == MP_OKAY) { + status = LTC_PKHA_ModRed(LTC_BASE, + ptrD, sizeD, + ptrC, sizeC, + ptrD, &sizeD, + kLTC_PKHA_IntegerArith); + if (status != kStatus_Success) + res = MP_VAL; + } + if (res == MP_OKAY) { + ltc_reverse_array(ptrD, sizeD); + res = mp_read_unsigned_bin(d, ptrD, sizeD); + + #ifndef WOLFSSL_SP_MATH + /* fix sign */ + d->sign = neg; + #endif } } else { @@ -488,11 +483,6 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) if (ptrD) { XFREE(ptrD, NULL, DYNAMIC_TYPE_BIGINT); } - - #ifndef WOLFSSL_SP_MATH - mp_clear(&aabs); - mp_clear(&babs); - #endif } else { #if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) @@ -504,7 +494,7 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) #ifdef ENABLE_NXPLTC_TESTS /* compare hardware vs software */ - if (mp_cmp(&t, d) != MP_EQ) { + if (doLtcTest && mp_cmp(&t, d) != MP_EQ) { printf("mp_mulmod test fail!\n"); mp_dump("D", d, 0); @@ -520,111 +510,77 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) { int res = MP_OKAY; - int szA, szB, szC; -#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) - mp_int tmp; -#endif + int szG, szX, szP; #ifdef ENABLE_NXPLTC_TESTS mp_int t; mp_init(&t); - res = wolfcrypt_mp_exptmod(G, X, P, Y); + if (doLtcTest) + wolfcrypt_mp_exptmod(G, X, P, &t); #endif - /* if G cannot fit into LTC_PKHA, reduce it */ - szA = mp_unsigned_bin_size(G); -#if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) - if (szA > LTC_MAX_INT_BYTES) { - res = mp_init(&tmp); - if (res != MP_OKAY) - return res; - if ((res = mp_mod(G, P, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - G = &tmp; - szA = mp_unsigned_bin_size(G); - } -#endif - szB = mp_unsigned_bin_size(X); - szC = mp_unsigned_bin_size(P); + szG = mp_unsigned_bin_size(G); + szX = mp_unsigned_bin_size(X); + szP = mp_unsigned_bin_size(P); - if ((szA <= LTC_MAX_INT_BYTES) && - (szB <= LTC_MAX_INT_BYTES) && - (szC <= LTC_MAX_INT_BYTES)) + if ((szG <= LTC_MAX_INT_BYTES) && + (szX <= LTC_MAX_INT_BYTES) && + (szP <= LTC_MAX_INT_BYTES)) { - uint16_t sizeG, sizeX, sizeP; - uint8_t *ptrG, *ptrX, *ptrP; - - /* if G is negative, add modulus to convert to positive number for LTC */ -#ifndef WOLFSSL_SP_MATH - mp_int gabs; - res = mp_init(&gabs); - if (G->sign) - res = mp_add(G, P, &gabs); - else - res = mp_copy(G, &gabs); - if (res != MP_OKAY) { - mp_clear(&gabs); - return res; - } -#endif + uint16_t sizeG, sizeX, sizeP, sizeY; + uint8_t *ptrG, *ptrX, *ptrP, *ptrY; ptrG = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); ptrX = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); ptrP = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - if (ptrG && ptrX && ptrP) { - res = ltc_get_lsb_bin_from_mp_int(ptrG, &gabs, &sizeG); + ptrY = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + if (ptrG && ptrX && ptrP && ptrY) { + res = ltc_get_lsb_bin_from_mp_int(ptrG, G, &sizeG); if (res == MP_OKAY) res = ltc_get_lsb_bin_from_mp_int(ptrX, X, &sizeX); if (res == MP_OKAY) res = 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 exponentiation */ - /* 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 reduce */ - if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrG, sizeG, ptrP, - sizeP) >= 0) { - if (LTC_PKHA_ModRed(LTC_BASE, ptrG, sizeG, ptrP, sizeP, - ptrG, &sizeG, kLTC_PKHA_IntegerArith) != kStatus_Success) { - res = MP_VAL; - } + if (res == MP_OKAY && + LTC_PKHA_CompareBigNum(ptrG, sizeG, ptrP, sizeP) >= 0) { + res = LTC_PKHA_ModRed(LTC_BASE, + ptrG, sizeG, + ptrP, sizeP, + ptrG, &sizeG, kLTC_PKHA_IntegerArith); + res = (res == kStatus_Success) ? MP_OKAY: MP_VAL; } - if (res == MP_OKAY) { - if (LTC_PKHA_ModExp(LTC_BASE, ptrG, sizeG, ptrP, sizeP, ptrX, sizeX, - ptrP, &sizeP, kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, - kLTC_PKHA_TimingEqualized) != kStatus_Success) { - res = MP_VAL; - } - else { - ltc_reverse_array(ptrP, sizeP); - res = mp_read_unsigned_bin(Y, ptrP, sizeP); - } + res = LTC_PKHA_ModExp(LTC_BASE, + ptrG, sizeG, /* integer input */ + ptrP, sizeP, /* modulus */ + ptrX, sizeX, /* expenoent */ + ptrY, &sizeY, /* out */ + kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, + kLTC_PKHA_TimingEqualized); + res = (res == kStatus_Success) ? MP_OKAY: MP_VAL; + } + if (res == MP_OKAY) { + ltc_reverse_array(ptrY, sizeY); + res = mp_read_unsigned_bin(Y, ptrY, sizeY); } } else { res = MP_MEM; } - if (ptrG) { - XFREE(ptrG, NULL, DYNAMIC_TYPE_BIGINT); - } - if (ptrX) { - XFREE(ptrX, NULL, DYNAMIC_TYPE_BIGINT); + if (ptrY) { + XFREE(ptrY, NULL, DYNAMIC_TYPE_BIGINT); } if (ptrP) { XFREE(ptrP, NULL, DYNAMIC_TYPE_BIGINT); } - #ifndef WOLFSSL_SP_MATH - mp_clear(&gabs); - #endif + if (ptrX) { + XFREE(ptrX, NULL, DYNAMIC_TYPE_BIGINT); + } + if (ptrG) { + XFREE(ptrG, NULL, DYNAMIC_TYPE_BIGINT); + } } else { #if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) @@ -636,7 +592,7 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) #ifdef ENABLE_NXPLTC_TESTS /* compare hardware vs software */ - if (mp_cmp(&t, Y) != MP_EQ) { + if (doLtcTest && mp_cmp(&t, Y) != MP_EQ) { printf("mp_exptmod test fail!\n"); mp_dump("Y", Y, 0); @@ -645,11 +601,6 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) mp_clear(&t); #endif -#ifndef USE_FAST_MATH - if (szA > LTC_MAX_INT_BYTES) - mp_clear(&tmp); -#endif - return res; } @@ -668,7 +619,8 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) #ifdef ENABLE_NXPLTC_TESTS int result_soft = 0; - res = mp_prime_is_prime_ex(a, t, &result_soft, rng); + if (doLtcTest) + mp_prime_is_prime_ex(a, t, &result_soft, rng); #endif szA = mp_unsigned_bin_size(a); @@ -726,7 +678,7 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) #ifdef ENABLE_NXPLTC_TESTS /* compare hardware vs software */ - if (*result != result_soft) { + if (doLtcTest && *result != result_soft) { printf("Fail! mp_prime_is_prime_ex %d != %d\n", *result, result_soft); } #endif @@ -1164,7 +1116,7 @@ status_t LTC_PKHA_Prime25519SquareRootMod(const uint8_t *A, size_t sizeA, /* I = I - 1 */ XMEMSET(VV, 0xff, sizeof(VV)); /* just temp for maximum integer - for non-modular subtract */ - if (0 <= LTC_PKHA_CompareBigNum(I, szI, &one, sizeof(one))) { + if (LTC_PKHA_CompareBigNum(I, szI, &one, sizeof(one)) >= 0) { if (status == kStatus_Success) { status = LTC_PKHA_ModSub1(LTC_BASE, I, szI, &one, sizeof(one), VV, sizeof(VV), I, &szI); From 5f99979597b56e4b5e63b74f07d963107120f55e Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 11 Jun 2021 09:10:26 -0700 Subject: [PATCH 8/8] Peer review feedback and improvements. --- wolfcrypt/src/port/nxp/ksdk_port.c | 116 ++++++++++++++++++----------- 1 file changed, 74 insertions(+), 42 deletions(-) diff --git a/wolfcrypt/src/port/nxp/ksdk_port.c b/wolfcrypt/src/port/nxp/ksdk_port.c index 0ef8b12f5..8e3e5cf37 100644 --- a/wolfcrypt/src/port/nxp/ksdk_port.c +++ b/wolfcrypt/src/port/nxp/ksdk_port.c @@ -100,7 +100,8 @@ static int ltc_get_lsb_bin_from_mp_int(uint8_t *dst, mp_int *A, uint16_t *psz) sz = mp_unsigned_bin_size(A); #ifndef WOLFSSL_SP_MATH - res = mp_to_unsigned_lsb_bin(A, dst); /* result is lsbyte at lowest addr as required by LTC */ + /* result is lsbyte at lowest addr as required by LTC */ + res = mp_to_unsigned_lsb_bin(A, dst); #else res = mp_to_unsigned_bin(A, dst); if (res == MP_OKAY) { @@ -133,17 +134,22 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) szA = mp_unsigned_bin_size(A); szB = mp_unsigned_bin_size(B); - /* if unsigned mul can fit into LTC PKHA let's use it, otherwise call software mul */ + /* 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 = 0; - uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrN = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrN = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); /* unsigned multiply */ -#ifndef WOLFSSL_SP_MATH - neg = (A->sign == B->sign) ? MP_ZPOS : MP_NEG; +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) + int neg = (A->sign == B->sign) ? MP_ZPOS : MP_NEG; #endif if (ptrA && ptrB && ptrN && ptrC) { @@ -168,10 +174,11 @@ int mp_mul(mp_int *A, mp_int *B, mp_int *C) ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(C, ptrC, sizeC); - #ifndef WOLFSSL_SP_MATH +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) /* fix sign */ C->sign = neg; - #endif +#endif } else { res = MP_VAL; @@ -230,14 +237,17 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) { - int neg = 0; - uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); -#ifndef WOLFSSL_SP_MATH +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) /* get sign for the result */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + int neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; #endif /* get remainder of unsigned a divided by unsigned b */ @@ -255,10 +265,11 @@ int mp_mod(mp_int *a, mp_int *b, mp_int *c) ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(c, ptrC, sizeC); - #ifndef WOLFSSL_SP_MATH +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) /* fix sign */ c->sign = neg; - #endif +#endif } else { res = MP_VAL; @@ -317,9 +328,12 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) szA = mp_unsigned_bin_size(a); szB = mp_unsigned_bin_size(b); if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES)) { - uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); - uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); + uint8_t *ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrB = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); + uint8_t *ptrC = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, + DYNAMIC_TYPE_BIGINT); if (ptrA && ptrB && ptrC) { uint16_t sizeA, sizeB, sizeC; @@ -329,6 +343,7 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) res = ltc_get_lsb_bin_from_mp_int(ptrB, b, &sizeB); /* if a >= b then reduce */ + /* TODO: Perhaps always do mod reduce depending on hardware performance */ if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrA, sizeA, ptrB, sizeB) >= 0) { if (LTC_PKHA_ModRed(LTC_BASE, ptrA, sizeA, ptrB, sizeB, @@ -342,9 +357,11 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c) ltc_reverse_array(ptrC, sizeC); res = mp_read_unsigned_bin(c, ptrC, sizeC); - #ifndef WOLFSSL_SP_MATH + +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) c->sign = a->sign; - #endif +#endif } else { res = MP_VAL; @@ -408,7 +425,6 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) if ((szA <= LTC_MAX_INT_BYTES) && (szB <= LTC_MAX_INT_BYTES) && (szC <= LTC_MAX_INT_BYTES)) { - int neg = 0; uint8_t *ptrA, *ptrB, *ptrC, *ptrD; ptrA = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); @@ -417,8 +433,9 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) ptrD = (uint8_t*)XMALLOC(LTC_MAX_INT_BYTES, NULL, DYNAMIC_TYPE_BIGINT); /* unsigned multiply */ -#ifndef WOLFSSL_SP_MATH - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) + int neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; #endif if (ptrA && ptrB && ptrC && ptrD) { @@ -461,10 +478,11 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) ltc_reverse_array(ptrD, sizeD); res = mp_read_unsigned_bin(d, ptrD, sizeD); - #ifndef WOLFSSL_SP_MATH +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) /* fix sign */ d->sign = neg; - #endif +#endif } } else { @@ -507,7 +525,7 @@ int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d) } /* Y = G^X mod P */ -int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) +int ltc_mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int useConstTime) { int res = MP_OKAY; int szG, szX, szP; @@ -542,6 +560,7 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) res = ltc_get_lsb_bin_from_mp_int(ptrP, P, &sizeP); /* if G >= P then reduce */ + /* TODO: Perhaps always do mod reduce depending on hardware performance */ if (res == MP_OKAY && LTC_PKHA_CompareBigNum(ptrG, sizeG, ptrP, sizeP) >= 0) { res = LTC_PKHA_ModRed(LTC_BASE, @@ -557,7 +576,8 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) ptrX, sizeX, /* expenoent */ ptrY, &sizeY, /* out */ kLTC_PKHA_IntegerArith, kLTC_PKHA_NormalValue, - kLTC_PKHA_TimingEqualized); + useConstTime ? kLTC_PKHA_TimingEqualized : + kLTC_PKHA_NoTimingEqualized); res = (res == kStatus_Success) ? MP_OKAY: MP_VAL; } if (res == MP_OKAY) { @@ -604,10 +624,14 @@ int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) return res; } +int mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y) +{ + return ltc_mp_exptmod(G, X, P, Y, 1); +} + int mp_exptmod_nct(mp_int * G, mp_int * X, mp_int * P, mp_int * Y) { - /* use hardware implementation even for non-constant time operations */ - return mp_exptmod(G, X, P, Y); + return ltc_mp_exptmod(G, X, P, Y, 0); } #if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || \ @@ -670,7 +694,7 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) } else { #if defined(FREESCALE_LTC_TFM_RSA_4096_ENABLE) - res = mp_prime_is_prime_ex(a, t, result, rng); + res = wolfcrypt_mp_prime_is_prime_ex(a, t, result, rng); #else res = NOT_COMPILED_IN; #endif @@ -688,7 +712,8 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) int mp_prime_is_prime(mp_int* a, int t, int* result) { - return mp_prime_is_prime_ex(a, t, result, NULL); + /* the NXP LTC prime check requires an RNG, so use software version */ + return wolfcrypt_mp_prime_is_prime_ex(a, t, result, NULL); } #endif /* !NO_RSA || !NO_DSA || !NO_DH || WOLFSSL_KEY_GEN */ @@ -699,7 +724,8 @@ int mp_prime_is_prime(mp_int* a, int t, int* result) #if defined(HAVE_ECC) && defined(FREESCALE_LTC_ECC) /* 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. + * 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 zeros * so that result array has 32 bytes, same as modulus (sz). @@ -923,7 +949,8 @@ int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, size = szModulus; /* find LTC friendly parameters for the selected curve */ - if (ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, size) != 0) { + if (ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, + size) != 0) { return ECC_BAD_ARG_E; } @@ -945,7 +972,8 @@ int wc_ecc_mulmod_ex(const mp_int *k, ecc_point *G, ecc_point *R, mp_int* a, /* if k is negative, we compute the multiplication with abs(-k) * with result (x, y) and modify the result to (x, -y) */ -#ifndef WOLFSSL_SP_MATH +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \ + defined(WOLFSSL_SP_INT_NEGATIVE) R->y->sign = k->sign; #endif } @@ -993,7 +1021,8 @@ int wc_ecc_point_add(ecc_point *mG, ecc_point *mQ, ecc_point *mR, mp_int *m) size = mp_unsigned_bin_size(m); /* find LTC friendly parameters for the selected curve */ - if (ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, size) != 0) { + if (ltc_get_ecc_specs(&modbin, &r2modn, &aCurveParam, &bCurveParam, + size) != 0) { res = ECC_BAD_ARG_E; } else { @@ -1053,7 +1082,8 @@ static const uint8_t invThree[32] = { /* * * 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 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) * @@ -1115,7 +1145,8 @@ status_t LTC_PKHA_Prime25519SquareRootMod(const uint8_t *A, size_t sizeA, } /* I = I - 1 */ - XMEMSET(VV, 0xff, sizeof(VV)); /* just temp for maximum integer - for non-modular subtract */ + /* just temp for maximum integer - for non-modular subtract */ + XMEMSET(VV, 0xff, sizeof(VV)); if (LTC_PKHA_CompareBigNum(I, szI, &one, sizeof(one)) >= 0) { if (status == kStatus_Success) { status = LTC_PKHA_ModSub1(LTC_BASE, I, szI, &one, sizeof(one), @@ -1769,7 +1800,8 @@ status_t LTC_PKHA_Ed25519_PointDecompress(const uint8_t *pubkey, return status; } -/* LSByte first of Ed25519 parameter l = 2^252 + 27742317777372353535851937790883648493 */ +/* 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,