diff --git a/configure.ac b/configure.ac index 8f277be6f..e7d232162 100644 --- a/configure.ac +++ b/configure.ac @@ -4693,16 +4693,17 @@ ENABLED_SP_EC_256=no ENABLED_SP_EC_384=no ENABLED_SP_NO_MALLOC=no ENABLED_SP_NONBLOCK=no +ENABLED_SP_SMALL=no for v in `echo $ENABLED_SP | tr "," " "` do case $v in small) + ENABLED_SP_SMALL=yes ENABLED_SP_RSA=yes ENABLED_SP_DH=yes ENABLED_SP_FF_2048=yes ENABLED_SP_FF_3072=yes ENABLED_SP_ECC=yes - ENABLED_SP_SMALL=yes ENABLED_SP_EC_256=yes if test "$host_cpu" = "x86_64"; then ENABLED_SP_FF_4096=yes @@ -4727,8 +4728,8 @@ do ;; smallec256 | smallp256 | small256) - ENABLED_SP_ECC=yes ENABLED_SP_SMALL=yes + ENABLED_SP_ECC=yes ENABLED_SP_EC_256=yes ;; ec256 | p256 | 256) @@ -4736,8 +4737,8 @@ do ENABLED_SP_EC_256=yes ;; smallec384 | smallp384 | small384) - ENABLED_SP_ECC=yes ENABLED_SP_SMALL=yes + ENABLED_SP_ECC=yes ENABLED_SP_EC_384=yes ;; ec384 | p384 | 384) @@ -4875,6 +4876,10 @@ if test "$ENABLED_SP_NONBLOCK" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NONBLOCK" AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NONBLOCK" fi +if test "$ENABLED_SMALL" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" +fi AC_ARG_ENABLE([sp-asm], @@ -4960,11 +4965,97 @@ if test "$ENABLED_SP_MATH" = "yes"; then ENABLED_FASTMATH="no" ENABLED_SLOWMATH="no" fi + +AC_ARG_ENABLE([sp-math-all], + [AS_HELP_STRING([--enable-sp-math],[Enable Single Precision math implementation only (default: disabled)])], + [ ENABLED_SP_MATH_ALL=$enableval ], + [ ENABLED_SP_MATH_ALL=no ], + ) +for v in `echo $ENABLED_SP_MATH_ALL | tr "," " "` +do + case $v in + yes | no) + ;; + small) + ENABLED_SP_MATH_ALL="yes" + ENABLED_SP_SMALL="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" + ;; + huge) + ENABLED_SP_MATH_ALL="yes" + ENABLED_FASTHUGEMATH="yes" + AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_HUGE_CFLAGS" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_INT_LARGE_COMBA" + ;; + 256 | 384 | 521 | 1024 | 2048 | 3072 | 4096) + AM_CFLAGS="$AM_CFLAGS -DSP_INT_BITS=$v" + ENABLED_SP_MATH_ALL="yes" + ;; + *) + AC_MSG_ERROR([Support SP int bit sizes: 256, 384, 521, 1024, 2048, 3072, 4096. $ENABLED_SP_MATH_ALL not supported]) + ;; + esac +done + +if test "$ENABLED_SP_MATH_ALL" = "yes"; then + + ENABLED_FASTMATH="no" + ENABLED_SLOWMATH="no" + ENABLED_SP="yes" + #ENABLED_SP_MATH="yes" + + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_MATH_ALL" + + case $host_cpu in + *x86_64*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_X86_64" + ;; + *x86*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_X86" + ;; + *aarch64*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM64" + ;; + *arm*) + if test $host_alias = "thumb"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM_THUMB -mthumb -march=armv6" + else + if test $host_alias = "cortex"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM_CORTEX_M -mcpu=cortex-m4" + else + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM32" + fi + fi + ;; + *ppc64* | *powerpc64*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_PPC64" + ;; + *ppc* | *powerpc*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_PPC" + ;; + *mips64*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_MIPS64" + ;; + *mips*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_MIPS" + ;; + *riscv32*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_RISCV32" + ;; + *riscv64*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_RISCV64" + ;; + *s390x*) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_S390X" + ;; + esac +fi + if test "$ENABLED_SP_MATH" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_MATH" fi - # Fast RSA using Intel IPP ippdir="${srcdir}/IPP" ipplib="lib" # if autoconf guesses 32bit system changes lib directory @@ -5487,9 +5578,6 @@ then fi AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_WOLFSCEP" fi -#if test "$ENABLED_SP_MATH" = "yes" && test "$ENABLED_KEYGEN" = "yes"; then -# AC_MSG_ERROR([Cannot use single precision math and key generation]) -#fi if test "x$ENABLED_PKCS7" = "xyes" then @@ -5597,7 +5685,17 @@ then AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_HUGE_CFLAGS" fi else - AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_CFLAGS" + if test "$ENABLED_SP" = "yes" && test "$ENABLED_SP_SMALL" = "no" + then + AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_FAST_CFLAGS" + if test "$ENABLED_FASTHUGEMATH" = "yes" + then + AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_HUGE_CFLAGS" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_INT_LARGE_COMBA" + fi + else + AM_CFLAGS="$AM_CFLAGS $OPTIMIZE_CFLAGS" + fi fi ]) fi @@ -5813,7 +5911,7 @@ AM_CONDITIONAL([BUILD_SP_ARM32],[test "x$ENABLED_SP_ARM32_ASM" = "xyes" || test AM_CONDITIONAL([BUILD_SP_ARM_THUMB],[test "x$ENABLED_SP_ARM_THUMB_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_SP_ARM_CORTEX],[test "x$ENABLED_SP_ARM_CORTEX_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_SP_X86_64],[test "x$ENABLED_SP_X86_64_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) -AM_CONDITIONAL([BUILD_SP_INT],[test "x$ENABLED_SP_MATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_INT],[test "x$ENABLED_SP_MATH" = "xyes" || test "x$ENABLED_SP_MATH_ALL" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_FAST_RSA],[test "x$ENABLED_FAST_RSA" = "xyes"]) AM_CONDITIONAL([BUILD_MCAPI],[test "x$ENABLED_MCAPI" = "xyes"]) AM_CONDITIONAL([BUILD_ASYNCCRYPT],[test "x$ENABLED_ASYNCCRYPT" = "xyes"]) @@ -6126,6 +6224,7 @@ echo " * Stack sizes in tests: $ENABLED_STACKSIZE" echo " * User Crypto: $ENABLED_USER_CRYPTO" echo " * Fast RSA: $ENABLED_FAST_RSA" echo " * Single Precision: $ENABLED_SP" +echo " * SP math implementation: $ENABLED_SP_MATH_ALL" echo " * Async Crypto: $ENABLED_ASYNCCRYPT" echo " * PKCS#11: $ENABLED_PKCS11" echo " * PKCS#12: $ENABLED_PKCS12" diff --git a/examples/client/client.c b/examples/client/client.c index 1481e685c..dc67f866d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1308,7 +1308,11 @@ static void Usage(void) printf("%s", msg[++msgid]); #endif #elif defined(USE_FAST_MATH) + #if !defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_SP_MATH) printf("%d\n", FP_MAX_BITS/2); + #else + printf("%d\n", SP_INT_MAX_BITS/2); + #endif #else /* normal math has unlimited max size */ printf("%s", msg[++msgid]); diff --git a/src/ssl.c b/src/ssl.c index 6e636c05a..4dd1c6fa6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -46101,7 +46101,6 @@ int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, return SSL_FAILURE; } -#ifdef OPENSSL_EXTRA const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void) { WOLFSSL_MSG("wolfSSL_BN_value_one"); @@ -46119,7 +46118,6 @@ const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void) return bn_one; } -#endif /* return compliant with OpenSSL * size of BIGNUM in bytes, 0 if error */ diff --git a/src/tls13.c b/src/tls13.c index dfe55333e..73a1cc9d4 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -2853,6 +2853,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo); #endif + if (ssl == NULL || ssl->arrays == NULL) + return BAD_FUNC_ARG; + /* Protocol version length check. */ if (OPAQUE16_LEN > helloSz) return BUFFER_ERROR; diff --git a/tests/api.c b/tests/api.c index 551e5ce9b..e1174da20 100644 --- a/tests/api.c +++ b/tests/api.c @@ -14237,7 +14237,7 @@ static int test_wc_MakeRsaKey (void) RsaKey genKey; WC_RNG rng; - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; #else int bits = 2048; @@ -14898,7 +14898,7 @@ static int test_wc_RsaKeyToDer (void) RsaKey genKey; WC_RNG rng; byte* der; - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; word32 derSz = 611; /* (2 x 128) + 2 (possible leading 00) + (5 x 64) + 5 (possible leading 00) @@ -15008,7 +15008,7 @@ static int test_wc_RsaKeyToPublicDer (void) RsaKey key; WC_RNG rng; byte* der; - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; word32 derLen = 162; #else @@ -15107,7 +15107,7 @@ static int test_wc_RsaPublicEncryptDecrypt (void) const char* inStr = "Everyone gets Friday off."; word32 plainLen = 25; word32 inLen = (word32)XSTRLEN(inStr); - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; word32 cipherLen = 128; #else @@ -15197,7 +15197,7 @@ static int test_wc_RsaPublicEncryptDecrypt_ex (void) const word32 plainSz = 25; byte* res = NULL; int idx = 0; - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; const word32 cipherSz = 128; #else @@ -15314,7 +15314,7 @@ static int test_wc_RsaSSL_SignVerify (void) const word32 plainSz = 25; word32 inLen = (word32)XSTRLEN(inStr); word32 idx = 0; - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; const word32 outSz = 128; #else @@ -15476,7 +15476,7 @@ static int test_wc_RsaEncryptSize (void) } printf(testingFmt, "wc_RsaEncryptSize()"); -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) if (ret == 0) { ret = MAKE_RSA_KEY(&key, 1024, WC_RSA_EXPONENT, &rng); if (ret == 0) { @@ -15546,7 +15546,7 @@ static int test_wc_RsaFlattenPublicKey (void) byte n[256]; word32 eSz = sizeof(e); word32 nSz = sizeof(n); - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) int bits = 1024; #else int bits = 2048; @@ -27928,6 +27928,8 @@ static void test_wolfSSL_BN(void) AssertIntEQ((int)(value[0] & 0x03), 3); BN_free(val); +#if !defined(WOLFSSL_SP_MATH) && (!defined(WOLFSSL_SP_MATH_ALL) || \ + defined(WOLFSSL_SP_INT_NEGATIVE)) AssertIntEQ(BN_set_word(a, 1), SSL_SUCCESS); AssertIntEQ(BN_set_word(b, 5), SSL_SUCCESS); AssertIntEQ(BN_is_word(a, (WOLFSSL_BN_ULONG)BN_get_word(a)), SSL_SUCCESS); @@ -27942,6 +27944,7 @@ static void test_wolfSSL_BN(void) } #endif AssertIntEQ(BN_get_word(c), 4); +#endif BN_free(a); BN_free(b); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index d9f623fd4..dee2727bd 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -587,8 +587,8 @@ static const char* bench_result_words1[][4] = { defined(HAVE_CURVE25519) || defined(HAVE_CURVE25519_SHARED_SECRET) || \ defined(HAVE_ED25519) || defined(HAVE_CURVE448) || \ defined(HAVE_CURVE448_SHARED_SECRET) || defined(HAVE_ED448) -#if defined(HAVE_ECC) || !defined(WOLFSSL_RSA_PUBLIC_ONLY) || \ - defined(WOLFSSL_PUBLIC_MP) || !defined(NO_DH) +#if defined(HAVE_ECC) || defined(WOLFSSL_PUBLIC_MP) || !defined(NO_DH) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) static const char* bench_desc_words[][9] = { /* 0 1 2 3 4 5 6 7 8 */ @@ -927,6 +927,27 @@ static int rsa_sign_verify = 0; static int use_ffdhe = 0; #endif + +#ifdef HAVE_ECC +/* Detect ECC key size to use */ +#ifndef BENCH_ECC_SIZE + #ifndef NO_ECC256 + #define BENCH_ECC_SIZE 32 + #elif defined(HAVE_ECC384) + #define BENCH_ECC_SIZE 48 + #elif defined(HAVE_ECC224) + #define BENCH_ECC_SIZE 28 + #elif defined(HAVE_ECC521) + #define BENCH_ECC_SIZE 66 + #else + #error No ECC keygen size defined for benchmark + #endif +#endif +#define BENCH_MAX_ECC_SIZE BENCH_ECC_SIZE + +static int bench_ecc_size = BENCH_ECC_SIZE; +#endif + /* Don't print out in CSV format by default */ static int csv_format = 0; #ifdef BENCH_ASYM @@ -4344,7 +4365,7 @@ exit: void bench_rsaKeyGen(int doAsync) { int k, keySz; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) const int keySizes[2] = {1024, 2048}; #else const int keySizes[1] = {2048}; @@ -4713,7 +4734,7 @@ void bench_rsa(int doAsync) for (i = 0; i < BENCH_MAX_PENDING; i++) { /* setup an async context for each key */ if (wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT, - doAsync ? devId : INVALID_DEVID) < 0) { + doAsync ? devId : INVALID_DEVID) < 0) { goto exit_bench_rsa; } @@ -5228,23 +5249,6 @@ void bench_ntruKeyGen(void) #endif #ifdef HAVE_ECC - -/* Detect ECC key size to use */ -#ifndef BENCH_ECC_SIZE - #ifndef NO_ECC256 - #define BENCH_ECC_SIZE 32 - #elif defined(HAVE_ECC384) - #define BENCH_ECC_SIZE 48 - #elif defined(HAVE_ECC224) - #define BENCH_ECC_SIZE 28 - #elif defined(HAVE_ECC521) - #define BENCH_ECC_SIZE 66 - #else - #error No ECC keygen size defined for benchmark - #endif -#endif -static int bench_ecc_size = BENCH_ECC_SIZE; - void bench_eccMakeKey(int doAsync) { int ret = 0, i, times, count, pending = 0; @@ -5308,11 +5312,11 @@ void bench_ecc(int doAsync) const char**desc = bench_desc_words[lng_index]; #ifdef HAVE_ECC_DHE - DECLARE_ARRAY(shared, byte, BENCH_MAX_PENDING, BENCH_ECC_SIZE, HEAP_HINT); + DECLARE_ARRAY(shared, byte, BENCH_MAX_PENDING, BENCH_MAX_ECC_SIZE, HEAP_HINT); #endif #if !defined(NO_ASN) && defined(HAVE_ECC_SIGN) DECLARE_ARRAY(sig, byte, BENCH_MAX_PENDING, ECC_MAX_SIG_SIZE, HEAP_HINT); - DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, BENCH_ECC_SIZE, HEAP_HINT); + DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, BENCH_MAX_ECC_SIZE, HEAP_HINT); #endif #ifdef DECLARE_VAR_IS_HEAP_ALLOC diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index bdd6bd1e4..e67ae7886 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -990,7 +990,8 @@ static int CheckBitString(const byte* input, word32* inOutIdx, int* len, (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \ (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \ ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ - (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) + (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \ + (!defined(NO_DSA) && !defined(HAVE_SELFTEST) && defined(WOLFSSL_KEY_GEN)) /* Set the DER/BER encoding of the ASN.1 BIT_STRING header. * diff --git a/wolfcrypt/src/cpuid.c b/wolfcrypt/src/cpuid.c index 09b265122..7bc852e60 100644 --- a/wolfcrypt/src/cpuid.c +++ b/wolfcrypt/src/cpuid.c @@ -28,8 +28,8 @@ #include -#if (defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \ - defined(WOLFSSL_AESNI)) && !defined(WOLFSSL_NO_ASM) +#if defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \ + defined(WOLFSSL_AESNI) || defined(WOLFSSL_SP_X86_64_ASM) /* Each platform needs to query info type 1 from cpuid to see if aesni is * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts */ diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index af281feb2..e19d5a49b 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1262,7 +1262,7 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz, #endif #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_SMALL_STACK x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (x == NULL) @@ -1482,6 +1482,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, ret = MP_INIT_E; } + /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */ if (ret == 0 && prime != NULL) { #ifdef WOLFSSL_HAVE_SP_DH #ifndef WOLFSSL_SP_NO_2048 @@ -1511,8 +1512,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, #endif { - /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */ -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) /* calculate (y^q) mod(p), store back into y */ if (mp_exptmod(y, q, p, y) != MP_OKAY) ret = MP_EXPTMOD_E; @@ -1797,7 +1797,7 @@ int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz, #endif #endif { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY) ret = MP_EXPTMOD_E; #else @@ -1853,14 +1853,14 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - mp_int* y; -#ifndef WOLFSSL_SP_MATH - mp_int* x; - mp_int* z; + mp_int* y = NULL; +#if !defined(WOLFSSL_SP_MATH) + mp_int* x = NULL; + mp_int* z = NULL; #endif #else mp_int y[1]; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) mp_int x[1]; mp_int z[1]; #endif @@ -1882,7 +1882,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (y == NULL) return MEMORY_E; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (x == NULL) { XFREE(y, key->heap, DYNAMIC_TYPE_DH); @@ -1911,7 +1911,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, mp_clear(y); #ifdef WOLFSSL_SMALL_STACK - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif @@ -1933,7 +1933,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, mp_clear(y); #ifdef WOLFSSL_SMALL_STACK - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif @@ -1955,7 +1955,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, mp_clear(y); #ifdef WOLFSSL_SMALL_STACK - #ifndef WOLFSSL_SP_MATH + #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif @@ -1966,7 +1966,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, #endif #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(z, key->heap, DYNAMIC_TYPE_DH); @@ -2001,7 +2001,7 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, #endif #ifdef WOLFSSL_SMALL_STACK -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 332b89c4d..115b76c27 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -150,7 +150,7 @@ ECC Curve Sizes: #include #endif -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #define GEN_MEM_ERR MP_MEM #elif defined(USE_FAST_MATH) #define GEN_MEM_ERR FP_MEM @@ -1569,7 +1569,7 @@ static void alt_fp_init(mp_int* a) int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, mp_int* a, mp_int* modulus, mp_digit mp) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_SMALL_STACK mp_int* t1 = NULL; mp_int* t2 = NULL; @@ -1936,7 +1936,7 @@ done: int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, mp_int* modulus, mp_digit mp) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_SMALL_STACK mp_int* t1 = NULL; mp_int* t2 = NULL; @@ -2252,7 +2252,7 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, */ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_SMALL_STACK mp_int* t1 = NULL; mp_int* t2 = NULL; @@ -2369,7 +2369,8 @@ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) /* get 1/z */ if (err == MP_OKAY) { -#if defined(ECC_TIMING_RESISTANT) && defined(USE_FAST_MATH) +#if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \ + defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) if (ct) { err = mp_invmod_mont_ct(z, modulus, t1, mp); if (err == MP_OKAY) @@ -2468,7 +2469,7 @@ int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp) #if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifndef ECC_TIMING_RESISTANT @@ -2805,7 +2806,6 @@ static int ecc_mulmod(mp_int* k, ecc_point* P, ecc_point* Q, ecc_point** R, #endif -#ifndef WOLFSSL_SP_MATH /* Convert the point to montogmery form. * * @param [in] p Point to convert. @@ -2861,7 +2861,6 @@ static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus, #endif return err; } -#endif /* !WOLFSSL_SP_MATH */ #ifdef WOLFSSL_SMALL_STACK_CACHE static int ecc_key_tmp_init(ecc_key* key, void* heap) @@ -2926,7 +2925,7 @@ static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap) #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) { ecc_point *tG, *M[M_POINTS]; int i, err; @@ -3021,7 +3020,7 @@ exit: return ECC_BAD_ARG_E; } #endif -#endif /* !defined(WOLFSSL_SP_MATH) && !defined(FP_ECC) */ +#endif /* !WOLFSSL_SP_MATH || !FP_ECC */ #ifndef FP_ECC /** @@ -3038,7 +3037,7 @@ exit: int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap) -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) { ecc_point *tG, *M[M_POINTS]; int i, err; @@ -3783,7 +3782,7 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, byte* out, word32* outlen, ecc_curve_spec* curve) { int err = MP_OKAY; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) ecc_point* result = NULL; word32 x = 0; #endif @@ -3825,7 +3824,7 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, else #endif #endif -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) { err = WC_KEY_SIZE_E; @@ -4185,7 +4184,7 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, { int err = MP_OKAY; #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) ecc_point* base = NULL; #endif ecc_point* pub; @@ -4223,13 +4222,8 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, } } -#ifndef WOLFSSL_SP_MATH - if ((err == MP_OKAY) && (mp_iszero(&key->k) || (key->k.sign == MP_NEG) || + if ((err == MP_OKAY) && (mp_iszero(&key->k) || mp_isneg(&key->k) || (mp_cmp(&key->k, curve->order) != MP_LT))) -#else - if ((err == MP_OKAY) && (mp_iszero(&key->k) || - (mp_cmp(&key->k, curve->order) != MP_LT))) -#endif { err = ECC_PRIV_KEY_E; } @@ -4264,7 +4258,7 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, else #endif #endif -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) err = WC_KEY_SIZE_E; #else { @@ -4377,7 +4371,7 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, int err; #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); #endif #endif /* !WOLFSSL_ATECC508A */ @@ -4527,7 +4521,7 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id, #endif /* WOLFSSL_HAVE_SP_ECC */ { /* software key gen */ -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) err = WC_KEY_SIZE_E; #else @@ -5108,7 +5102,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, ecc_key* key, mp_int *r, mp_int *s) { int err = 0; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) mp_int* e; #if (!defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)) && \ !defined(WOLFSSL_SMALL_STACK) @@ -5138,7 +5132,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return ECC_BAD_ARG_E; } -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) if (key->idx == ECC_CUSTOM_IDX || (ecc_sets[key->idx].id != ECC_SECP256R1 && ecc_sets[key->idx].id != ECC_SECP384R1)) { @@ -5146,7 +5140,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #endif -#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_HAVE_SP_ECC) +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_HAVE_SP_ECC) || \ + (defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_HAVE_SP_ECC)) if (key->idx != ECC_CUSTOM_IDX #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC @@ -5224,7 +5219,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) err = wc_ecc_alloc_mpint(key, &key->e); @@ -5516,7 +5511,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, XFREE(e, key->heap, DYNAMIC_TYPE_ECC); #endif FREE_CURVE_SPECS(); -#endif /* WOLFSSL_SP_MATH */ +#endif /* !WOLFSSL_SP_MATH */ return err; } @@ -5525,11 +5520,17 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key) { int ret = 0; + DECLARE_CURVE_SPECS(curve, 1); if (k == NULL || klen == 0 || key == NULL) { ret = BAD_FUNC_ARG; } + if (ret == 0) { + ALLOC_CURVE_SPECS(1); + ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER); + } + if (ret == 0) { if (key->sign_k == NULL) { key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, @@ -5546,7 +5547,11 @@ int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key) if (ret == 0) { ret = mp_read_unsigned_bin(key->sign_k, k, klen); } + if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) { + ret = MP_VAL; + } + FREE_CURVE_SPECS(); return ret; } #endif /* WOLFSSL_ECDSA_SET_K */ @@ -6034,7 +6039,8 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, } #endif /* ECC_SHAMIR */ -#endif /* !WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCEL*/ +#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && + * !WOLFSSL_CRYPTOCEL */ #ifdef HAVE_ECC_VERIFY @@ -6348,8 +6354,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } #endif -#if (defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_HAVE_SP_ECC)) && \ - !defined(FREESCALE_LTC_ECC) +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_HAVE_SP_ECC) || \ + (defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_HAVE_SP_ECC)) && \ + !defined(FREESCALE_LTC_ECC) if (key->idx != ECC_CUSTOM_IDX #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC @@ -6411,7 +6418,6 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #endif #if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) - ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V) @@ -6737,81 +6743,87 @@ int wc_ecc_import_point_der_ex(byte* in, word32 inLen, const int curve_idx, #ifdef HAVE_COMP_KEY if (err == MP_OKAY && compressed == 1) { /* build y */ -#ifndef WOLFSSL_SP_MATH - int did_init = 0; - mp_int t1, t2; - DECLARE_CURVE_SPECS(curve, 3); - - ALLOC_CURVE_SPECS(3); - - if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) - err = MEMORY_E; - else - did_init = 1; - - /* load curve info */ - if (err == MP_OKAY) - err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve, - (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | - ECC_CURVE_FIELD_BF)); - - /* compute x^3 */ - if (err == MP_OKAY) - err = mp_sqr(point->x, &t1); - if (err == MP_OKAY) - err = mp_mulmod(&t1, point->x, curve->prime, &t1); - - /* compute x^3 + a*x */ - if (err == MP_OKAY) - err = mp_mulmod(curve->Af, point->x, curve->prime, &t2); - if (err == MP_OKAY) - err = mp_add(&t1, &t2, &t1); - - /* compute x^3 + a*x + b */ - if (err == MP_OKAY) - err = mp_add(&t1, curve->Bf, &t1); - - /* compute sqrt(x^3 + a*x + b) */ - if (err == MP_OKAY) - err = mp_sqrtmod_prime(&t1, curve->prime, &t2); - - /* adjust y */ - if (err == MP_OKAY) { - if ((mp_isodd(&t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) || - (mp_isodd(&t2) == MP_NO && pointType == ECC_POINT_COMP_EVEN)) { - err = mp_mod(&t2, curve->prime, point->y); - } - else { - err = mp_submod(curve->prime, &t2, curve->prime, point->y); - } - } - - if (did_init) { - mp_clear(&t2); - mp_clear(&t1); - } - - wc_ecc_curve_free(curve); - FREE_CURVE_SPECS(); -#else - #ifndef WOLFSSL_SP_NO_256 + #if defined(WOLFSSL_HAVE_SP_ECC) + #ifndef WOLFSSL_SP_NO_256 if (curve_idx != ECC_CUSTOM_IDX && ecc_sets[curve_idx].id == ECC_SECP256R1) { sp_ecc_uncompress_256(point->x, pointType, point->y); } else - #endif - #ifdef WOLFSSL_SP_384 + #endif + #ifdef WOLFSSL_SP_384 if (curve_idx != ECC_CUSTOM_IDX && ecc_sets[curve_idx].id == ECC_SECP384R1) { sp_ecc_uncompress_384(point->x, pointType, point->y); } else + #endif #endif + #if !defined(WOLFSSL_SP_MATH) + { + int did_init = 0; + mp_int t1, t2; + DECLARE_CURVE_SPECS(curve, 3); + + ALLOC_CURVE_SPECS(3); + + if (mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL) != MP_OKAY) + err = MEMORY_E; + else + did_init = 1; + + /* load curve info */ + if (err == MP_OKAY) + err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve, + (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | + ECC_CURVE_FIELD_BF)); + + /* compute x^3 */ + if (err == MP_OKAY) + err = mp_sqr(point->x, &t1); + if (err == MP_OKAY) + err = mp_mulmod(&t1, point->x, curve->prime, &t1); + + /* compute x^3 + a*x */ + if (err == MP_OKAY) + err = mp_mulmod(curve->Af, point->x, curve->prime, &t2); + if (err == MP_OKAY) + err = mp_add(&t1, &t2, &t1); + + /* compute x^3 + a*x + b */ + if (err == MP_OKAY) + err = mp_add(&t1, curve->Bf, &t1); + + /* compute sqrt(x^3 + a*x + b) */ + if (err == MP_OKAY) + err = mp_sqrtmod_prime(&t1, curve->prime, &t2); + + /* adjust y */ + if (err == MP_OKAY) { + if ((mp_isodd(&t2) == MP_YES && + pointType == ECC_POINT_COMP_ODD) || + (mp_isodd(&t2) == MP_NO && + pointType == ECC_POINT_COMP_EVEN)) { + err = mp_mod(&t2, curve->prime, point->y); + } + else { + err = mp_submod(curve->prime, &t2, curve->prime, point->y); + } + } + + if (did_init) { + mp_clear(&t2); + mp_clear(&t1); + } + + wc_ecc_curve_free(curve); + FREE_CURVE_SPECS(); + } + #else { err = WC_KEY_SIZE_E; } -#endif + #endif } #endif @@ -7089,7 +7101,7 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, /* is ecc point on curve described by dp ? */ int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) int err; #ifdef WOLFSSL_SMALL_STACK mp_int* t1; @@ -7131,7 +7143,7 @@ int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) /* compute y^2 - x^3 */ if (err == MP_OKAY) - err = mp_sub(t1, t2, t1); + err = mp_submod(t1, t2, prime, t1); /* Determine if curve "a" should be used in calc */ #ifdef WOLFSSL_CUSTOM_CURVES @@ -7361,7 +7373,7 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, else #endif #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap); if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf)) err = ECC_INF_E; @@ -7413,7 +7425,7 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) int wc_ecc_check_key(ecc_key* key) { int err; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) mp_int* b = NULL; @@ -7508,8 +7520,8 @@ int wc_ecc_check_key(ecc_key* key) /* SP 800-56Ar3, section 5.6.2.1.2 */ /* private keys must be in the range [1, n-1] */ if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) && - (mp_iszero(&key->k) || (key->k.sign == MP_NEG) || - (mp_cmp(&key->k, curve->order) != MP_LT))) { + (mp_iszero(&key->k) || mp_isneg(&key->k) || + (mp_cmp(&key->k, curve->order) != MP_LT))) { err = ECC_PRIV_KEY_E; } @@ -7644,7 +7656,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, #ifdef HAVE_COMP_KEY if (err == MP_OKAY && compressed == 1) { /* build y */ -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) mp_int t1, t2; int did_init = 0; @@ -8392,7 +8404,7 @@ int wc_ecc_sig_size(ecc_key* key) #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) /** Our FP cache */ typedef struct { @@ -9037,7 +9049,7 @@ static int add_entry(int idx, ecc_point *g) } #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) /* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart * * The algorithm builds patterns in increasing bit order by first making all @@ -9333,7 +9345,7 @@ done: #endif #ifdef ECC_SHAMIR -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) /* perform a fixed point ECC mulmod */ static int accel_fp_mul2add(int idx1, int idx2, mp_int* kA, mp_int* kB, @@ -9713,7 +9725,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, int map, void* heap) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) int idx, err = MP_OKAY; mp_digit mp; mp_int mu; @@ -9822,7 +9834,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) int idx, err = MP_OKAY; mp_digit mp; mp_int mu; @@ -9927,7 +9939,7 @@ int wc_ecc_mulmod_ex2(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, #endif } -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) /* helper function for freeing the cache ... must be called with the cache mutex locked */ static void wc_ecc_fp_free_cache(void) @@ -9968,7 +9980,7 @@ void wc_ecc_fp_init(void) /** Free the Fixed Point cache */ void wc_ecc_fp_free(void) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifndef HAVE_THREAD_LS if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */ wc_InitMutex(&ecc_fp_lock); diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 640c2ddab..95c894353 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4700,21 +4700,21 @@ static int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) } #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) #ifndef WOLFSSL_SP_NO_2048 - if (mp_count_bits(a) == 1024) + if (mp_count_bits(a) == 1024 && mp_isodd(a)) err = sp_ModExp_1024(b, &r, a, &y); - else if (mp_count_bits(a) == 2048) + else if (mp_count_bits(a) == 2048 && mp_isodd(a)) err = sp_ModExp_2048(b, &r, a, &y); else #endif #ifndef WOLFSSL_SP_NO_3072 - if (mp_count_bits(a) == 1536) + if (mp_count_bits(a) == 1536 && mp_isodd(a)) err = sp_ModExp_1536(b, &r, a, &y); - else if (mp_count_bits(a) == 3072) + else if (mp_count_bits(a) == 3072 && mp_isodd(a)) err = sp_ModExp_3072(b, &r, a, &y); else #endif #ifdef WOLFSSL_SP_4096 - if (mp_count_bits(a) == 4096) + if (mp_count_bits(a) == 4096 && mp_isodd(a)) err = sp_ModExp_4096(b, &r, a, &y); else #endif @@ -5254,7 +5254,12 @@ int mp_radix_size (mp_int *a, int radix, int *size) } if (mp_iszero(a) == MP_YES) { - *size = 2; +#ifndef WC_DISABLE_RADIX_ZERO_PAD + if (radix == 16) + *size = 3; + else +#endif + *size = 2; return MP_OKAY; } @@ -5311,6 +5316,11 @@ int mp_toradix (mp_int *a, char *str, int radix) /* quick out if its zero */ if (mp_iszero(a) == MP_YES) { +#ifndef WC_DISABLE_RADIX_ZERO_PAD + if (radix == 16) { + *str++ = '0'; + } +#endif *str++ = '0'; *str = '\0'; return MP_OKAY; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 742853c6c..64289a940 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -651,19 +651,25 @@ int wc_CheckRsaKey(RsaKey* key) break; #endif /* WOLFSSL_SP_4096 */ default: - /* If using only single prcsision math then issue key size error, - otherwise fall-back to multi-precision math calculation */ - #ifdef WOLFSSL_SP_MATH + /* If using only single precsision math then issue key size + * error, otherwise fall-back to multi-precision math + * calculation */ + #if defined(WOLFSSL_SP_MATH) ret = WC_KEY_SIZE_E; + #else + if (mp_exptmod_nct(k, &key->e, &key->n, tmp) != MP_OKAY) + ret = MP_EXPTMOD_E; + if (ret == 0) { + if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY) + ret = MP_EXPTMOD_E; + } #endif break; } } -#endif /* WOLFSSL_HAVE_SP_RSA */ - -#ifndef WOLFSSL_SP_MATH +#else if (ret == 0) { - if (mp_exptmod(k, &key->e, &key->n, tmp) != MP_OKAY) + if (mp_exptmod_nct(k, &key->e, &key->n, tmp) != MP_OKAY) ret = MP_EXPTMOD_E; } @@ -671,7 +677,7 @@ int wc_CheckRsaKey(RsaKey* key) if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY) ret = MP_EXPTMOD_E; } -#endif /* !WOLFSSL_SP_MATH */ +#endif /* WOLFSSL_HAVE_SP_RSA */ if (ret == 0) { if (mp_cmp(k, tmp) != MP_EQ) @@ -2076,7 +2082,7 @@ done: static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, word32* outLen, int type, RsaKey* key, WC_RNG* rng) { -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_SMALL_STACK mp_int* tmp; #ifdef WC_RSA_BLINDING @@ -2183,7 +2189,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, #endif #endif /* WOLFSSL_HAVE_SP_RSA */ -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) (void)rng; WOLFSSL_MSG("SP Key Size Error"); return WC_KEY_SIZE_E; @@ -2237,8 +2243,15 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, ret = MP_INVMOD_E; /* rnd = rnd^e */ + #ifndef WOLFSSL_SP_MATH_ALL if (ret == 0 && mp_exptmod(rnd, &key->e, &key->n, rnd) != MP_OKAY) ret = MP_EXPTMOD_E; + #else + if (ret == 0 && mp_exptmod_nct(rnd, &key->e, &key->n, + rnd) != MP_OKAY) { + ret = MP_EXPTMOD_E; + } + #endif /* tmp = tmp*rnd mod n */ if (ret == 0 && mp_mulmod(tmp, rnd, &key->n, tmp) != MP_OKAY) @@ -2292,8 +2305,14 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, ret = MP_EXPTMOD_E; /* tmp = (tmpa - tmpb) * qInv (mod p) */ +#if defined(WOLFSSL_SP_MATH) || (defined(WOLFSSL_SP_MATH_ALL) && \ + !defined(WOLFSSL_SP_INT_NEGATIVE)) + if (ret == 0 && mp_submod(tmpa, tmpb, &key->p, tmp) != MP_OKAY) + ret = MP_SUB_E; +#else if (ret == 0 && mp_sub(tmpa, tmpb, tmp) != MP_OKAY) ret = MP_SUB_E; +#endif if (ret == 0 && mp_mulmod(tmp, &key->u, &key->p, tmp) != MP_OKAY) @@ -3751,8 +3770,11 @@ static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size) if (ret == 0) ret = mp_sub(p, q, &d); +#if !defined(WOLFSSL_SP_MATH) && (!defined(WOLFSSL_SP_MATH_ALL) || \ + defined(WOLFSSL_SP_INT_NEGATIVE)) if (ret == 0) ret = mp_abs(&d, &d); +#endif /* compare */ if (ret == 0) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 081917461..7009d65a8 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -213,7 +213,8 @@ static int InitSha256(wc_Sha256* sha256) /* Hardware Acceleration */ -#if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) +#if defined(USE_INTEL_SPEEDUP) && (defined(HAVE_INTEL_AVX1) || \ + defined(HAVE_INTEL_AVX2)) /* in case intel instructions aren't available, plus we need the K[] global */ #define NEED_SOFT_SHA256 @@ -981,7 +982,8 @@ static int InitSha256(wc_Sha256* sha256) if (sha256->buffLen == WC_SHA256_BLOCK_SIZE) { #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags)) #endif { @@ -1013,7 +1015,8 @@ static int InitSha256(wc_Sha256* sha256) /* process blocks */ #ifdef XTRANSFORM_LEN - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) if (Transform_Sha256_Len_p != NULL) #endif { @@ -1028,11 +1031,13 @@ static int InitSha256(wc_Sha256* sha256) len -= blocksLen; } } - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) else #endif #endif /* XTRANSFORM_LEN */ - #if !defined(XTRANSFORM_LEN) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if !defined(XTRANSFORM_LEN) || (defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) { while (len >= WC_SHA256_BLOCK_SIZE) { word32* local32 = sha256->buffer; @@ -1040,7 +1045,8 @@ static int InitSha256(wc_Sha256* sha256) /* Intel transform function requires use of sha256->buffer */ /* Little Endian requires byte swap, so can't use data directly */ #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER) && \ - !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2) + !(defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) if (((size_t)data % WC_HASH_DATA_ALIGNMENT) == 0) { local32 = (word32*)data; } @@ -1054,7 +1060,8 @@ static int InitSha256(wc_Sha256* sha256) len -= WC_SHA256_BLOCK_SIZE; #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags)) #endif { @@ -1141,7 +1148,8 @@ static int InitSha256(wc_Sha256* sha256) sha256->buffLen += WC_SHA256_BLOCK_SIZE - sha256->buffLen; #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags)) #endif { @@ -1178,7 +1186,8 @@ static int InitSha256(wc_Sha256* sha256) /* store lengths */ #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags)) #endif { @@ -1191,10 +1200,11 @@ static int InitSha256(wc_Sha256* sha256) XMEMCPY(&local[WC_SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen, sizeof(word32)); - #if defined(FREESCALE_MMCAU_SHA) || defined(HAVE_INTEL_AVX1) || \ - defined(HAVE_INTEL_AVX2) + #if defined(FREESCALE_MMCAU_SHA) || (defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) /* Kinetis requires only these bytes reversed */ - #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags)) #endif { @@ -1374,7 +1384,8 @@ static int InitSha256(wc_Sha256* sha256) sha224->loLen = 0; sha224->hiLen = 0; - #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2) + #if defined(USE_INTEL_SPEEDUP) && \ + (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) /* choose best Transform function under this runtime environment */ Sha256_SetTransform(); #endif diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index cc677a481..11c79fa3c 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -45,33 +45,1942 @@ This library provides single precision (SP) integer math functions. * WOLFSSL_HAVE_SP_ECC: Enable SP ECC support * WOLFSSL_SP_MATH: Use only single precision math and algorithms * it supports (no fastmath tfm.c or normal integer.c) + * WOLFSSL_SP_MATH_ALL Implementation of all MP functions + * (replacement for tfm.c and integer.c) * WOLFSSL_SP_SMALL: Use smaller version of code and avoid large * stack variables * WOLFSSL_SP_NO_MALLOC: Always use stack, no heap XMALLOC/XFREE allowed * WOLFSSL_SP_NO_2048: Disable RSA/DH 2048-bit support * WOLFSSL_SP_NO_3072: Disable RSA/DH 3072-bit support * WOLFSSL_SP_4096: Enable RSA/RH 4096-bit support - * WOLFSSL_SP_384 Enable ECC 384-bit SECP384R1 support * WOLFSSL_SP_NO_256 Disable ECC 256-bit SECP256R1 support + * WOLFSSL_SP_384 Enable ECC 384-bit SECP384R1 support * WOLFSSL_SP_ASM Enable assembly speedups (detect platform) - * WOLFSSL_SP_X86_64_ASM Enable Intel x86 assembly speedups like AVX/AVX2 - * WOLFSSL_SP_ARM32_ASM Enable Aarch32 assembly speedups - * WOLFSSL_SP_ARM64_ASM Enable Aarch64 assembly speedups - * WOLFSSL_SP_ARM_CORTEX_M_ASM Enable Cortex-M assembly speedups - * WOLFSSL_SP_ARM_THUMB_ASM Enable ARM Thumb assembly speedups + * WOLFSSL_SP_X86_64_ASM Enable Intel x64 assembly implementation + * WOLFSSL_SP_ARM32_ASM Enable Aarch32 assembly implementation + * WOLFSSL_SP_ARM64_ASM Enable Aarch64 assembly implementation + * WOLFSSL_SP_ARM_CORTEX_M_ASM Enable Cortex-M assembly implementation + * WOLFSSL_SP_ARM_THUMB_ASM Enable ARM Thumb assembly implementation * (used with -mthumb) + * WOLFSSL_SP_X86_64 Enable Intel x86 64-bit assembly speedups + * WOLFSSL_SP_X86 Enable Intel x86 assembly speedups + * WOLFSSL_SP_PPC64 Enable PPC64 assembly speedups + * WOLFSSL_SP_PPC Enable PPC assembly speedups + * WOLFSSL_SP_MIPS64 Enable MIPS64 assembly speedups + * WOLFSSL_SP_MIPS Enable MIPS assembly speedups + * WOLFSSL_SP_RISCV64 Enable RISCV64 assmebly speedups + * WOLFSSL_SP_RISCV32 Enable RISCV32 assmebly speedups + * WOLFSSL_SP_S390X Enable S390X assembly speedups * SP_WORD_SIZE Force 32 or 64 bit mode * WOLFSSL_SP_NONBLOCK Enables "non blocking" mode for SP math, which * will return FP_WOULDBLOCK for long operations and function must be * called again until complete. */ -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #include +#ifndef WOLFSSL_NO_ASM + #if defined(WOLFSSL_SP_X86_64) && SP_WORD_SIZE == 64 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "movq %[b], %%rax \n\t" \ + "mulq %[a] \n\t" \ + "movq %%rax, %[l] \n\t" \ + "movq %%rdx, %[h] \n\t" \ + : [h] "=r" (vh) \ + : [a] "m" (va), [b] "m" (vb), [l] "m" (vl) \ + : "memory", "%rax", "%rdx", "cc" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movq %[b], %%rax \n\t" \ + "mulq %[a] \n\t" \ + "movq $0 , %[o] \n\t" \ + "movq %%rax, %[l] \n\t" \ + "movq %%rdx, %[h] \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "m" (va), [b] "m" (vb) \ + : "%rax", "%rdx", "cc" \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movq %[b], %%rax \n\t" \ + "mulq %[a] \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + "adcq $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "m" (va), [b] "m" (vb) \ + : "%rax", "%rdx", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "movq %[b], %%rax \n\t" \ + "mulq %[a] \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va), [b] "m" (vb) \ + : "%rax", "%rdx", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movq %[b], %%rax \n\t" \ + "mulq %[a] \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + "adcq $0 , %[o] \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + "adcq $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "m" (va), [b] "m" (vb) \ + : "%rax", "%rdx", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movq %[b], %%rax \n\t" \ + "mulq %[a] \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + "adcq $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "m" (va), [b] "m" (vb) \ + : "%rax", "%rdx", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "movq %[a], %%rax \n\t" \ + "mulq %%rax \n\t" \ + "movq %%rax, %[l] \n\t" \ + "movq %%rdx, %[h] \n\t" \ + : [h] "=r" (vh) \ + : [a] "m" (va), [l] "m" (vl) \ + : "memory", "%rax", "%rdx", "cc" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "movq %[a], %%rax \n\t" \ + "mulq %%rax \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + "adcq $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "m" (va) \ + : "%rax", "%rdx", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "movq %[a], %%rax \n\t" \ + "mulq %%rax \n\t" \ + "addq %%rax, %[l] \n\t" \ + "adcq %%rdx, %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va) \ + : "%rax", "%rdx", "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addq %[a], %[l] \n\t" \ + "adcq $0 , %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va) \ + : "cc" \ + ) +/* Add va, variable in a register, into: vh | vl */ +#define SP_ASM_ADDC_REG(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addq %[a], %[l] \n\t" \ + "adcq $0 , %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "subq %[a], %[l] \n\t" \ + "sbbq $0 , %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va) \ + : "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "addq %[a], %[l] \n\t" \ + "adcq %[b], %[h] \n\t" \ + "adcq %[c], %[o] \n\t" \ + "addq %[a], %[l] \n\t" \ + "adcq %[b], %[h] \n\t" \ + "adcq %[c], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "%rax", "%rdx", "cc" \ + ) + +#ifndef WOLFSSL_SP_DIV_WORD_HALF +/* Divide a two digit number by a digit number and return. (hi | lo) / d + * + * Using divq instruction on Intel x64. + * + * @param [in] hi SP integer digit. High digit of the dividend. + * @param [in] lo SP integer digit. Lower digit of the dividend. + * @param [in] d SP integer digit. Number to divide by. + * @reutrn The division result. + */ +static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, + sp_int_digit d) +{ + __asm__ __volatile__ ( + "divq %2" + : "+a" (lo) + : "d" (hi), "r" (d) + : "cc" + ); + return lo; +} +#define SP_ASM_DIV_WORD +#endif + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_X86_64 && SP_WORD_SIZE == 64 */ + + #if defined(WOLFSSL_SP_X86) && SP_WORD_SIZE == 32 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "movl %[b], %%eax \n\t" \ + "mull %[a] \n\t" \ + "movl %%eax, %[l] \n\t" \ + "movl %%edx, %[h] \n\t" \ + : [h] "=r" (vh) \ + : [a] "m" (va), [b] "m" (vb), [l] "m" (vl) \ + : "memory", "eax", "edx", "cc" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movl %[b], %%eax \n\t" \ + "mull %[a] \n\t" \ + "movl $0 , %[o] \n\t" \ + "movl %%eax, %[l] \n\t" \ + "movl %%edx, %[h] \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "m" (va), [b] "m" (vb) \ + : "eax", "edx", "cc" \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movl %[b], %%eax \n\t" \ + "mull %[a] \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + "adcl $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "eax", "edx", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "movl %[b], %%eax \n\t" \ + "mull %[a] \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va), [b] "m" (vb) \ + : "eax", "edx", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movl %[b], %%eax \n\t" \ + "mull %[a] \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + "adcl $0 , %[o] \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + "adcl $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "eax", "edx", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "movl %[b], %%eax \n\t" \ + "mull %[a] \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + "adcl $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "m" (va), [b] "m" (vb) \ + : "eax", "edx", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "movl %[a], %%eax \n\t" \ + "mull %%eax \n\t" \ + "movl %%eax, %[l] \n\t" \ + "movl %%edx, %[h] \n\t" \ + : [h] "=r" (vh) \ + : [a] "m" (va), [l] "m" (vl) \ + : "memory", "eax", "edx", "cc" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "movl %[a], %%eax \n\t" \ + "mull %%eax \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + "adcl $0 , %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "m" (va) \ + : "eax", "edx", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "movl %[a], %%eax \n\t" \ + "mull %%eax \n\t" \ + "addl %%eax, %[l] \n\t" \ + "adcl %%edx, %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va) \ + : "eax", "edx", "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addl %[a], %[l] \n\t" \ + "adcl $0 , %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va) \ + : "cc" \ + ) +/* Add va, variable in a register, into: vh | vl */ +#define SP_ASM_ADDC_REG(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addl %[a], %[l] \n\t" \ + "adcl $0 , %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "subl %[a], %[l] \n\t" \ + "sbbl $0 , %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "m" (va) \ + : "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "addl %[a], %[l] \n\t" \ + "adcl %[b], %[h] \n\t" \ + "adcl %[c], %[o] \n\t" \ + "addl %[a], %[l] \n\t" \ + "adcl %[b], %[h] \n\t" \ + "adcl %[c], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "cc" \ + ) + +#ifndef WOLFSSL_SP_DIV_WORD_HALF +/* Divide a two digit number by a digit number and return. (hi | lo) / d + * + * Using divl instruction on Intel x64. + * + * @param [in] hi SP integer digit. High digit of the dividend. + * @param [in] lo SP integer digit. Lower digit of the dividend. + * @param [in] d SP integer digit. Number to divide by. + * @reutrn The division result. + */ +static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, + sp_int_digit d) +{ + __asm__ __volatile__ ( + "divl %2" + : "+a" (lo) + : "d" (hi), "r" (d) + : "cc" + ); + return lo; +} +#define SP_ASM_DIV_WORD +#endif + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_X86 && SP_WORD_SIZE == 32 */ + + #if defined(WOLFSSL_SP_ARM64) && SP_WORD_SIZE == 64 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mul x10, %[a], %[b] \n\t" \ + "umulh %[h], %[a], %[b] \n\t" \ + "str x10, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "x10", "cc" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[b] \n\t" \ + "umulh %[h], %[a], %[b] \n\t" \ + "mov %[l], x8 \n\t" \ + "mov %[o], xzr \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "x8" \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[b] \n\t" \ + "umulh x9, %[a], %[b] \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adcs %[h], %[h], x9 \n\t" \ + "adc %[o], %[o], xzr \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "x8", "x9", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[b] \n\t" \ + "umulh x9, %[a], %[b] \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adc %[h], %[h], x9 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "x8", "x9", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[b] \n\t" \ + "umulh x9, %[a], %[b] \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adcs %[h], %[h], x9 \n\t" \ + "adc %[o], %[o], xzr \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adcs %[h], %[h], x9 \n\t" \ + "adc %[o], %[o], xzr \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "x8", "x9", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[b] \n\t" \ + "umulh x9, %[a], %[b] \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adc %[h], %[h], x9 \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adcs %[h], %[h], x9 \n\t" \ + "adc %[o], %[o], xzr \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "x8", "x9", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mul x9, %[a], %[a] \n\t" \ + "umulh %[h], %[a], %[a] \n\t" \ + "str x9, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "x9" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[a] \n\t" \ + "umulh x9, %[a], %[a] \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adcs %[h], %[h], x9 \n\t" \ + "adc %[o], %[o], xzr \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "x8", "x9", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mul x8, %[a], %[a] \n\t" \ + "umulh x9, %[a], %[a] \n\t" \ + "adds %[l], %[l], x8 \n\t" \ + "adc %[h], %[h], x9 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "x8", "x9", "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "adds %[l], %[l], %[a] \n\t" \ + "adc %[h], %[h], xzr \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "subs %[l], %[l], %[a] \n\t" \ + "sbc %[h], %[h], xzr \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "adds %[l], %[l], %[a] \n\t" \ + "adcs %[h], %[h], %[b] \n\t" \ + "adc %[o], %[o], %[c] \n\t" \ + "adds %[l], %[l], %[a] \n\t" \ + "adcs %[h], %[h], %[b] \n\t" \ + "adc %[o], %[o], %[c] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "cc" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_ARM64 && SP_WORD_SIZE == 64 */ + + #if (defined(WOLFSSL_SP_ARM32) || defined(WOLFSSL_SP_ARM_CORTEX_M)) && \ + SP_WORD_SIZE == 32 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "umull r8, %[h], %[a], %[b] \n\t" \ + "str r8, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "r8" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "umull %[l], %[h], %[a], %[b] \n\t" \ + "mov %[o], #0 \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "umull r8, r9, %[a], %[b] \n\t" \ + "adds %[l], %[l], r8 \n\t" \ + "adcs %[h], %[h], r9 \n\t" \ + "adc %[o], %[o], #0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r8", "r9", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "umlal %[l], %[h], %[a], %[b] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "umull r8, r9, %[a], %[b] \n\t" \ + "adds %[l], %[l], r8 \n\t" \ + "adcs %[h], %[h], r9 \n\t" \ + "adc %[o], %[o], #0 \n\t" \ + "adds %[l], %[l], r8 \n\t" \ + "adcs %[h], %[h], r9 \n\t" \ + "adc %[o], %[o], #0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r8", "r9", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "umull r8, r9, %[a], %[b] \n\t" \ + "adds %[l], %[l], r8 \n\t" \ + "adc %[h], %[h], r9 \n\t" \ + "adds %[l], %[l], r8 \n\t" \ + "adcs %[h], %[h], r9 \n\t" \ + "adc %[o], %[o], #0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r8", "r9", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "umull r8, %[h], %[a], %[a] \n\t" \ + "str r8, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "r8" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "umull r8, r9, %[a], %[a] \n\t" \ + "adds %[l], %[l], r8 \n\t" \ + "adcs %[h], %[h], r9 \n\t" \ + "adc %[o], %[o], #0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "r8", "r9", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "umlal %[l], %[h], %[a], %[a] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "adds %[l], %[l], %[a] \n\t" \ + "adc %[h], %[h], #0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "subs %[l], %[l], %[a] \n\t" \ + "sbc %[h], %[h], #0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "adds %[l], %[l], %[a] \n\t" \ + "adcs %[h], %[h], %[b] \n\t" \ + "adc %[o], %[o], %[c] \n\t" \ + "adds %[l], %[l], %[a] \n\t" \ + "adcs %[h], %[h], %[b] \n\t" \ + "adc %[o], %[o], %[c] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "cc" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* (WOLFSSL_SP_ARM32 || ARM_CORTEX_M) && SP_WORD_SIZE == 32 */ + + #if defined(WOLFSSL_SP_PPC64) && SP_WORD_SIZE == 64 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[b] \n\t" \ + "mulhdu %[h], %[a], %[b] \n\t" \ + "std 16, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "16" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulhdu %[h], %[a], %[b] \n\t" \ + "mulld %[l], %[a], %[b] \n\t" \ + "li %[o], 0 \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[b] \n\t" \ + "mulhdu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[b] \n\t" \ + "mulhdu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[b] \n\t" \ + "mulhdu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[b] \n\t" \ + "mulhdu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[a] \n\t" \ + "mulhdu %[h], %[a], %[a] \n\t" \ + "std 16, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "16" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[a] \n\t" \ + "mulhdu 17, %[a], %[a] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "16", "17", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mulld 16, %[a], %[a] \n\t" \ + "mulhdu 17, %[a], %[a] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "16", "17", "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addc %[l], %[l], %[a] \n\t" \ + "addze %[h], %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "subfc %[l], %[a], %[l] \n\t" \ + "li 16, 0 \n\t" \ + "subfe %[h], 16, %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "16", "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "addc %[l], %[l], %[a] \n\t" \ + "adde %[h], %[h], %[b] \n\t" \ + "adde %[o], %[o], %[c] \n\t" \ + "addc %[l], %[l], %[a] \n\t" \ + "adde %[h], %[h], %[b] \n\t" \ + "adde %[o], %[o], %[c] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "cc" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_PPC64 && SP_WORD_SIZE == 64 */ + + #if defined(WOLFSSL_SP_PPC) && SP_WORD_SIZE == 32 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[b] \n\t" \ + "mulhwu %[h], %[a], %[b] \n\t" \ + "stw 16, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "16" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulhwu %[h], %[a], %[b] \n\t" \ + "mullw %[l], %[a], %[b] \n\t" \ + "li %[o], 0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[b] \n\t" \ + "mulhwu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[b] \n\t" \ + "mulhwu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[b] \n\t" \ + "mulhwu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[b] \n\t" \ + "mulhwu 17, %[a], %[b] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "16", "17", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[a] \n\t" \ + "mulhwu %[h], %[a], %[a] \n\t" \ + "stw 16, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "16" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[a] \n\t" \ + "mulhwu 17, %[a], %[a] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + "addze %[o], %[o] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "16", "17", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mullw 16, %[a], %[a] \n\t" \ + "mulhwu 17, %[a], %[a] \n\t" \ + "addc %[l], %[l], 16 \n\t" \ + "adde %[h], %[h], 17 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "16", "17", "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addc %[l], %[l], %[a] \n\t" \ + "addze %[h], %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "subfc %[l], %[a], %[l] \n\t" \ + "li 16, 0 \n\t" \ + "subfe %[h], 16, %[h] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "16", "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "addc %[l], %[l], %[a] \n\t" \ + "adde %[h], %[h], %[b] \n\t" \ + "adde %[o], %[o], %[c] \n\t" \ + "addc %[l], %[l], %[a] \n\t" \ + "adde %[h], %[h], %[b] \n\t" \ + "adde %[o], %[o], %[c] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "cc" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_PPC && SP_WORD_SIZE == 64 */ + + #if defined(WOLFSSL_SP_MIPS64) && SP_WORD_SIZE == 64 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[b] \n\t" \ + "mflo %[l] \n\t" \ + "mfhi %[h] \n\t" \ + : [h] "=r" (vh), [l] "=r" (vl) \ + : [a] "r" (va), [b] "r" (vb) \ + : "memory", "$10", "$lo", "$hi" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[b] \n\t" \ + "mflo %[l] \n\t" \ + "mfhi %[h] \n\t" \ + "move %[o], $0 \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[a] \n\t" \ + "mflo $10 \n\t" \ + "mfhi %[h] \n\t" \ + "sd $10, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "$10", "$lo", "$hi" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[a] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "dmultu %[a], %[a] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "daddu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "daddu %[h], %[h], $11 \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "daddu %[l], %[l], %[a] \n\t" \ + "sltu $12, %[l], %[a] \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "$12" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "move $12, %[l] \n\t" \ + "dsubu %[l], $12, %[a] \n\t" \ + "sltu $12, $12, %[l] \n\t" \ + "dsubu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "$12" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "daddu %[l], %[l], %[a] \n\t" \ + "sltu $12, %[l], %[a] \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], %[b] \n\t" \ + "sltu $12, %[h], %[b] \n\t" \ + "daddu %[o], %[o], %[c] \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[l], %[l], %[a] \n\t" \ + "sltu $12, %[l], %[a] \n\t" \ + "daddu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + "daddu %[h], %[h], %[b] \n\t" \ + "sltu $12, %[h], %[b] \n\t" \ + "daddu %[o], %[o], %[c] \n\t" \ + "daddu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "$12" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_MIPS64 && SP_WORD_SIZE == 64 */ + + #if defined(WOLFSSL_SP_MIPS) && SP_WORD_SIZE == 32 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "multu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi %[h] \n\t" \ + "sw $10, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "$10", "$lo", "$hi" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "multu %[a], %[b] \n\t" \ + "mflo %[l] \n\t" \ + "mfhi %[h] \n\t" \ + "move %[o], $0 \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "multu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "multu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "multu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "multu %[a], %[b] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "multu %[a], %[a] \n\t" \ + "mflo $10 \n\t" \ + "mfhi %[h] \n\t" \ + "sw $10, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "$10", "$lo", "$hi" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "multu %[a], %[a] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "sltu $12, %[h], $11 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "multu %[a], %[a] \n\t" \ + "mflo $10 \n\t" \ + "mfhi $11 \n\t" \ + "addu %[l], %[l], $10 \n\t" \ + "sltu $12, %[l], $10 \n\t" \ + "addu %[h], %[h], $11 \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "$10", "$11", "$12", "$lo", "$hi" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "addu %[l], %[l], %[a] \n\t" \ + "sltu $12, %[l], %[a] \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "$12" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "move $12, %[l] \n\t" \ + "subu %[l], $12, %[a] \n\t" \ + "sltu $12, $12, %[l] \n\t" \ + "subu %[h], %[h], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "$12" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "addu %[l], %[l], %[a] \n\t" \ + "sltu $12, %[l], %[a] \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], %[b] \n\t" \ + "sltu $12, %[h], %[b] \n\t" \ + "addu %[o], %[o], %[c] \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[l], %[l], %[a] \n\t" \ + "sltu $12, %[l], %[a] \n\t" \ + "addu %[h], %[h], $12 \n\t" \ + "sltu $12, %[h], $12 \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + "addu %[h], %[h], %[b] \n\t" \ + "sltu $12, %[h], %[b] \n\t" \ + "addu %[o], %[o], %[c] \n\t" \ + "addu %[o], %[o], $12 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "$12" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_MIPS && SP_WORD_SIZE == 32 */ + + #if defined(WOLFSSL_SP_RISCV64) && SP_WORD_SIZE == 64 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu %[h], %[a], %[b] \n\t" \ + "sd a5, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "a5" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulhu %[h], %[a], %[b] \n\t" \ + "mul %[l], %[a], %[b] \n\t" \ + "add %[o], zero, zero \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[a] \n\t" \ + "mulhu %[h], %[a], %[a] \n\t" \ + "sd a5, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "a5" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[a] \n\t" \ + "mulhu a6, %[a], %[a] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "a5", "a6", "a7" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[a] \n\t" \ + "mulhu a6, %[a], %[a] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "a5", "a6", "a7" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "add %[l], %[l], %[a] \n\t" \ + "sltu a7, %[l], %[a] \n\t" \ + "add %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "a7" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "add a7, %[l], zero \n\t" \ + "sub %[l], a7, %[a] \n\t" \ + "sltu a7, a7, %[l] \n\t" \ + "sub %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "a7" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "add %[l], %[l], %[a] \n\t" \ + "sltu a7, %[l], %[a] \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], %[b] \n\t" \ + "sltu a7, %[h], %[b] \n\t" \ + "add %[o], %[o], %[c] \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[l], %[l], %[a] \n\t" \ + "sltu a7, %[l], %[a] \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], %[b] \n\t" \ + "sltu a7, %[h], %[b] \n\t" \ + "add %[o], %[o], %[c] \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "a7" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_RISCV64 && SP_WORD_SIZE == 64 */ + + #if defined(WOLFSSL_SP_RISCV32) && SP_WORD_SIZE == 32 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu %[h], %[a], %[b] \n\t" \ + "sw a5, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "a5" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mulhu %[h], %[a], %[b] \n\t" \ + "mul %[l], %[a], %[b] \n\t" \ + "add %[o], zero, zero \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[b] \n\t" \ + "mulhu a6, %[a], %[b] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "a5", "a6", "a7" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[a] \n\t" \ + "mulhu %[h], %[a], %[a] \n\t" \ + "sw a5, %[l] \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "a5" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[a] \n\t" \ + "mulhu a6, %[a], %[a] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "sltu a7, %[h], a6 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "a5", "a6", "a7" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "mul a5, %[a], %[a] \n\t" \ + "mulhu a6, %[a], %[a] \n\t" \ + "add %[l], %[l], a5 \n\t" \ + "sltu a7, %[l], a5 \n\t" \ + "add %[h], %[h], a6 \n\t" \ + "add %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "a5", "a6", "a7" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "add %[l], %[l], %[a] \n\t" \ + "sltu a7, %[l], %[a] \n\t" \ + "add %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "a7" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "add a7, %[l], zero \n\t" \ + "sub %[l], a7, %[a] \n\t" \ + "sltu a7, a7, %[l] \n\t" \ + "sub %[h], %[h], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "a7" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "add %[l], %[l], %[a] \n\t" \ + "sltu a7, %[l], %[a] \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], %[b] \n\t" \ + "sltu a7, %[h], %[b] \n\t" \ + "add %[o], %[o], %[c] \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[l], %[l], %[a] \n\t" \ + "sltu a7, %[l], %[a] \n\t" \ + "add %[h], %[h], a7 \n\t" \ + "sltu a7, %[h], a7 \n\t" \ + "add %[o], %[o], a7 \n\t" \ + "add %[h], %[h], %[b] \n\t" \ + "sltu a7, %[h], %[b] \n\t" \ + "add %[o], %[o], %[c] \n\t" \ + "add %[o], %[o], a7 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "a7" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_RISCV32 && SP_WORD_SIZE == 32 */ + + #if defined(WOLFSSL_SP_S390X) && SP_WORD_SIZE == 64 + +/* Multiply va by vb and store double size result in: vh | vl */ +#define SP_ASM_MUL(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %[b] \n\t" \ + "stg %%r1, %[l] \n\t" \ + "lgr %[h], %%r0 \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [b] "r" (vb), [l] "m" (vl) \ + : "memory", "r0", "r1" \ + ) +/* Multiply va by vb and store double size result in: vo | vh | vl */ +#define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %[b] \n\t" \ + "lghi %[o], 0 \n\t" \ + "lgr %[l], %%r1 \n\t" \ + "lgr %[h], %%r0 \n\t" \ + : [l] "=r" (vl), [h] "=r" (vh), [o] "=r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r0", "r1" \ + ) +/* Multiply va by vb and add double size result into: vo | vh | vl */ +#define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "lghi %%r10, 0 \n\t" \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %[b] \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + "alcgr %[o], %%r10 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r0", "r1", "r10", "cc" \ + ) +/* Multiply va by vb and add double size result into: vh | vl */ +#define SP_ASM_MUL_ADD_NO(vl, vh, va, vb) \ + __asm__ __volatile__ ( \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %[b] \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r0", "r1", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl */ +#define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "lghi %%r10, 0 \n\t" \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %[b] \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + "alcgr %[o], %%r10 \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + "alcgr %[o], %%r10 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r0", "r1", "r10", "cc" \ + ) +/* Multiply va by vb and add double size result twice into: vo | vh | vl + * Assumes first add will not overflow vh | vl + */ +#define SP_ASM_MUL_ADD2_NO(vl, vh, vo, va, vb) \ + __asm__ __volatile__ ( \ + "lghi %%r10, 0 \n\t" \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %[b] \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + "alcgr %[o], %%r10 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb) \ + : "r0", "r1", "r10", "cc" \ + ) +/* Square va and store double size result in: vh | vl */ +#define SP_ASM_SQR(vl, vh, va) \ + __asm__ __volatile__ ( \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %%r1 \n\t" \ + "stg %%r1, %[l] \n\t" \ + "lgr %[h], %%r0 \n\t" \ + : [h] "=r" (vh) \ + : [a] "r" (va), [l] "m" (vl) \ + : "memory", "r0", "r1" \ + ) +/* Square va and add double size result into: vo | vh | vl */ +#define SP_ASM_SQR_ADD(vl, vh, vo, va) \ + __asm__ __volatile__ ( \ + "lghi %%r10, 0 \n\t" \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %%r1 \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + "alcgr %[o], %%r10 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va) \ + : "r0", "r1", "r10", "cc" \ + ) +/* Square va and add double size result into: vh | vl */ +#define SP_ASM_SQR_ADD_NO(vl, vh, va) \ + __asm__ __volatile__ ( \ + "lgr %%r1, %[a] \n\t" \ + "mlgr %%r0, %%r1 \n\t" \ + "algr %[l], %%r1 \n\t" \ + "alcgr %[h], %%r0 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "r0", "r1", "cc" \ + ) +/* Add va into: vh | vl */ +#define SP_ASM_ADDC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "lghi %%r10, 0 \n\t" \ + "algr %[l], %[a] \n\t" \ + "alcgr %[h], %%r10 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "r10", "cc" \ + ) +/* Sub va from: vh | vl */ +#define SP_ASM_SUBC(vl, vh, va) \ + __asm__ __volatile__ ( \ + "lghi %%r10, 0 \n\t" \ + "slgr %[l], %[a] \n\t" \ + "slbgr %[h], %%r10 \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh) \ + : [a] "r" (va) \ + : "r10", "cc" \ + ) +/* Add two times vc | vb | va into vo | vh | vl */ +#define SP_ASM_ADD_DBL_3(vl, vh, vo, va, vb, vc) \ + __asm__ __volatile__ ( \ + "algr %[l], %[a] \n\t" \ + "alcgr %[h], %[b] \n\t" \ + "alcgr %[o], %[c] \n\t" \ + "algr %[l], %[a] \n\t" \ + "alcgr %[h], %[b] \n\t" \ + "alcgr %[o], %[c] \n\t" \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "r" (va), [b] "r" (vb), [c] "r" (vc) \ + : "cc" \ + ) + +#define SP_INT_ASM_AVAILABLE + + #endif /* WOLFSSL_SP_S390X && SP_WORD_SIZE == 64 */ + +#ifdef SP_INT_ASM_AVAILABLE + #ifndef SP_INT_NO_ASM + #define SQR_MUL_ASM + #endif + #ifndef SP_ASM_ADDC_REG + #define SP_ASM_ADDC_REG SP_ASM_ADDC + #endif /* SP_ASM_ADDC_REG */ +#endif /* SQR_MUL_ASM */ + +#endif /* !WOLFSSL_NO_ASM */ + +#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \ + !defined(NO_DSA) || !defined(NO_DH) || \ + (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA) || \ + defined(WOLFSSL_SP_MATH_ALL) +#ifndef WC_NO_CACHE_RESISTANT + /* Mask of address for constant time operations. */ + const size_t sp_off_on_addr[2] = + { + (size_t) 0, + (size_t)-1 + }; +#endif +#endif + #if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_HAVE_SP_RSA) +/* Modular exponentiation implementations using Single Precision. */ WOLFSSL_LOCAL int sp_ModExp_1024(sp_int* base, sp_int* exp, sp_int* mod, sp_int* res); WOLFSSL_LOCAL int sp_ModExp_1536(sp_int* base, sp_int* exp, sp_int* mod, @@ -85,95 +1994,114 @@ WOLFSSL_LOCAL int sp_ModExp_4096(sp_int* base, sp_int* exp, sp_int* mod, #endif -int sp_get_digit_count(sp_int *a) -{ - int ret; - if (!a) - ret = 0; - else - ret = a->used; - return ret; -} +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp); +#endif -/* Initialize the big number to be zero. +/* Initialize the multi-precision number to be zero. * - * a SP integer. - * returns MP_OKAY always. + * @param [out] a SP integer. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL. */ int sp_init(sp_int* a) { - a->used = 0; - a->size = SP_INT_DIGITS; -#ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&a->raw); -#endif - return MP_OKAY; -} + int err = MP_OKAY; -#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) -/* Initialize up to six big numbers to be zero. - * - * a SP integer. - * b SP integer. - * c SP integer. - * d SP integer. - * e SP integer. - * f SP integer. - * returns MP_OKAY always. - */ -int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, sp_int* e, - sp_int* f) -{ - if (a != NULL) { + if (a == NULL) { + err = MP_VAL; + } + if (err == MP_OKAY) { a->used = 0; a->size = SP_INT_DIGITS; + #ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign = MP_ZPOS; + #endif #ifdef HAVE_WOLF_BIGINT wc_bigint_init(&a->raw); #endif } - if (b != NULL) { - b->used = 0; - b->size = SP_INT_DIGITS; - #ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&b->raw); - #endif + + return err; +} + +int sp_init_size(sp_int* a, int size) +{ + int err = sp_init(a); + + if (err == MP_OKAY) { + a->size = size; } - if (c != NULL) { - c->used = 0; - c->size = SP_INT_DIGITS; - #ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&c->raw); - #endif + + return err; +} + +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || !defined(NO_DH) || defined(HAVE_ECC) +/* Initialize up to six multi-precision numbers to be zero. + * + * @param [out] n1 SP integer. + * @param [out] n2 SP integer. + * @param [out] n3 SP integer. + * @param [out] n4 SP integer. + * @param [out] n5 SP integer. + * @param [out] n6 SP integer. + * + * @return MP_OKAY on success. + */ +int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, + sp_int* n6) +{ + if (n1 != NULL) { + n1->used = 0; + n1->size = SP_INT_DIGITS; +#ifdef WOLFSSL_SP_INT_NEGATIVE + n1->sign = MP_ZPOS; +#endif } - if (d != NULL) { - d->used = 0; - d->size = SP_INT_DIGITS; - #ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&d->raw); - #endif + if (n2 != NULL) { + n2->used = 0; + n2->size = SP_INT_DIGITS; +#ifdef WOLFSSL_SP_INT_NEGATIVE + n2->sign = MP_ZPOS; +#endif } - if (e != NULL) { - e->used = 0; - e->size = SP_INT_DIGITS; - #ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&e->raw); - #endif + if (n3 != NULL) { + n3->used = 0; + n3->size = SP_INT_DIGITS; +#ifdef WOLFSSL_SP_INT_NEGATIVE + n3->sign = MP_ZPOS; +#endif } - if (f != NULL) { - f->used = 0; - f->size = SP_INT_DIGITS; - #ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&f->raw); - #endif + if (n4 != NULL) { + n4->used = 0; + n4->size = SP_INT_DIGITS; +#ifdef WOLFSSL_SP_INT_NEGATIVE + n4->sign = MP_ZPOS; +#endif + } + if (n5 != NULL) { + n5->used = 0; + n5->size = SP_INT_DIGITS; +#ifdef WOLFSSL_SP_INT_NEGATIVE + n5->sign = MP_ZPOS; +#endif + } + if (n6 != NULL) { + n6->used = 0; + n6->size = SP_INT_DIGITS; +#ifdef WOLFSSL_SP_INT_NEGATIVE + n6->sign = MP_ZPOS; +#endif } return MP_OKAY; } -#endif +#endif /* !WOLFSSL_RSA_PUBLIC_ONLY || !NO_DH || HAVE_ECC */ -/* Free the memory from the big number. +/* Free the memory allocated in the multi-precision number. * - * a SP integer. + * @param [in] a SP integer. */ void sp_free(sp_int* a) { @@ -184,167 +2112,288 @@ void sp_free(sp_int* a) } } -/* Clear and Free the data from the big number and set to zero. +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || !defined(NO_DH) || defined(HAVE_ECC) +/* Grow multi-precision number to be able to hold l digits. + * This function does nothing as the number of digits is fixed. * - * a SP integer. + * @param [in,out] a SP integer. + * @param [in] l Number of digits to grow to. + * + * @return MP_OKAY on success + * @return MP_MEM if the number of digits requested is more than available. + */ +int sp_grow(sp_int* a, int l) +{ + int err = MP_OKAY; + + if (a == NULL) { + err = MP_VAL; + } + if ((err == MP_OKAY) && (l > a->size)) { + err = MP_MEM; + } + if (err == MP_OKAY) { + int i; + + for (i = a->used; i < l; i++) { + a->dp[i] = 0; + } + } + + return err; +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY || !NO_DH || HAVE_ECC */ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || defined(WOLFSSL_KEY_GEN) +/* Set the multi-precision number to zero. + * + * Assumes a is not NULL. + * + * @param [out] a SP integer to set to zero. + */ +static void _sp_zero(sp_int* a) +{ + a->dp[0] = 0; + a->used = 0; +#ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign = MP_ZPOS; +#endif +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY || WOLFSSL_KEY_GEN */ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Set the multi-precision number to zero. + * + * @param [out] a SP integer to set to zero. + */ +void sp_zero(sp_int* a) +{ + if (a != NULL) { + _sp_zero(a); + } +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY */ + +/* Clear the data from the multi-precision number and set to zero. + * + * @param [out] a SP integer. */ void sp_clear(sp_int* a) { if (a != NULL) { int i; - for (i=0; iused; i++) + for (i = 0; i < a->used; i++) { a->dp[i] = 0; + } a->used = 0; - - sp_free(a); + #ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign = MP_ZPOS; + #endif } } -/* Calculate the number of 8-bit values required to represent the big number. +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || !defined(NO_DH) || defined(HAVE_ECC) +/* Ensure the data in the multi-precision number is zeroed. * - * a SP integer. - * returns the count. + * Use when security sensitive data needs to be wiped. + * + * @param [in] a SP integer. */ -int sp_unsigned_bin_size(sp_int* a) +void sp_forcezero(sp_int* a) { - int size = sp_count_bits(a); - return (size + 7) / 8; + ForceZero(a->dp, a->used * sizeof(sp_int_digit)); + a->used = 0; +#ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign = MP_ZPOS; +#endif +#ifdef HAVE_WOLF_BIGINT + wc_bigint_zero(&a->raw); +#endif } +#endif /* !WOLFSSL_RSA_VERIFY_ONLY || !NO_DH || HAVE_ECC */ -/* Convert a number as an array of bytes in big-endian format to a big number. +#if defined(WOLSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + defined(SQR_MUL_ASM) +/* Copy value of multi-precision number a into r. * - * a SP integer. - * in Array of bytes. - * inSz Number of data bytes in array. - * returns MP_VAL when the number is too big to fit in an SP and - MP_OKAY otherwise. + * @param [in] a SP integer - source. + * @param [out] r SP integer - destination. + * + * @return MP_OKAY on success. */ -int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz) +int sp_copy(sp_int* a, sp_int* r) { int err = MP_OKAY; - int i, j = 0, k; - /* Extra digit added to SP_INT_DIGITS to be used in calculations. */ - if (inSz > (SP_INT_DIGITS - 1) * (int)sizeof(a->dp[0])) { + if ((a == NULL) || (r == NULL)) { err = MP_VAL; } - else if (inSz == 0) { - XMEMSET(a->dp, 0, a->size * sizeof(*a->dp)); - a->used = 0; - } - else { - for (i = inSz-1; i >= (SP_WORD_SIZE/8); i -= (SP_WORD_SIZE/8), j++) { - a->dp[j] = (((sp_int_digit)in[i-0]) << (0*8)) - | (((sp_int_digit)in[i-1]) << (1*8)) - | (((sp_int_digit)in[i-2]) << (2*8)) - | (((sp_int_digit)in[i-3]) << (3*8)); - #if SP_WORD_SIZE == 64 - a->dp[j] |= (((sp_int_digit)in[i-4]) << (4*8)) - | (((sp_int_digit)in[i-5]) << (5*8)) - | (((sp_int_digit)in[i-6]) << (6*8)) - | (((sp_int_digit)in[i-7]) << (7*8)); - #endif - } - if (i >= 0) { - a->dp[j] = 0; - for (k = 0; k <= i; k++) { - a->dp[j] <<= 8; - a->dp[j] |= in[k]; - } - } - a->used = j + 1; - - sp_clamp(a); - } - - return err; -} - -#ifdef HAVE_ECC -/* Convert a number as string in big-endian format to a big number. - * Only supports base-16 (hexadecimal). - * Negative values not supported. - * - * a SP integer. - * in NUL terminated string. - * radix Number of values in a digit. - * returns BAD_FUNC_ARG when radix not supported or value is negative, MP_VAL - * when a character is not valid and MP_OKAY otherwise. - */ -int sp_read_radix(sp_int* a, const char* in, int radix) -{ - int err = MP_OKAY; - int i, j = 0, k = 0; - char ch; - - if ((radix != 16) || (*in == '-')) { - err = BAD_FUNC_ARG; - } - - while (*in == '0') { - in++; - } - - if (err == MP_OKAY) { - a->dp[0] = 0; - for (i = (int)(XSTRLEN(in) - 1); i >= 0; i--) { - ch = in[i]; - if (ch >= '0' && ch <= '9') - ch -= '0'; - else if (ch >= 'A' && ch <= 'F') - ch -= 'A' - 10; - else if (ch >= 'a' && ch <= 'f') - ch -= 'a' - 10; - else { - err = MP_VAL; - break; - } - - a->dp[k] |= ((sp_int_digit)ch) << j; - j += 4; - if (k >= SP_INT_DIGITS - 1) { - err = MP_VAL; - break; - } - if (j == DIGIT_BIT) - a->dp[++k] = 0; - j &= SP_WORD_SIZE - 1; - } - } - - if (err == MP_OKAY) { - a->used = k + 1; - if (a->dp[k] == 0) - a->used--; - - for (k++; k < a->size; k++) - a->dp[k] = 0; - - sp_clamp(a); + else if (a != r) { + XMEMCPY(r->dp, a->dp, a->used * sizeof(sp_int_digit)); + if (a->used == 0) + r->dp[0] = 0; + r->used = a->used; +#ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = a->sign; +#endif } return err; } #endif -/* Compare two big numbers. +#if defined(WOLSSL_SP_MATH_ALL) || (defined(HAVE_ECC) && defined(FP_ECC)) +/* Initializes r and copies in value from a. * - * a SP integer. - * b SP integer. - * returns MP_GT if a is greater than b, MP_LT if a is less than b and MP_EQ - * when a equals b. + * @param [out] r SP integer - destination. + * @param [in] a SP integer - source. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL. */ -int sp_cmp(sp_int* a, sp_int* b) +int sp_init_copy(sp_int* r, sp_int* a) +{ + int err; + + err = sp_init(r); + if (err == MP_OKAY) { + err = sp_copy(a, r); + } + return err; +} +#endif /* WOLSSL_SP_MATH_ALL || (HAVE_ECC && FP_ECC) */ + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || !defined(NO_DSA) +/* Exchange the values in a and b. + * + * @param [in,out] a SP integer to swap. + * @param [in,out] b SP integer to swap. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or b is NULL. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_exch(sp_int* a, sp_int* b) +{ + int err = MP_OKAY; +#ifndef WOLFSSL_SMALL_STACK + sp_int t[1]; +#else + sp_int* t = NULL; +#endif + + if ((a == NULL) || (b == NULL)) { + err = MP_VAL; + } + +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif + + if (err == MP_OKAY) { + *t = *a; + *a = *b; + *b = *t; + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif + return err; +} +#endif /* defined(WOLFSSL_SP_MATH_ALL) || !NO_DH || !NO_DSA */ + +#if defined(HAVE_ECC) && defined(ECC_TIMING_RESISTANT) && \ + !defined(WC_NO_CACHE_RESISTANT) +int sp_cond_swap_ct(sp_int * a, sp_int * b, int c, int m) +{ + int i; + sp_digit mask = (sp_digit)0 - m; +#ifndef WOLFSSL_SMALL_STACK + sp_int t[1]; +#else + sp_int* t; +#endif + +#ifdef WOLFSSL_SMALL_STACK + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) + return MP_MEM; +#endif + + t->used = (a->used ^ b->used) & mask; + for (i = 0; i < c; i++) { + t->dp[i] = (a->dp[i] ^ b->dp[i]) & mask; + } + a->used ^= t->used; + for (i = 0; i < c; i++) { + a->dp[i] ^= t->dp[i]; + } + b->used ^= t->used; + for (i = 0; i < c; i++) { + b->dp[i] ^= t->dp[i]; + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); +#endif + return MP_OKAY; +} +#endif /* HAVE_ECC && ECC_TIMING_RESISTANT && !WC_NO_CACHE_RESISTANT */ + +#ifdef WOLFSSL_SP_INT_NEGATIVE +/* Calculate the absolute value of the multi-precision number. + * + * @param [in] a SP integer to calculate absolute value of. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL. + */ +int sp_abs(sp_int* a, sp_int* r) +{ + int err; + + err = sp_copy(a, r); + if (r != NULL) { + r->sign = MP_ZPOS; + } + + return err; +} +#endif /* WOLFSSL_SP_INT_NEGATIVE */ + +/* Compare absolute value of two multi-precision numbers. + * + * @param [in] a SP integer. + * @param [in] b SP integer. + * + * @return MP_GT when a is greater than b. + * @return MP_LT when a is less than b. + * @return MP_EQ when a is equals b. + */ +static int _sp_cmp_abs(sp_int* a, sp_int* b) { int ret = MP_EQ; - int i; - if (a->used > b->used) + if (a->used > b->used) { ret = MP_GT; - else if (a->used < b->used) + } + else if (a->used < b->used) { ret = MP_LT; + } else { + int i; + for (i = a->used - 1; i >= 0; i--) { if (a->dp[i] > b->dp[i]) { ret = MP_GT; @@ -356,38 +2405,173 @@ int sp_cmp(sp_int* a, sp_int* b) } } } + return ret; } -/* Count the number of bits in the big number. +#ifdef WOLFSSL_SP_MATH_ALL +/* Compare absolute value of two multi-precision numbers. * - * a SP integer. - * returns the number of bits. + * @param [in] a SP integer. + * @param [in] b SP integer. + * + * @return MP_GT when a is greater than b. + * @return MP_LT when a is less than b. + * @return MP_EQ when a is equals b. + */ +int sp_cmp_mag(sp_int* a, sp_int* b) +{ + int ret; + + if (a == b) { + ret = MP_EQ; + } + else if (a == NULL) { + ret = MP_LT; + } + else if (b == NULL) { + ret = MP_GT; + } + else + { + ret = _sp_cmp_abs(a, b); + } + + return ret; +} +#endif + +/* Compare two multi-precision numbers. + * + * Assumes a and b are not NULL. + * + * @param [in] a SP integer. + * @param [in] a SP integer. + * + * @return MP_GT when a is greater than b. + * @return MP_LT when a is less than b. + * @return MP_EQ when a is equals b. + */ +static int _sp_cmp(sp_int* a, sp_int* b) +{ + int ret; + +#ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == b->sign) { +#endif + ret = _sp_cmp_abs(a, b); +#ifdef WOLFSSL_SP_INT_NEGATIVE + } + else if (a->sign > b->sign) { + ret = MP_LT; + } + else /* (a->sign < b->sign) */ { + ret = MP_GT; + } +#endif + + return ret; +} + + +/* Compare two multi-precision numbers. + * + * Pointers are compared such that NULL is less than not NULL. + * + * @param [in] a SP integer. + * @param [in] a SP integer. + * + * @return MP_GT when a is greater than b. + * @return MP_LT when a is less than b. + * @return MP_EQ when a is equals b. + */ +int sp_cmp(sp_int* a, sp_int* b) +{ + int ret; + + if (a == b) { + ret = MP_EQ; + } + else if (a == NULL) { + ret = MP_LT; + } + else if (b == NULL) { + ret = MP_GT; + } + else + { + ret = _sp_cmp(a, b); + } + + return ret; +} + +/************************* + * Bit check/set functions + *************************/ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Check if a bit is set + * + * When a is NULL, result is 0. + * + * @param [in] a SP integer. + * @param [in] b Bit position to check. + * + * @return 0 when bit is not set. + * @return 1 when bit is set. + */ +int sp_is_bit_set(sp_int* a, unsigned int b) +{ + int ret = 0; + int i = (int)(b >> SP_WORD_SHIFT); + int s = (int)(b & SP_WORD_MASK); + + if ((a != NULL) && (i < a->used)) { + ret = (int)((a->dp[i] >> s) & (sp_int_digit)1); + } + + return ret; +} +#endif /* WOLFSSL_RSA_VERIFY_ONLY */ + +/* Count the number of bits in the multi-precision number. + * + * When a is not NULL, result is 0. + * + * @param [in] a SP integer. + * + * @return The number of bits in the number. */ int sp_count_bits(sp_int* a) { int r = 0; - sp_int_digit d; - r = a->used - 1; - while (r >= 0 && a->dp[r] == 0) - r--; - if (r < 0) - r = 0; - else { - d = a->dp[r]; - r *= SP_WORD_SIZE; - if (d >= (1L << (SP_WORD_SIZE / 2))) { - r += SP_WORD_SIZE; - while ((d & (1UL << (SP_WORD_SIZE - 1))) == 0) { - r--; - d <<= 1; - } + if (a != NULL) { + r = a->used - 1; + while ((r >= 0) && (a->dp[r] == 0)) { + r--; + } + if (r < 0) { + r = 0; } else { - while (d != 0) { - r++; - d >>= 1; + sp_int_digit d; + + d = a->dp[r]; + r *= SP_WORD_SIZE; + if (d > SP_HALF_MAX) { + r += SP_WORD_SIZE; + while ((d & (1UL << (SP_WORD_SIZE - 1))) == 0) { + r--; + d <<= 1; + } + } + else { + while (d != 0) { + r++; + d >>= 1; + } } } } @@ -395,412 +2579,571 @@ int sp_count_bits(sp_int* a) return r; } -/* Determine if the most significant byte of the encoded big number as the top - * bit set. +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && defined(FP_ECC)) + +/* Number of entries in array of number of least significant zero bits. */ +#define SP_LNZ_CNT 16 +/* Number of bits the array checks. */ +#define SP_LNZ_BITS 4 +/* Mask to apply to check with array. */ +#define SP_LNZ_MASK 0xf +/* Number of least significant zero bits in first SP_LNZ_CNT numbers. */ +static const int lnz[SP_LNZ_CNT] = { + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* Count the number of least significant zero bits. * - * a SP integer. - * returns 1 when the top bit is set and 0 otherwise. + * When a is not NULL, result is 0. + * + * @param [in] a SP integer to use. + * + * @return Number of leas significant zero bits. + */ +#if !defined(HAVE_ECC) || !defined(HAVE_COMP_KEY) +static +#endif /* !HAVE_ECC || HAVE_COMP_KEY */ +int sp_cnt_lsb(sp_int* a) +{ + int bc = 0; + + if ((a != NULL) && (!sp_iszero(a))) { + int i; + int j; + int cnt = 0; + + for (i = 0; i < a->used && a->dp[i] == 0; i++, cnt += SP_WORD_SIZE) { + } + + for (j = 0; j < SP_WORD_SIZE; j += SP_LNZ_BITS) { + bc = lnz[(a->dp[i] >> j) & SP_LNZ_MASK]; + if (bc != 4) { + bc += cnt + j; + break; + } + } + } + + return bc; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || (HAVE_ECC && FP_ECC) */ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Determine if the most significant byte of the encoded multi-precision number + * has the top bit set. + * + * When A is NULL, result is 0. + * + * @param [in] a SP integer. + * + * @return 1 when the top bit of top byte is set. + * @return 0 when the top bit of top byte is not set. */ int sp_leading_bit(sp_int* a) { int bit = 0; - sp_int_digit d; - if (a->used > 0) { - d = a->dp[a->used - 1]; - while (d > (sp_int_digit)0xff) + if ((a != NULL) && (a->used > 0)) { + sp_int_digit d = a->dp[a->used - 1]; + #if SP_WORD_SIZE > 8 + while (d > (sp_int_digit)0xff) { d >>= 8; + } + #endif bit = (int)(d >> 7); } return bit; } +#endif /* !WOLFSSL_RSA_VERIFY_ONLY */ -#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \ - !defined(WOLFSSL_RSA_VERIFY_ONLY) -/* Convert the big number to an array of bytes in big-endian format. - * The array must be large enough for encoded number - use mp_unsigned_bin_size - * to calculate the number of bytes required. +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \ + !defined(NO_RSA) +/* Set a bit of a: a |= 1 << i + * The field 'used' is updated in a. * - * a SP integer. - * out Array to put encoding into. - * returns MP_OKAY always. - */ -int sp_to_unsigned_bin(sp_int* a, byte* out) -{ - int i, j, b; - sp_int_digit d; - - j = sp_unsigned_bin_size(a) - 1; - for (i=0; j>=0; i++) { - d = a->dp[i]; - for (b = 0; b < SP_WORD_SIZE / 8; b++) { - out[j] = d; - if (--j < 0) { - break; - } - d >>= 8; - } - } - - return MP_OKAY; -} -#endif - -/* Convert the big number to an array of bytes in big-endian format. - * The array must be large enough for encoded number - use mp_unsigned_bin_size - * to calculate the number of bytes required. - * Front-pads the output array with zeros make number the size of the array. + * @param [in,out] a SP integer to set bit into. + * @param [in] i Index of bit to set. * - * a SP integer. - * out Array to put encoding into. - * outSz Size of the array. - * returns MP_OKAY always. + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL or index is too large. */ -int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz) -{ - int i, j, b; - - j = outSz - 1; - for (i = 0; j >= 0 && i < a->used; i++) { - for (b = 0; b < SP_WORD_SIZE; b += 8) { - out[j--] = a->dp[i] >> b; - if (j < 0) - break; - } - } - for (; j >= 0; j--) { - out[j] = 0; - } - - return MP_OKAY; -} - -#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) -/* Ensure the data in the big number is zeroed. - * - * a SP integer. - */ -void sp_forcezero(sp_int* a) -{ - ForceZero(a->dp, a->used * sizeof(sp_int_digit)); - a->used = 0; -} -#endif - -#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) -/* Copy value of big number a into r. - * - * a SP integer. - * r SP integer. - * returns MP_OKAY always. - */ -int sp_copy(sp_int* a, sp_int* r) -{ - if (a != r) { - XMEMCPY(r->dp, a->dp, a->used * sizeof(sp_int_digit)); - r->used = a->used; - } - return MP_OKAY; -} - -/* creates "a" then copies b into it */ -int sp_init_copy (sp_int * a, sp_int * b) -{ - int err; - if ((err = sp_init(a)) == MP_OKAY) { - if((err = sp_copy (b, a)) != MP_OKAY) { - sp_clear(a); - } - } - return err; -} -#endif - -/* Set the big number to be the value of the digit. - * - * a SP integer. - * d Digit to be set. - * returns MP_OKAY always. - */ -int sp_set(sp_int* a, sp_int_digit d) -{ - if (d == 0) { - a->dp[0] = d; - a->used = 0; - } - else { - a->dp[0] = d; - a->used = 1; - } - return MP_OKAY; -} - -/* Recalculate the number of digits used. - * - * a SP integer. - */ -void sp_clamp(sp_int* a) -{ - int i; - - for (i = a->used - 1; i >= 0 && a->dp[i] == 0; i--) { - } - a->used = i + 1; -} - -#if defined(WOLFSSL_RSA_VERIFY_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) -/* Grow big number to be able to hold l digits. - * This function does nothing as the number of digits is fixed. - * - * a SP integer. - * l Number of digits. - * returns MP_MEM if the number of digits requested is more than available and - * MP_OKAY otherwise. - */ -int sp_grow(sp_int* a, int l) +int sp_set_bit(sp_int* a, int i) { int err = MP_OKAY; + int w = (int)(i >> SP_WORD_SHIFT); - if (l > a->size) - err = MP_MEM; + if ((a == NULL) || (w >= a->size)) { + err = MP_VAL; + } + else { + int s = (int)(i & (SP_WORD_SIZE - 1)); + int j; + + for (j = a->used; j <= w; j++) { + a->dp[j] = 0; + } + a->dp[w] |= (sp_int_digit)1 << s; + if (a->used <= w) { + a->used = w + 1; + } + } + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || HAVE_ECC || + * WOLFSSL_KEY_GEN || OPENSSL_EXTRA || !NO_RSA */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_KEY_GEN) +/* Exponentiate 2 to the power of e: a = 2^e + * This is done by setting the 'e'th bit. + * + * @param [out] a SP integer to hold result. + * @param [in] e Exponent. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL or 2^exponent is too large. + */ +int sp_2expt(sp_int* a, int e) +{ + int err = 0; + + if (a == NULL) { + err = MP_VAL; + } + else { + _sp_zero(a); + err = sp_set_bit(a, e); + } return err; } -#endif +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_KEY_GEN */ -#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) -/* Sub a one digit number from the big number. +/********************** + * Digit/Long functions + **********************/ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Set the multi-precision number to be the value of the digit. * - * a SP integer. - * d Digit to subtract. - * r SP integer - result. - * returns MP_OKAY always. + * @param [out] a SP integer to become number. + * @param [in] d Digit to be set. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL. */ -int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r) +int sp_set(sp_int* a, sp_int_digit d) { - int i = 0; - sp_int_digit t; + int err = MP_OKAY; - r->used = a->used; - t = a->dp[0] - d; - if (t > a->dp[0]) { - for (++i; i < a->used; i++) { - r->dp[i] = a->dp[i] - 1; - if (r->dp[i] != (sp_int_digit)-1) - break; - } + if (a == NULL) { + err = MP_VAL; } - r->dp[0] = t; - if (r != a) { - for (++i; i < a->used; i++) - r->dp[i] = a->dp[i]; + if (err == MP_OKAY) { + a->dp[0] = d; + a->used = d > 0; + #ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign = MP_ZPOS; + #endif } - sp_clamp(r); - return MP_OKAY; + return err; } -#endif +#endif /* WOLFSSL_RSA_VERIFY_ONLY */ -/* Compare a one digit number with a big number. +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_RSA) +/* Set a number into the multi-precision number. * - * a SP integer. - * d Digit to compare with. - * returns MP_GT if a is greater than d, MP_LT if a is less than d and MP_EQ - * when a equals d. + * Number may be larger than the size of a digit. + * + * @param [out] a SP integer to set. + * @param [in] n Long value to set. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL. */ -int sp_cmp_d(sp_int *a, sp_int_digit d) +int sp_set_int(sp_int* a, unsigned long n) +{ + int err = MP_OKAY; + + if (a == NULL) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + #if SP_WORD_SIZE < SP_ULONG_BITS + if (n <= (sp_int_digit)SP_DIGIT_MAX) { + #endif + a->dp[0] = (sp_int_digit)n; + a->used = (n != 0); + #if SP_WORD_SIZE < SP_ULONG_BITS + } + else { + int i; + + for (i = 0; n > 0; i++,n >>= SP_WORD_SIZE) { + a->dp[i] = (sp_int_digit)n; + } + a->used = i; + } + #endif + #ifdef WOLFSSL_SP_INT_NEGATIVE + a->sign = MP_ZPOS; + #endif + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || !NO_RSA */ + +/* Compare a one digit number with a multi-precision number. + * + * When a is NULL, MP_LT is returned. + * + * @param [in] a SP integer to compare. + * @param [in] d Digit to compare with. + * + * @return MP_GT when a is greater than d. + * @return MP_LT when a is less than d. + * @return MP_EQ when a is equals d. + */ +int sp_cmp_d(sp_int* a, sp_int_digit d) { int ret = MP_EQ; - /* special case for zero*/ - if (a->used == 0) { - if (d == 0) - ret = MP_EQ; - else - ret = MP_LT; + if (a == NULL) { + ret = MP_LT; } - else if (a->used > 1) - ret = MP_GT; - else { - /* compare the only digit of a to d */ - if (a->dp[0] > d) + else +#ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == MP_NEG) { + ret = MP_LT; + } + else +#endif + { + /* special case for zero*/ + if (a->used == 0) { + if (d == 0) { + ret = MP_EQ; + } + else { + ret = MP_LT; + } + } + else if (a->used > 1) { ret = MP_GT; - else if (a->dp[0] < d) - ret = MP_LT; + } + else { + if (a->dp[0] > d) { + ret = MP_GT; + } + else if (a->dp[0] < d) { + ret = MP_LT; + } + } } return ret; } -#if !defined(NO_DH) || defined(HAVE_ECC) || !defined(WOLFSSL_RSA_VERIFY_ONLY) -/* Left shift the number by number of bits. - * Bits may be larger than the word size. +#if defined(WOLFSSL_SP_INT_NEGATIVE) || !defined(NO_PWDBASED) || \ + defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_RSA) || \ + defined(WOLFSSL_SP_MATH_ALL) +/* Add a one digit number to the multi-precision number. * - * a SP integer. - * n Number of bits to shift. - * returns MP_OKAY always. - */ -static int sp_lshb(sp_int* a, int n) -{ - int i; - sp_digit v; - - if (n >= SP_WORD_SIZE) { - sp_lshd(a, n / SP_WORD_SIZE); - n %= SP_WORD_SIZE; - } - - if ((n != 0) && (a->used != 0)) { - v = a->dp[a->used - 1] >> (SP_WORD_SIZE - n); - if (v != 0) { - a->dp[a->used] = v; - } - a->dp[a->used - 1] = a->dp[a->used - 1] << n; - for (i = a->used - 2; i >= 0; i--) { - a->dp[i+1] |= a->dp[i] >> (SP_WORD_SIZE - n); - a->dp[i] = a->dp[i] << n; - } - if (v != 0) { - a->used++; - } - } - - return MP_OKAY; -} - -/* Subtract two large numbers into result: r = a - b - * a must be greater than b. + * @param [in] a SP integer be added to. + * @param [in] d Digit to add. + * @param [out] r SP integer to store result in. * - * a SP integer. - * b SP integer. - * r SP integer. - * returns MP_OKAY always. + * @returnn MP_OKAY on success. + * @returnn MP_VAL when result is too large for fixed size dp array. */ -int sp_sub(sp_int* a, sp_int* b, sp_int* r) +static int _sp_add_d(sp_int* a, sp_int_digit d, sp_int* r) { - int i; - sp_int_digit c = 0; + int err = MP_OKAY; + int i = 0; sp_int_digit t; - for (i = 0; i < a->used && i < b->used; i++) { - t = a->dp[i] - b->dp[i] - c; - if (c == 0) - c = t > a->dp[i]; - else - c = t >= a->dp[i]; - r->dp[i] = t; + r->used = a->used; + if (a->used == 0) { + r->used = d > 0; } - for (; i < a->used; i++) { - r->dp[i] = a->dp[i] - c; - c &= (r->dp[i] == (sp_int_digit)-1); + t = a->dp[0] + d; + if (t < a->dp[0]) { + for (++i; i < a->used; i++) { + r->dp[i] = a->dp[i] + 1; + if (r->dp[i] != 0) { + break; + } + } + if (i == a->used) { + r->used++; + if (i < r->size) + r->dp[i] = 1; + else + err = MP_VAL; + } + } + if (err == MP_OKAY) { + r->dp[0] = t; + if (r != a) { + for (++i; i < a->used; i++) { + r->dp[i] = a->dp[i]; + } + } } - r->used = i; - sp_clamp(r); - return MP_OKAY; + return err; } +#endif /* WOLFSSL_SP_INT_NEGATIVE || !NO_PWDBASED || WOLFSSL_KEY_GEN || + * !NO_DH || !NO_RSA */ -/* Shift a right by n bits into r: r = a >> n +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE) || \ + !defined(NO_DH) || !defined(NO_DSA) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +/* Sub a one digit number from the multi-precision number. * - * a SP integer operand. - * n Number of bits to shift. - * r SP integer result. + * returns MP_OKAY always. + * @param [in] a SP integer be subtracted from. + * @param [in] d Digit to subtract. + * @param [out] r SP integer to store result in. */ -void sp_rshb(sp_int* a, int n, sp_int* r) +static void _sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r) { - int i = n / SP_WORD_SIZE; - int j; + int i = 0; + sp_int_digit t; - if (i >= a->used) { - r->dp[0] = 0; - r->used = 0; + r->used = a->used; + if (a->used == 0) { + r->dp[0] = 0; } else { - n %= SP_WORD_SIZE; - if (n == 0) { - for (j = 0; i < a->used; i++, j++) - r->dp[j] = a->dp[i]; - r->used = j; + t = a->dp[0] - d; + if (t > a->dp[0]) { + for (++i; i < a->used; i++) { + r->dp[i] = a->dp[i] - 1; + if (r->dp[i] != SP_DIGIT_MAX) { + break; + } + } } - if (n > 0) { - for (j = 0; i < a->used-1; i++, j++) - r->dp[j] = (a->dp[i] >> n) | (a->dp[i+1] << (SP_WORD_SIZE - n)); - r->dp[j] = a->dp[i] >> n; - r->used = j + 1; - sp_clamp(r); + r->dp[0] = t; + if (r != a) { + for (++i; i < a->used; i++) { + r->dp[i] = a->dp[i]; + } } + sp_clamp(r); } } +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_SP_INT_NEGATIVE || !NO_DH || !NO_DSA || + * HAVE_ECC || (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ -#if defined(WOLFSSL_SP_SMALL) || (defined(WOLFSSL_KEY_GEN) || \ - !defined(NO_DH) && !defined(WC_NO_RNG)) +#if !defined(NO_PWDBASED) || defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || \ + !defined(NO_DSA) || !defined(NO_RSA) +/* Add a one digit number to the multi-precision number. + * + * @param [in] a SP integer be added to. + * @param [in] d Digit to add. + * @param [out] r SP integer to store result in. + * + * @returnn MP_OKAY on success. + * @returnn MP_VAL when result is too large for fixed size dp array. + */ +int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } + else + { + #ifndef WOLFSSL_SP_INT_NEGATIVE + err = _sp_add_d(a, d, r); + #else + if (a->sign == MP_ZPOS) { + r->sign = MP_ZPOS; + err = _sp_add_d(a, d, r); + } + else if ((a->used > 1) || (a->dp[0] >= d)) { + r->sign = MP_NEG; + _sp_sub_d(a, d, r); + } + else { + r->sign = MP_ZPOS; + r->dp[0] = d - a->dp[0]; + } + #endif + } + + return err; +} +#endif /* !NO_PWDBASED || WOLFSSL_KEY_GEN || !NO_DH || !NO_DSA || !NO_RSA */ + +#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + !defined(NO_DH) || defined(HAVE_ECC) || !defined(NO_DSA) +/* Sub a one digit number from the multi-precision number. + * + * @param [in] a SP integer be subtracted from. + * @param [in] d Digit to subtract. + * @param [out] r SP integer to store result in. + * + * @returnn MP_OKAY on success. + * @returnn MP_VAL when a or r is NULL. + */ +int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } + else { + #ifndef WOLFSSL_SP_INT_NEGATIVE + _sp_sub_d(a, d, r); + #else + if (a->sign == MP_NEG) { + r->sign = MP_NEG; + err = _sp_add_d(a, d, r); + } + else if ((a->used > 1) || (a->dp[0] >= d)) { + r->sign = MP_ZPOS; + _sp_sub_d(a, d, r); + } + else { + r->sign = MP_NEG; + r->dp[0] = d - a->dp[0]; + r->used = r->dp[0] > 0; + } + #endif + } + + return err; +} +#endif /* (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) || !NO_DH || HAVE_ECC || + * !NO_DSA */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_SMALL) || \ + (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)) /* Multiply a by digit n and put result into r shifting up o digits. * r = (a * n) << (o * SP_WORD_SIZE) * - * a SP integer to be multiplied. - * n Number to multiply by. - * r SP integer result. - * o Number of digits to move result up by. + * @param [in] a SP integer to be multiplied. + * @param [in] n Number (SP digit) to multiply by. + * @param [out] r SP integer result. + * @param [in] o Number of digits to move result up by. */ static void _sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r, int o) { int i; sp_int_word t = 0; - for (i = 0; i < o; i++) +#ifdef WOLFSSL_SP_SMALL + for (i = 0; i < o; i++) { r->dp[i] = 0; + } +#else + /* Don't use the offset. Only when doing small code size div. */ + (void)o; +#endif - for (i = 0; i < a->used; i++) { - t += (sp_int_word)n * a->dp[i]; - r->dp[i + o] = (sp_int_digit)t; + for (i = 0; i < a->used; i++, o++) { + t += (sp_int_word)a->dp[i] * n; + r->dp[o] = (sp_int_digit)t; t >>= SP_WORD_SIZE; } - r->dp[i+o] = (sp_int_digit)t; - r->used = i+o+1; + r->dp[o++] = (sp_int_digit)t; + r->used = o; sp_clamp(r); } -#endif +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_SP_SMALL || + * (WOLFSSL_KEY_GEN && !NO_RSA) */ +#if defined(WOLFSSL_SP_MATH_ALL) || (defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA)) +/* Multiply a by digit n and put result into r. r = a * n + * + * @param [in] a SP integer to multiply. + * @param [in] n Digit to multiply by. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or b is NULL, or a has maximum number of digits used. + */ +int sp_mul_d(sp_int* a, sp_int_digit d, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } + if ((err == MP_OKAY) && (a->used + 1 > r->size)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + _sp_mul_d(a, d, r, 0); + #ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = a->sign; + #endif + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || (WOLFSSL_KEY_GEN && !NO_RSA) */ + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +#ifndef SP_ASM_DIV_WORD /* Divide a two digit number by a digit number and return. (hi | lo) / d * - * hi SP integer digit. High digit. - * lo SP integer digit. Lower digit. - * d SP integer digit. Number to divide by. - * returns the division result. + * @param [in] hi SP integer digit. High digit of the dividend. + * @param [in] lo SP integer digit. Lower digit of the dividend. + * @param [in] d SP integer digit. Number to divide by. + * @reutrn The division result. */ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, sp_int_digit d) { #ifdef WOLFSSL_SP_DIV_WORD_HALF - sp_int_digit div = d >> SP_HALF_SIZE; sp_int_digit r; - sp_int_digit r2; - sp_int_word w = ((sp_int_word)hi << SP_WORD_SIZE) | lo; - sp_int_word trial; - r = hi / div; - if (r > SP_HALF_MAX) { - r = SP_HALF_MAX; + if (hi != 0) { + sp_int_digit div = d >> SP_HALF_SIZE; + sp_int_digit r2; + sp_int_word w = ((sp_int_word)hi << SP_WORD_SIZE) | lo; + sp_int_word trial; + + r = hi / div; + if (r > SP_HALF_MAX) { + r = SP_HALF_MAX; + } + r <<= SP_HALF_SIZE; + trial = r * (sp_int_word)d; + while (trial > w) { + r -= (sp_int_digit)1 << SP_HALF_SIZE; + trial -= (sp_int_word)d << SP_HALF_SIZE; + } + w -= trial; + r2 = ((sp_int_digit)(w >> SP_HALF_SIZE)) / div; + trial = r2 * (sp_int_word)d; + while (trial > w) { + r2--; + trial -= d; + } + w -= trial; + r += r2; + r2 = ((sp_int_digit)w) / d; + r += r2; } - r <<= SP_HALF_SIZE; - trial = r * (sp_int_word)d; - while (trial > w) { - r -= (sp_int_digit)1 << SP_HALF_SIZE; - trial -= (sp_int_word)d << SP_HALF_SIZE; + else { + r = lo / d; } - w -= trial; - r2 = ((sp_int_digit)(w >> SP_HALF_SIZE)) / div; - trial = r2 * (sp_int_word)d; - while (trial > w) { - r2--; - trial -= d; - } - w -= trial; - r += r2; - r2 = ((sp_int_digit)w) / d; - r += r2; return r; #else @@ -812,21 +3155,1116 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, r = (sp_int_digit)w; return r; -#endif +#endif /* WOLFSSL_SP_DIV_WORD_HALF */ +} +#endif /* !SP_ASM_DIV_WORD */ +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +#if !defined(WOLFSSL_SP_SMALL) && (defined(WOLFSSL_SP_MATH_ALL) || \ + defined(WOLFSSL_HAVE_SP_DH) || (defined(HAVE_ECC) && (defined(FP_ECC) || \ + defined(HAVE_COMP_KEY)))) +/* Divide by 3: r = a / 3 and rem = a % 3 + * + * @param [in] a SP integer to be divided. + * @param [out] r SP integer that is the quotient. May be NULL. + * @param [out] rem SP integer that is the remainder. May be NULL. + */ +static void _sp_div_3(sp_int* a, sp_int* r, sp_int_digit* rem) +{ + int i; + sp_int_word t; + sp_int_digit tr = 0; + sp_int_digit tt; + static const char r6[6] = { 0, 0, 0, 1, 1, 1 }; + static const char rem6[6] = { 0, 1, 2, 0, 1, 2 }; + + if (r == NULL) { + for (i = a->used - 1; i >= 0; i--) { + t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i]; + #if SP_WORD_SIZE == 64 + tt = (t * 0x5555555555555555L) >> 64; + #elif SP_WORD_SIZE == 32 + tt = (t * 0x55555555) >> 32; + #elif SP_WORD_SIZE == 16 + tt = (t * 0x5555) >> 16; + #elif SP_WORD_SIZE == 8 + tt = (t * 0x55) >> 8; + #endif + tr = (sp_int_digit)(t - (sp_int_word)tt * 3); + tr = rem6[tr]; + } + *rem = tr; + } + else { + for (i = a->used - 1; i >= 0; i--) { + t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i]; + #if SP_WORD_SIZE == 64 + tt = (t * 0x5555555555555555L) >> 64; + #elif SP_WORD_SIZE == 32 + tt = (t * 0x55555555) >> 32; + #elif SP_WORD_SIZE == 16 + tt = (t * 0x5555) >> 16; + #elif SP_WORD_SIZE == 8 + tt = (t * 0x55) >> 8; + #endif + tr = (sp_int_digit)(t - (sp_int_word)tt * 3); + tt += r6[tr]; + tr = rem6[tr]; + r->dp[i] = tt; + } + r->used = a->used; + sp_clamp(r); + if (rem != NULL) { + *rem = tr; + } + } } +/* Divide by 10: r = a / 10 and rem = a % 10 + * + * @param [in] a SP integer to be divided. + * @param [out] r SP integer that is the quotient. May be NULL. + * @param [out] rem SP integer that is the remainder. May be NULL. + */ +static void _sp_div_10(sp_int* a, sp_int* r, sp_int_digit* rem) +{ + int i; + sp_int_word t; + sp_int_digit tr = 0; + sp_int_digit tt; + if (r == NULL) { + for (i = a->used - 1; i >= 0; i--) { + t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i]; + #if SP_WORD_SIZE == 64 + tt = (t * 0x1999999999999999L) >> 64; + #elif SP_WORD_SIZE == 32 + tt = (t * 0x19999999) >> 32; + #elif SP_WORD_SIZE == 16 + tt = (t * 0x1999) >> 16; + #elif SP_WORD_SIZE == 8 + tt = (t * 0x19) >> 8; + #endif + tr = (sp_int_digit)(t - (sp_int_word)tt * 10); + tr = tr % 10; + } + *rem = tr; + } + else { + for (i = a->used - 1; i >= 0; i--) { + t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i]; + #if SP_WORD_SIZE == 64 + tt = (t * 0x1999999999999999L) >> 64; + #elif SP_WORD_SIZE == 32 + tt = (t * 0x19999999) >> 32; + #elif SP_WORD_SIZE == 16 + tt = (t * 0x1999) >> 16; + #elif SP_WORD_SIZE == 8 + tt = (t * 0x19) >> 8; + #endif + tr = (sp_int_digit)(t - (sp_int_word)tt * 10); + tt += tr / 10; + tr = tr % 10; + r->dp[i] = tt; + } + r->used = a->used; + sp_clamp(r); + if (rem != NULL) { + *rem = tr; + } + } +} +#endif /* !WOLFSSL_SP_SMALL && (WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || + * (HAVE_ECC && FP_ECC)) */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && (defined(FP_ECC) || defined(HAVE_COMP_KEY))) +/* Divide by small number: r = a / d and rem = a % d + * + * @param [in] a SP integer to be divided. + * @param [in] d Digit to divide by. + * @param [out] r SP integer that is the quotient. May be NULL. + * @param [out] rem SP integer that is the remainder. May be NULL. + */ +static void _sp_div_small(sp_int* a, sp_int_digit d, sp_int* r, + sp_int_digit* rem) +{ + int i; + sp_int_word t; + sp_int_digit tr = 0; + sp_int_digit tt; + sp_int_digit m; + + if (r == NULL) { + m = SP_DIGIT_MAX / d; + for (i = a->used - 1; i >= 0; i--) { + t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i]; + tt = (t * m) >> SP_WORD_SIZE; + tr = (sp_int_digit)(t - tt * d); + tr = tr % d; + } + *rem = tr; + } + else { + m = SP_DIGIT_MAX / d; + for (i = a->used - 1; i >= 0; i--) { + t = ((sp_int_word)tr << SP_WORD_SIZE) | a->dp[i]; + tt = (t * m) >> SP_WORD_SIZE; + tr = (sp_int_digit)(t - tt * d); + tt += tr / d; + tr = tr % d; + r->dp[i] = tt; + } + r->used = a->used; + sp_clamp(r); + if (rem != NULL) { + *rem = tr; + } + } +} +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) +/* Divide a multi-precision number by a digit size number and calcualte + * remainder. + * r = a / d; rem = a % d + * + * @param [in] a SP integer to be divided. + * @param [in] d Digit to divide by. + * @param [out] r SP integer that is the quotient. May be NULL. + * @param [out] rem Digit that is the remainder. May be NULL. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL or d is 0. + */ +int sp_div_d(sp_int* a, sp_int_digit d, sp_int* r, sp_int_digit* rem) +{ + int err = MP_OKAY; + + if ((a == NULL) || (d == 0)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + #if !defined(WOLFSSL_SP_SMALL) + if (d == 3) { + _sp_div_3(a, r, rem); + } + else if (d == 10) { + _sp_div_10(a, r, rem); + } + else + #endif + if (d <= SP_HALF_MAX) { + _sp_div_small(a, d, r, rem); + } + else + { + int i; + sp_int_word w = 0; + sp_int_digit t; + + for (i = a->used - 1; i >= 0; i--) { + t = sp_div_word((sp_int_digit)w, a->dp[i], d); + w = (w << SP_WORD_SIZE) | a->dp[i]; + w -= (sp_int_word)t * d; + if (r != NULL) { + r->dp[i] = t; + } + } + if (r != NULL) { + r->used = a->used; + sp_clamp(r); + } + + if (rem != NULL) { + *rem = (sp_int_digit)w; + } + } + + #ifdef WOLFSSL_SP_INT_NEGATIVE + if (r != NULL) { + r->sign = a->sign; + } + #endif + } + + return err; +} +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && (defined(FP_ECC) || defined(HAVE_COMP_KEY))) +/* Calculate a modulo the digit d into r: r = a mod d + * + * @param [in] a SP integer to reduce. + * @param [in] d Digit to that is the modulus. + * @param [out] r Digit that is the result.. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL or d is 0. + */ +#if !defined(WOLFSSL_SP_MATH_ALL) && (!defined(HAVE_ECC) || \ + !defined(HAVE_COMP_KEY)) +static +#endif /* !WOLFSSL_SP_MATH_ALL && (!HAVE_ECC || !HAVE_COMP_KEY) */ +int sp_mod_d(sp_int* a, const sp_int_digit d, sp_int_digit* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL) || (d == 0)) { + err = MP_VAL; + } + + if (0) { + sp_print(a, "a"); + sp_print_digit(d, "m"); + } + + if (err == MP_OKAY) { + /* Check whether d is a power of 2. */ + if ((d & (d - 1)) == 0) { + if (a->used == 0) { + *r = 0; + } + else { + *r = a->dp[0] & (d - 1); + } + } + #if !defined(WOLFSSL_SP_SMALL) + else if (d == 3) { + _sp_div_3(a, NULL, r); + } + else if (d == 10) { + _sp_div_10(a, NULL, r); + } + #endif + else if (d <= SP_HALF_MAX) { + _sp_div_small(a, d, NULL, r); + } + else { + int i; + sp_int_word w = 0; + sp_int_digit t; + + for (i = a->used - 1; i >= 0; i--) { + t = sp_div_word((sp_int_digit)w, a->dp[i], d); + w = (w << SP_WORD_SIZE) | a->dp[i]; + w -= (sp_int_word)t * d; + } + + *r = (sp_int_digit)w; + } + + #ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == MP_NEG) { + *r = d - *r; + } + #endif + } + + if (0) { + sp_print_digit(*r, "rmod"); + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || + * (HAVE_ECC && (FP_ECC || HAVE_COMP_KEY)) */ + +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) +/* Divides a by 2 mod m and stores in r: r = (a / 2) mod m + * + * r = a / 2 (mod m) - constant time (a < m and positive) + * + * @param [in] a SP integer to divide. + * @param [in] m SP integer that is modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, m or r is NULL. + */ +int sp_div_2_mod_ct(sp_int* a, sp_int* m, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + sp_int_word w = 0; + sp_int_digit mask; + int i; + + if (0) { + sp_print(a, "a"); + sp_print(m, "m"); + } + + mask = 0 - (a->dp[0] & 1); + for (i = 0; i < m->used; i++) { + sp_int_digit mask_a = 0 - (i < a->used); + + w += m->dp[i] & mask; + w += a->dp[i] & mask_a; + r->dp[i] = (sp_int_digit)w; + w >>= DIGIT_BIT; + } + r->dp[i] = (sp_int_digit)w; + r->used = i + 1; + #ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = MP_ZPOS; + #endif + sp_clamp(r); + sp_div_2(r, r); + + if (0) { + sp_print(r, "rd2"); + } + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL && HAVE_ECC */ + +#if defined(HAVE_ECC) || !defined(NO_DSA) || defined(OPENSSL_EXTRA) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +/* Divides a by 2 and stores in r: r = a >> 1 + * + * @param [in] a SP integer to divide. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL. + */ +#if !(defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)) +static +#endif +int sp_div_2(sp_int* a, sp_int* r) +{ + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) + /* Only when a public API. */ + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } +#endif + + if (err == MP_OKAY) { + int i; + + r->used = a->used; + for (i = 0; i < a->used - 1; i++) { + r->dp[i] = (a->dp[i] >> 1) | (a->dp[i+1] << (SP_WORD_SIZE - 1)); + } + r->dp[i] = a->dp[i] >> 1; + r->used = i + 1; + sp_clamp(r); + #ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = a->sign; + #endif + } + + return err; +} +#endif /* HAVE_ECC || !NO_DSA || OPENSSL_EXTRA || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +/************************ + * Add/Subtract Functions + ************************/ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Add offset b to a into r: r = a + (b << (o * SP_WORD_SIZEOF)) + * + * @param [in] a SP integer to add to. + * @param [in] b SP integer to add. + * @param [out] r SP integer to store result in. + * @param [in] o Number of digits to offset b. + * + * @return MP_OKAY on success. + */ +static int _sp_add_off(sp_int* a, sp_int* b, sp_int* r, int o) +{ + int i; + int j; + sp_int_word t = 0; + + if (0) { + sp_print(a, "a"); + sp_print(b, "b"); + } + +#ifdef SP_MATH_NEED_ADD_OFF + for (i = 0; (i < o) && (i < a->used); i++) { + r->dp[i] = a->dp[i]; + } + for (; i < o; i++) { + r->dp[i] = 0; + } +#else + i = 0; + (void)o; +#endif + + for (j = 0; (i < a->used) && (j < b->used); i++, j++) { + t += a->dp[i]; + t += b->dp[j]; + r->dp[i] = (sp_int_digit)t; + t >>= SP_WORD_SIZE; + } + for (; i < a->used; i++) { + t += a->dp[i]; + r->dp[i] = (sp_int_digit)t; + t >>= SP_WORD_SIZE; + } + for (; j < b->used; i++, j++) { + t += b->dp[j]; + r->dp[i] = (sp_int_digit)t; + t >>= SP_WORD_SIZE; + } + r->used = i; + if (t != 0) { + r->dp[i] = (sp_int_digit)t; + r->used++; + } + + sp_clamp(r); + + if (0) { + sp_print(r, "radd"); + } + + return MP_OKAY; +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE) || \ + !defined(NO_DH) || defined(HAVE_ECC) || (!defined(NO_RSA) && \ + !defined(WOLFSSL_RSA_VERIFY_ONLY)) +/* Sub offset b from a into r: r = a - (b << (o * SP_WORD_SIZEOF)) + * a must be greater than b. + * + * @param [in] a SP integer to subtract from. + * @param [in] b SP integer to subtract. + * @param [out] r SP integer to store result in. + * @param [in] o Number of digits to offset b. + * + * @return MP_OKAY on success. + */ +static int _sp_sub_off(sp_int* a, sp_int* b, sp_int* r, int o) +{ + int i; + int j; + sp_int_sword t = 0; + + for (i = 0; (i < o) && (i < a->used); i++) { + r->dp[i] = a->dp[i]; + } + for (j = 0; (i < a->used) && (j < b->used); i++, j++) { + t += a->dp[i]; + t -= b->dp[j]; + r->dp[i] = (sp_int_digit)t; + t >>= SP_WORD_SIZE; + } + for (; i < a->used; i++) { + t += a->dp[i]; + r->dp[i] = (sp_int_digit)t; + t >>= SP_WORD_SIZE; + } + r->used = i; + sp_clamp(r); + + return MP_OKAY; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_SP_INT_NEGATIVE || !NO_DH || + * HAVE_ECC || (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Add b to a into r: r = a + b + * + * @param [in] a SP integer to add to. + * @param [in] b SP integer to add. + * @param [out] r SP integer to store result in. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b, or r is NULL. + */ +int sp_add(sp_int* a, sp_int* b, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (b == NULL) || (r == NULL)) { + err = MP_VAL; + } + else { + #ifndef WOLFSSL_SP_INT_NEGATIVE + err = _sp_add_off(a, b, r, 0); + #else + if (a->sign == b->sign) { + r->sign = a->sign; + err = _sp_add_off(a, b, r, 0); + } + else if (_sp_cmp_abs(a, b) != MP_LT) { + r->sign = a->sign; + err = _sp_sub_off(a, b, r, 0); + } + else { + r->sign = b->sign; + err = _sp_sub_off(b, a, r, 0); + } + #endif + } + + return err; +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY */ + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +/* Subtract b from a into r: r = a - b + * + * a must be greater than b unless WOLFSSL_SP_INT_NEGATIVE is defined. + * + * @param [in] a SP integer to subtract from. + * @param [in] b SP integer to subtract. + * @param [out] r SP integer to store result in. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b, or r is NULL. + */ +int sp_sub(sp_int* a, sp_int* b, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (b == NULL) || (r == NULL)) { + err = MP_VAL; + } + else { + #ifndef WOLFSSL_SP_INT_NEGATIVE + err = _sp_sub_off(a, b, r, 0); + #else + if (a->sign != b->sign) { + r->sign = a->sign; + err = _sp_add_off(a, b, r, 0); + } + else if (_sp_cmp_abs(a, b) != MP_LT) { + r->sign = a->sign; + err = _sp_sub_off(a, b, r, 0); + } + else { + r->sign = 1 - a->sign; + err = _sp_sub_off(b, a, r, 0); + } + #endif + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY)*/ + +/**************************** + * Add/Subtract mod functions + ****************************/ + +#if defined(WOLFSSL_SP_MATH_ALL) || (!defined(WOLFSSL_SP_MATH) && \ + defined(WOLFSSL_CUSTOM_CURVES)) +/* Add two value and reduce: r = (a + b) % m + * + * @param [in] a SP integer to add. + * @param [in] b SP integer to add with. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b, m or r is NULL. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_addmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) +{ + int err = MP_OKAY; +#ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; +#else + sp_int t[1]; +#endif /* WOLFSSL_SMALL_STACK */ + + if ((a == NULL) || (b == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif /* WOLFSSL_SMALL_STACK */ + + if (0 && (err == MP_OKAY)) { + sp_print(a, "a"); + sp_print(b, "b"); + sp_print(m, "m"); + } + + if (err == MP_OKAY) { + err = sp_add(a, b, t); + } + if (err == MP_OKAY) { + err = sp_mod(t, m, r); + } + + if (0 && (err == MP_OKAY)) { + sp_print(r, "rma"); + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif /* WOLFSSL_SMALL_STACK */ + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || (!WOLFSSL_SP_MATH && WOLFSSL_CUSTOM_CURVES) */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* Sub b from a and reduce: r = (a - b) % m + * Result is always positive. + * + * @param [in] a SP integer to subtract from + * @param [in] b SP integer to subtract. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b, m or r is NULL. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_submod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) +{ +#ifndef WOLFSSL_SP_INT_NEGATIVE + int err = MP_OKAY; +#ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; +#else + sp_int t[2]; +#endif /* WOLFSSL_SMALL_STACK */ + + if ((a == NULL) || (b == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif /* WOLFSSL_SMALL_STACK */ + + if (0 && (err == MP_OKAY)) { + sp_print(a, "a"); + sp_print(b, "b"); + sp_print(m, "m"); + } + + if (err == MP_OKAY) { + if (_sp_cmp(a, m) == MP_GT) { + err = sp_mod(a, m, &t[0]); + a = &t[0]; + } + } + if (err == MP_OKAY) { + if (_sp_cmp(b, m) == MP_GT) { + err = sp_mod(b, m, &t[1]); + b = &t[1]; + } + } + if (err == MP_OKAY) { + if (_sp_cmp(a, b) == MP_LT) { + err = sp_add(a, m, &t[0]); + if (err == MP_OKAY) { + err = sp_sub(&t[0], b, r); + } + } + else { + err = sp_sub(a, b, r); + } + } + + if (0 && (err == MP_OKAY)) { + sp_print(r, "rms"); + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); +#endif /* WOLFSSL_SMALL_STACK */ + return err; + +#else /* WOLFSSL_SP_INT_NEGATIVE */ + + int err = MP_OKAY; +#ifdef WOLFSSL_SMALL_STACK + sp_int* t; +#else + sp_int t[1]; +#endif + + if ((a == NULL) || (b == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif + + if (0 && (err == MP_OKAY)) { + sp_print(a, "a"); + sp_print(b, "b"); + sp_print(m, "m"); + } + if (err == MP_OKAY) { + err = sp_sub(a, b, t); + } + if (err == MP_OKAY) { + err = sp_mod(t, m, r); + } + + if (0 && (err == MP_OKAY)) { + sp_print(r, "rms"); + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); +#endif + return err; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) +/* Compare two multi-precision numbers. + * + * Constant time implementation. + * + * @param [in] a SP integer to compare. + * @param [in] b SP integer to compare. + * @param [in] len Number of digits to compare. + * + * @return MP_GT when a is greater than b. + * @return MP_LT when a is less than b. + * @return MP_EQ when a is equals b. + */ +static int sp_cmp_mag_ct(sp_int* a, sp_int* b, int len) +{ + int i; + sp_sint_digit r = MP_EQ; + sp_int_digit mask = SP_MASK; + + for (i = len - 1; i >= 0; i--) { + sp_int_digit am = 0 - (i < a->used); + sp_int_digit bm = 0 - (i < b->used); + sp_int_digit ad = a->dp[i] & am; + sp_int_digit bd = b->dp[i] & bm; + + r |= mask & (ad > bd); + mask &= (ad > bd) - 1; + r |= mask & (-(ad < bd)); + mask &= (ad < bd) - 1; + } + + return (int)r; +} +#endif /* WOLFSSL_SP_MATH_ALL && HAVE_ECC */ + +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) +/* Add two value and reduce: r = (a + b) % m + * + * r = a + b (mod m) - constant time (|a| < m and |b| < m and positive) + * + * Assumes a, b, m and r are not NULL. + * + * @param [in] a SP integer to add. + * @param [in] b SP integer to add with. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + */ +int sp_addmod_ct(sp_int* a, sp_int* b, sp_int* m, sp_int* r) +{ + sp_int_word w = 0; + sp_int_digit mask; + int i; + + if (0) { + sp_print(a, "a"); + sp_print(b, "b"); + sp_print(m, "m"); + } + + _sp_add_off(a, b, r, 0); + mask = 0 - (sp_cmp_mag_ct(r, m, m->used + 1) != MP_LT); + for (i = 0; i < m->used; i++) { + sp_int_digit mask_r = 0 - (i < r->used); + w += m->dp[i] & mask; + w = (r->dp[i] & mask_r) - w; + r->dp[i] = (sp_int_digit)w; + w = (w >> DIGIT_BIT) & 1; + } + r->dp[i] = 0; + r->used = i; +#ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = a->sign; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ + sp_clamp(r); + + if (0) { + sp_print(r, "rma"); + } + + return MP_OKAY; +} +#endif /* WOLFSSL_SP_MATH_ALL && HAVE_ECC */ + +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) +/* Sub b from a and reduce: r = (a - b) % m + * Result is always positive. + * + * r = a - b (mod m) - constant time (a < n and b < m and positive) + * + * Assumes a, b, m and r are not NULL. + * + * @param [in] a SP integer to subtract from + * @param [in] b SP integer to subtract. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + */ +int sp_submod_ct(sp_int* a, sp_int* b, sp_int* m, sp_int* r) +{ + sp_int_word w = 0; + sp_int_digit mask; + int i; + + if (0) { + sp_print(a, "a"); + sp_print(b, "b"); + sp_print(m, "m"); + } + + mask = 0 - (sp_cmp_mag_ct(a, b, m->used + 1) == MP_LT); + for (i = 0; i < m->used + 1; i++) { + sp_int_digit mask_a = 0 - (i < a->used); + sp_int_digit mask_m = 0 - (i < m->used); + + w += m->dp[i] & mask_m & mask; + w += a->dp[i] & mask_a; + r->dp[i] = (sp_int_digit)w; + w >>= DIGIT_BIT; + } + r->dp[i] = (sp_int_digit)w; + r->used = i + 1; +#ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = MP_ZPOS; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ + sp_clamp(r); + _sp_sub_off(r, b, r, 0); + + if (0) { + sp_print(r, "rms"); + } + + return MP_OKAY; +} +#endif /* WOLFSSL_SP_MATH_ALL && HAVE_ECC */ + +/******************** + * Shifting functoins + ********************/ + +#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \ + !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Left shift the multi-precision number by a number of digits. + * + * @param [in,out] a SP integer to shift. + * @param [in] s Number of digits to shift. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL or the result is too big to fit in an SP. + */ +int sp_lshd(sp_int* a, int s) +{ + int err = MP_OKAY; + + if (a == NULL) { + err = MP_VAL; + } + if ((err == MP_OKAY) && (a->used + s > a->size)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + XMEMMOVE(a->dp + s, a->dp, a->used * sizeof(sp_int_digit)); + a->used += s; + XMEMSET(a->dp, 0, s * sizeof(sp_int_digit)); + sp_clamp(a); + } + + return err; +} +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +/* Left shift the multi-precision number by n bits. + * Bits may be larger than the word size. + * + * @param [in,out] a SP integer to shift. + * @param [in] n Number of bits to shift left. + * + * @return MP_OKAY on success. + */ +static int sp_lshb(sp_int* a, int n) +{ + if (a->used != 0) { + int s = n >> SP_WORD_SHIFT; + int i; + + n &= SP_WORD_MASK; + if (n != 0) { + sp_int_digit v; + + v = a->dp[a->used - 1] >> (SP_WORD_SIZE - n); + a->dp[a->used - 1 + s] = a->dp[a->used - 1] << n; + for (i = a->used - 2; i >= 0; i--) { + a->dp[i + 1 + s] |= a->dp[i] >> (SP_WORD_SIZE - n); + a->dp[i + s] = a->dp[i] << n; + } + if (v != 0) { + a->dp[a->used + s] = v; + a->used++; + } + } + else if (s > 0) { + for (i = a->used - 1; i >= 0; i--) { + a->dp[i + s] = a->dp[i]; + } + } + a->used += s; + XMEMSET(a->dp, 0, SP_WORD_SIZEOF * s); + } + + return MP_OKAY; +} +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +/* Shift a right by n digits into r: r = a >> (n * SP_WORD_SIZE) + * + * @param [in] a SP integer to shift. + * @param [in] n Number of digits to shift. + * @param [out] r SP integer to store result in. + */ +void sp_rshd(sp_int* a, int c) +{ + if (a != NULL) { + int i; + int j; + + if (c >= a->used) { + a->dp[0] = 0; + a->used = 0; + } + else { + for (i = c, j = 0; i < a->used; i++, j++) { + a->dp[j] = a->dp[i]; + } + a->used -= c; + } + } +} +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + defined(WOLFSSL_HAVE_SP_DH) +/* Shift a right by n bits into r: r = a >> n + * + * @param [in] a SP integer to shift. + * @param [in] n Number of bits to shift. + * @param [out] r SP integer to store result in. + */ +void sp_rshb(sp_int* a, int n, sp_int* r) +{ + int i = n >> SP_WORD_SHIFT; + + if (i >= a->used) { + r->dp[0] = 0; + r->used = 0; +#ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = MP_ZPOS; +#endif + } + else { + int j; + + n &= SP_WORD_SIZE - 1; + if (n == 0) { + for (j = 0; i < a->used; i++, j++) + r->dp[j] = a->dp[i]; + r->used = j; + } + else if (n > 0) { + for (j = 0; i < a->used-1; i++, j++) + r->dp[j] = (a->dp[i] >> n) | (a->dp[i+1] << (SP_WORD_SIZE - n)); + r->dp[j] = a->dp[i] >> n; + r->used = j + 1; + sp_clamp(r); + } +#ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = a->sign; +#endif + } +} +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) || WOLFSSL_HAVE_SP_DH */ + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) /* Divide a by d and return the quotient in r and the remainder in rem. * r = a / d; rem = a % d * - * a SP integer to be divided. - * d SP integer to divide by. - * r SP integer of quotient. - * rem SP integer of remainder. - * returns MP_VAL when d is 0, MP_MEM when dynamic memory allocation fails and - * MP_OKAY otherwise. + * @param [in] a SP integer to be divided. + * @param [in] d SP integer to divide by. + * @param [out] r SP integer that is the quotient. + * @param [out] rem SP integer that is the remainder. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or d is NULL, r and rem are NULL, or d is 0. + * @return MP_MEM when dynamic memory allocation fails. */ -static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) +#ifndef WOLFSSL_SP_MATH_ALL +static +#endif +int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) { int err = MP_OKAY; int ret; @@ -845,21 +4283,38 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) sp_int sd[1]; sp_int tr[1]; sp_int trial[1]; -#endif - int o; +#endif /* WOLFSSL_SMALL_STACK */ #ifdef WOLFSSL_SP_SMALL int c; #else - int j; + int j, o; sp_int_word tw; sp_int_sword sw; -#endif +#endif /* WOLFSSL_SP_SMALL */ +#ifdef WOLFSSL_SP_INT_NEGATIVE + int aSign = MP_ZPOS; + int dSign = MP_ZPOS; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ - if (sp_iszero(d)) + if ((a == NULL) || (d == NULL) || ((r == NULL) && (rem == NULL))) { err = MP_VAL; + } + if ((err == MP_OKAY) && sp_iszero(d)) { + err = MP_VAL; + } + + if (0 && (err == MP_OKAY)) { + sp_print(a, "a"); + sp_print(d, "b"); + } if (err == MP_OKAY) { - ret = sp_cmp(a, d); + #ifdef WOLFSSL_SP_INT_NEGATIVE + aSign = a->sign; + dSign = d->sign; + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + + ret = _sp_cmp_abs(a, d); if (ret == MP_LT) { if (rem != NULL) { sp_copy(a, rem); @@ -877,40 +4332,40 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) sp_set(r, 1); #ifdef WOLFSSL_SP_INT_NEGATIVE r->sign = aSign; - #endif + #endif /* WOLFSSL_SP_INT_NEGATIVE */ } done = 1; } else if (sp_count_bits(a) == sp_count_bits(d)) { /* a is greater than d but same bit length */ if (rem != NULL) { - sp_sub(a, d, rem); + _sp_sub_off(a, d, rem, 0); } if (r != NULL) { sp_set(r, 1); #ifdef WOLFSSL_SP_INT_NEGATIVE r->sign = aSign; - #endif + #endif /* WOLFSSL_SP_INT_NEGATIVE */ } done = 1; } } #ifdef WOLFSSL_SMALL_STACK - if (!done && err == MP_OKAY) { + if ((!done) && (err == MP_OKAY)) { sa = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); if (sa == NULL) { err = MP_MEM; } } -#endif +#endif /* WOLFSSL_SMALL_STACK */ - if (!done && err == MP_OKAY) { + if ((!done) && (err == MP_OKAY)) { #ifdef WOLFSSL_SMALL_STACK sd = &sa[1]; tr = &sa[2]; trial = &sa[3]; -#endif +#endif /* WOLFSSL_SMALL_STACK */ sp_init(sa); sp_init(sd); @@ -918,7 +4373,7 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) sp_init(trial); s = sp_count_bits(d); - s = SP_WORD_SIZE - (s % SP_WORD_SIZE); + s = SP_WORD_SIZE - (s & SP_WORD_MASK); sp_copy(a, sa); if (s != SP_WORD_SIZE) { sp_lshb(sa, s); @@ -926,9 +4381,12 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) sp_lshb(sd, s); d = sd; } - - if (d->used < 0) - err = MP_VAL; + } + if ((!done) && (err == MP_OKAY) && (d->used > 0)) { +#ifdef WOLFSSL_SP_INT_NEGATIVE + sa->sign = MP_ZPOS; + sd->sign = MP_ZPOS; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ tr->used = sa->used - d->used + 1; sp_clear(tr); @@ -942,18 +4400,16 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) } if (sa->dp[sa->used - d->used + i] >= d->dp[i]) { i = sa->used; - o = sa->used - d->used; - sp_lshb(d, o * SP_WORD_SIZE); - sp_sub(sa, d, sa); - sp_rshb(d, o * SP_WORD_SIZE, d); + _sp_sub_off(sa, d, sa, sa->used - d->used); + /* Keep the same used so that 0 zeros will be put in. */ sa->used = i; if (r != NULL) { - tr->dp[o] = 1; + tr->dp[sa->used - d->used] = 1; } } for (i = sa->used - 1; i >= d->used; i--) { if (sa->dp[i] == dt) { - t = SP_MASK; /* f's */ + t = SP_DIGIT_MAX; } else { t = sp_div_word(sa->dp[i], sa->dp[i-1], dt); @@ -962,14 +4418,14 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) #ifdef WOLFSSL_SP_SMALL do { _sp_mul_d(d, t, trial, i - d->used); - c = sp_cmp(trial, sa); + c = _sp_cmp_abs(trial, sa); if (c == MP_GT) { t--; } } while (c == MP_GT); - sp_sub(sa, trial, sa); + _sp_sub_off(sa, trial, sa, 0); tr->dp[i - d->used] += t; if (tr->dp[i - d->used] < t) { tr->dp[i + 1 - d->used]++; @@ -1000,439 +4456,3237 @@ static int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem) for (j = 0; j <= d->used; j++) { sw += sa->dp[j + o]; sw -= trial->dp[j]; - sa->dp[j + o] = (sp_digit)sw; + sa->dp[j + o] = (sp_int_digit)sw; sw >>= SP_WORD_SIZE; } - tr->dp[o] += t; - if (tr->dp[o] < t) { - tr->dp[o + 1]++; - } -#endif + tr->dp[o] = t; +#endif /* WOLFSSL_SP_SMALL */ } sa->used = i + 1; if (rem != NULL) { - if (s != SP_WORD_SIZE) +#ifdef WOLFSSL_SP_INT_NEGATIVE + sa->sign = (sa->used == 0) ? MP_ZPOS : aSign; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ + if (s != SP_WORD_SIZE) { sp_rshb(sa, s, sa); + } sp_copy(sa, rem); sp_clamp(rem); } if (r != NULL) { sp_copy(tr, r); sp_clamp(r); +#ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = (aSign == dSign) ? MP_ZPOS : MP_NEG; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ } } #ifdef WOLFSSL_SMALL_STACK if (sa != NULL) XFREE(sa, NULL, DYNAMIC_TYPE_BIGINT); -#endif +#endif /* WOLFSSL_SMALL_STACK */ + + if (0 && (err == MP_OKAY)) { + if (rem != NULL) { + sp_print(rem, "rdr"); + } + if (r != NULL) { + sp_print(r, "rdw"); + } + } return err; } +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || \ + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ - +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) #ifndef FREESCALE_LTC_TFM /* Calculate the remainder of dividing a by m: r = a mod m. * - * a SP integer. - * m SP integer. - * r SP integer. - * returns MP_VAL when m is 0 and MP_OKAY otherwise. + * @param [in] a SP integer to reduce. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to store result in. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, m or r is NULL or m is 0. */ int sp_mod(sp_int* a, sp_int* m, sp_int* r) { - return sp_div(a, m, NULL, r); -} -#endif -#endif + int err = MP_OKAY; +#ifdef WOLFSSL_SP_INT_NEGATIVE + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif /* WOLFSSL_SMALL_STACK */ +#endif /* WOLFSSL_SP_INT_NEGATIVE */ -/* Clear all data in the big number and sets value to zero. - * - * a SP integer. - */ -void sp_zero(sp_int* a) -{ - XMEMSET(a->dp, 0, a->size * sizeof(*a->dp)); - a->used = 0; -} - -/* Add a one digit number to the big number. - * - * a SP integer. - * d Digit to add. - * r SP integer - result. - * returns MP_OKAY always. - */ -int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r) -{ - int i = 0; - sp_int_digit t; - - if (a == NULL || r == NULL || a->used > SP_INT_DIGITS) - return BAD_FUNC_ARG; - - r->used = a->used; - - if (d == 0) { - /*copy the content of to */ - for (; i < a->used; i++) - r->dp[i] = a->dp[i]; - - return MP_OKAY; - } - - if (a->used == 0) { - r->used = 1; - t = d; - } - else - t = a->dp[0] + d; - - if (a->used != 0 && t < a->dp[0]) { - for (++i; i < a->used; i++) { - r->dp[i] = a->dp[i] + 1; - if (r->dp[i] != 0) { - break; - } - } - if (i == a->used) { - r->used++; - if (i < SP_INT_DIGITS) - r->dp[i] = 1; - else - return MP_VAL; - } - } - r->dp[0] = t; - if (r != a) { - for (++i; i < a->used; i++) - r->dp[i] = a->dp[i]; - } - - return MP_OKAY; -} - - -#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \ - !defined(WOLFSSL_RSA_VERIFY_ONLY) -/* Left shift the big number by a number of digits. - * WIll chop off digits overflowing maximum size. - * - * a SP integer. - * s Number of digits to shift. - * returns MP_OKAY always. - */ -int sp_lshd(sp_int* a, int s) -{ - if (a->used + s > a->size) - a->used = a->size - s; - - XMEMMOVE(a->dp + s, a->dp, a->used * sizeof(sp_int_digit)); - a->used += s; - XMEMSET(a->dp, 0, s * sizeof(sp_int_digit)); - sp_clamp(a); - - return MP_OKAY; -} -#endif - -#if !defined(NO_PWDBASED) || defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) -/* Add two large numbers into result: r = a + b - * - * a SP integer. - * b SP integer. - * r SP integer. - * returns MP_OKAY always. - */ -int sp_add(sp_int* a, sp_int* b, sp_int* r) -{ - int i; - sp_int_digit c = 0; - sp_int_digit t; - - for (i = 0; i < a->used && i < b->used; i++) { - t = a->dp[i] + b->dp[i] + c; - if (c == 0) - c = t < a->dp[i]; - else - c = t <= a->dp[i]; - r->dp[i] = t; - } - for (; i < a->used; i++) { - r->dp[i] = a->dp[i] + c; - c = (a->dp[i] != 0) && (r->dp[i] == 0); - } - for (; i < b->used; i++) { - r->dp[i] = b->dp[i] + c; - c = (b->dp[i] != 0) && (r->dp[i] == 0); - } - if (c != 0) { - r->dp[i] = c; - } - r->used = (int)(i + c); - - return MP_OKAY; -} -#endif /* !NO_PWDBASED || WOLFSSL_KEY_GEN || !NO_DH */ - -#ifndef NO_RSA -/* Set a number into the big number. - * - * a SP integer. - * b Value to set. - * returns MP_OKAY always. - */ -int sp_set_int(sp_int* a, unsigned long b) -{ - if (b == 0) { - a->used = 0; - a->dp[0] = 0; - } - else { - a->used = 1; - a->dp[0] = (sp_int_digit)b; - } - - return MP_OKAY; -} -#endif /* !NO_RSA */ - -#ifdef WC_MP_TO_RADIX -/* Hex string characters. */ -static const char sp_hex_char[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' -}; - -/* Put the hex string version, big-endian, of a in str. - * - * a SP integer. - * str Hex string is stored here. - * returns MP_OKAY always. - */ -int sp_tohex(sp_int* a, char* str) -{ - int i, j; - - /* quick out if its zero */ - if (sp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - } - else { - i = a->used - 1; - for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4) { - if (((a->dp[i] >> j) & 0xf) != 0) - break; - } - for (; j >= 0; j -= 4) - *(str++) = sp_hex_char[(a->dp[i] >> j) & 0xf]; - for (--i; i >= 0; i--) { - for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4) - *(str++) = sp_hex_char[(a->dp[i] >> j) & 0xf]; - } - *str = '\0'; - } - - return MP_OKAY; -} -#endif /* WC_MP_TO_RADIX */ - -#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) && !defined(WC_NO_RNG) -/* Set a bit of a: a |= 1 << i - * The field 'used' is updated in a. - * - * a SP integer to modify. - * i Index of bit to set. - * returns MP_OKAY always. - */ -int sp_set_bit(sp_int* a, int i) -{ - int ret = MP_OKAY; - - if ((a == NULL) || (i / SP_WORD_SIZE >= SP_INT_DIGITS)) { - ret = BAD_FUNC_ARG; - } - else { - a->dp[i/SP_WORD_SIZE] |= (sp_int_digit)1 << (i % SP_WORD_SIZE); - if (a->used <= i / SP_WORD_SIZE) - a->used = (i / SP_WORD_SIZE) + 1; - } - return ret; -} - -/* Exponentiate 2 to the power of e: a = 2^e - * This is done by setting the 'e'th bit. - * - * a SP integer. - * e Exponent. - * returns MP_OKAY always. - */ -int sp_2expt(sp_int* a, int e) -{ - sp_zero(a); - return sp_set_bit(a, e); -} - -/* Generate a random prime for RSA only. - * - * r SP integer - * len Number of bytes to prime. - * rng Random number generator. - * heap Unused - * returns MP_OKAY on success and MP_VAL when length is not supported or random - * number genrator fails. - */ -int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap) -{ - static const int USE_BBS = 1; - int err = 0, type; - int isPrime = MP_NO; - - (void)heap; - - /* get type */ - if (len < 0) { - type = USE_BBS; - len = -len; - } - else { - type = 0; - } - -#if defined(WOLFSSL_HAVE_SP_DH) && defined(WOLFSSL_KEY_GEN) - if (len == 32) { - } - else -#endif - /* Generate RSA primes that are half the modulus length. */ -#ifndef WOLFSSL_SP_NO_3072 - if (len != 128 && len != 192) -#else - if (len != 128) -#endif - { + if ((a == NULL) || (m == NULL) || (r == NULL)) { err = MP_VAL; } - r->used = len / (SP_WORD_SIZE / 8); - - /* Assume the candidate is probably prime and then test until - * it is proven composite. */ - while (err == 0 && isPrime == MP_NO) { -#ifdef SHOW_GEN - printf("."); - fflush(stdout); -#endif - /* generate value */ - err = wc_RNG_GenerateBlock(rng, (byte*)r->dp, len); - if (err != 0) { - err = MP_VAL; - break; - } - - /* munge bits */ - ((byte*)r->dp)[len-1] |= 0x80 | 0x40; - r->dp[0] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); - - /* test */ - /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance - * of a 1024-bit candidate being a false positive, when it is our - * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.) - * Using 8 because we've always used 8 */ - sp_prime_is_prime_ex(r, 8, &isPrime, rng); +#ifndef WOLFSSL_SP_INT_NEGATIVE + if (err == MP_OKAY) { + err = sp_div(a, m, NULL, r); } +#else + if (err == MP_OKAY) { + #ifdef WOLFSSL_SMALL_STACK + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + #endif /* WOLFSSL_SMALL_STACK */ + } + if (err == MP_OKAY) { + sp_init(t); + err = sp_div(a, m, NULL, t); + } + if (err == MP_OKAY) { + if (t->sign != m->sign) { + err = sp_add(t, m, r); + } + else { + err = sp_copy(t, r); + } + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif /* WOLFSSL_SMALL_STACK */ +#endif /* WOLFSSL_SP_INT_NEGATIVE */ return err; } +#endif /* !FREESCALE_LTC_TFM */ +#endif /* WOLFSSL_SP_MATH_ALL || !NO_DH || HAVE_ECC || \ + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +/* START SP_MUL implementations. */ +/* This code is generated. + * To generate: + * cd scripts/sp/sp_int + * ./gen.sh + * File sp_mul.c contains code. + */ + +#ifdef SQR_MUL_ASM + /* Multiply a by b into r where a and b have same no. digits. r = a * b + * + * Optimised code for when number of digits in a and b are the same. + * + * @param [in] a SP integer to mulitply. + * @param [in] b SP integer to mulitply by. + * @param [out] r SP integer to hod reult. + * + * @return MP_OKAY otherwise. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_nxn(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + int j; + int k; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + sp_int_digit l, h, o; + sp_int_digit* dp; + + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + h = 0; + o = 0; + for (k = 1; k <= a->used - 1; k++) { + j = k; + dp = a->dp; + for (; j >= 0; dp++, j--) { + SP_ASM_MUL_ADD(l, h, o, dp[0], b->dp[j]); + } + t->dp[k] = l; + l = h; + h = o; + o = 0; + } + for (; k <= (a->used - 1) * 2; k++) { + i = k - (b->used - 1); + dp = &b->dp[b->used - 1]; + for (; i < a->used; i++, dp--) { + SP_ASM_MUL_ADD(l, h, o, a->dp[i], dp[0]); + } + t->dp[k] = l; + l = h; + h = o; + o = 0; + } + t->dp[k] = l; + t->dp[k+1] = h; + t->used = k + 2; + + sp_copy(t, r); + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + + /* Multiply a by b into r. r = a * b + * + * @param [in] a SP integer to mulitply. + * @param [in] b SP integer to mulitply by. + * @param [out] r SP integer to hod reult. + * + * @return MP_OKAY otherwise. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + int j; + int k; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + h = 0; + o = 0; + for (k = 1; k <= b->used - 1; k++) { + i = 0; + j = k; + for (; (i < a->used) && (j >= 0); i++, j--) { + SP_ASM_MUL_ADD(l, h, o, a->dp[i], b->dp[j]); + } + t->dp[k] = l; + l = h; + h = o; + o = 0; + } + for (; k <= (a->used - 1) + (b->used - 1); k++) { + j = b->used - 1; + i = k - j; + for (; (i < a->used) && (j >= 0); i++, j--) { + SP_ASM_MUL_ADD(l, h, o, a->dp[i], b->dp[j]); + } + t->dp[k] = l; + l = h; + h = o; + o = 0; + } + t->dp[k] = l; + t->dp[k+1] = h; + t->used = k + 2; + + sp_copy(t, r); + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#else + /* Multiply a by b into r. r = a * b + * + * @param [in] a SP integer to mulitply. + * @param [in] b SP integer to mulitply by. + * @param [out] r SP integer to hod reult. + * + * @return MP_OKAY otherwise. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + int j; + int k; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + sp_int_word w; + sp_int_word l; + sp_int_word h; + + w = (sp_int_word)a->dp[0] * b->dp[0]; + t->dp[0] = (sp_int_digit)w; + l = (sp_int_digit)(w >> SP_WORD_SIZE); + h = 0; + for (k = 1; k <= (a->used - 1) + (b->used - 1); k++) { + i = k - (b->used - 1); + i &= ~(i >> (sizeof(i) * 8 - 1)); + j = k - i; + for (; (i < a->used) && (j >= 0); i++, j--) { + w = (sp_int_word)a->dp[i] * b->dp[j]; + l += (sp_int_digit)w; + h += (sp_int_digit)(w >> SP_WORD_SIZE); + } + t->dp[k] = (sp_int_digit)l; + l >>= SP_WORD_SIZE; + l += (sp_int_digit)h; + h >>= SP_WORD_SIZE; + } + t->dp[k] = (sp_int_digit)l; + t->dp[k+1] = (sp_int_digit)h; + t->used = k + 2; + + sp_clamp(t); + sp_copy(t, r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif + +#ifndef WOLFSSL_SP_SMALL +#ifndef WOLFSSL_HAVE_SP_ECC +#if SP_WORD_SIZE == 64 +#ifndef SQR_MUL_ASM + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_4(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + #ifdef WOLFSSL_SMALL_STACK + sp_int_word* w = NULL; + #else + sp_int_word w[16]; + #endif + sp_int_digit* da = a->dp; + sp_int_digit* db = b->dp; + + #ifdef WOLFSSL_SMALL_STACK + w = (sp_int_word*)XMALLOC(sizeof(sp_word) * 16, NULL, + DYNAMIC_TYPE_BIGINT); + if (w == NULL) { + err = MP_MEM; + } + #endif + + if (err == MP_OKAY) { + w[0] = (sp_int_word)da[0] * db[0]; + w[1] = (sp_int_word)da[0] * db[1]; + w[2] = (sp_int_word)da[1] * db[0]; + w[3] = (sp_int_word)da[0] * db[2]; + w[4] = (sp_int_word)da[1] * db[1]; + w[5] = (sp_int_word)da[2] * db[0]; + w[6] = (sp_int_word)da[0] * db[3]; + w[7] = (sp_int_word)da[1] * db[2]; + w[8] = (sp_int_word)da[2] * db[1]; + w[9] = (sp_int_word)da[3] * db[0]; + w[10] = (sp_int_word)da[1] * db[3]; + w[11] = (sp_int_word)da[2] * db[2]; + w[12] = (sp_int_word)da[3] * db[1]; + w[13] = (sp_int_word)da[2] * db[3]; + w[14] = (sp_int_word)da[3] * db[2]; + w[15] = (sp_int_word)da[3] * db[3]; + + r->dp[0] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[1]; + w[0] += (sp_int_digit)w[2]; + r->dp[1] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[1] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[1]; + w[2] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[2]; + w[0] += (sp_int_digit)w[3]; + w[0] += (sp_int_digit)w[4]; + w[0] += (sp_int_digit)w[5]; + r->dp[2] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[3] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[3]; + w[4] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[4]; + w[5] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[5]; + w[0] += (sp_int_digit)w[6]; + w[0] += (sp_int_digit)w[7]; + w[0] += (sp_int_digit)w[8]; + w[0] += (sp_int_digit)w[9]; + r->dp[3] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[6] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[6]; + w[7] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[7]; + w[8] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[8]; + w[9] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[9]; + w[0] += (sp_int_digit)w[10]; + w[0] += (sp_int_digit)w[11]; + w[0] += (sp_int_digit)w[12]; + r->dp[4] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[10] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[10]; + w[11] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[11]; + w[12] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[12]; + w[0] += (sp_int_digit)w[13]; + w[0] += (sp_int_digit)w[14]; + r->dp[5] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[13] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[13]; + w[14] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[14]; + w[0] += (sp_int_digit)w[15]; + r->dp[6] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[15] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[15]; + r->dp[7] = w[0]; + + r->used = 8; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (w != NULL) { + XFREE(w, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + return err; + } +#else /* SQR_MUL_ASM */ + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_4(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[0]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[0]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[0]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[1]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[2]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[3], b->dp[3]); + t->dp[6] = l; + t->dp[7] = h; + t->used = 8; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 64 +#ifdef SQR_MUL_ASM + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_6(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[0]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[0]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[0]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[0]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[0]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[1]); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[2]); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[3]); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[4]); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[5], b->dp[5]); + t->dp[10] = l; + t->dp[11] = h; + t->used = 12; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_8(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[0]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[0]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[0]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[0]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[0]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[0]); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[0]); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[1]); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[2]); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[3]); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[4]); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[5]); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[6]); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[7], b->dp[7]); + t->dp[14] = l; + t->dp[15] = h; + t->used = 16; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_12(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[0]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[0]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[0]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[0]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[0]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[0]); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[0]); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[0]); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[0]); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[0]); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[0]); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[1]); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[2]); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[3]); + t->dp[14] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[4]); + t->dp[15] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[5]); + t->dp[16] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[6]); + t->dp[17] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[7]); + t->dp[18] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[8]); + t->dp[19] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[9]); + t->dp[20] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[10]); + t->dp[21] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[11], b->dp[11]); + t->dp[22] = l; + t->dp[23] = h; + t->used = 24; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#endif /* WOLFSSL_HAVE_SP_ECC */ + +#if defined(SQR_MUL_ASM) && defined(WOLFSSL_SP_INT_LARGE_COMBA) + #if SP_INT_DIGITS >= 32 + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_16(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[0]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[0]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[0]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[0]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[0]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[0]); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[0]); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[0]); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[0]); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[0]); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[0]); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[0]); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[0]); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[0]); + t->dp[14] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[0]); + t->dp[15] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[1]); + t->dp[16] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[2]); + t->dp[17] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[3]); + t->dp[18] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[4]); + t->dp[19] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[5]); + t->dp[20] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[6]); + t->dp[21] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[7]); + t->dp[22] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[8]); + t->dp[23] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[9]); + t->dp[24] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[10]); + t->dp[25] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[11]); + t->dp[26] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[12]); + t->dp[27] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[13]); + t->dp[28] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[14]); + t->dp[29] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[15], b->dp[15]); + t->dp[30] = l; + t->dp[31] = h; + t->used = 32; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 32 */ + + #if SP_INT_DIGITS >= 48 + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_24(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_MUL(t->dp[0], l, a->dp[0], b->dp[0]); + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[0]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[0], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[0]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[0]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[0]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[0]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[0]); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[0]); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[0]); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[0]); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[0]); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[0]); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[0]); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[0]); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[0]); + t->dp[14] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[0]); + t->dp[15] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[0]); + t->dp[16] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[0]); + t->dp[17] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[0]); + t->dp[18] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[0]); + t->dp[19] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[0]); + t->dp[20] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[0]); + t->dp[21] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[0]); + t->dp[22] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[0], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[1]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[0]); + t->dp[23] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[1], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[2]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[1]); + t->dp[24] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[2], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[3]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[2]); + t->dp[25] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[3], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[4]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[3]); + t->dp[26] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[4], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[5]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[4]); + t->dp[27] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[5], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[6]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[5]); + t->dp[28] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[6], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[7]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[6]); + t->dp[29] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[7], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[8]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[7]); + t->dp[30] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[8], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[9]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[8]); + t->dp[31] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[9], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[10]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[9]); + t->dp[32] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[10], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[11]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[10]); + t->dp[33] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[11], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[12]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[11]); + t->dp[34] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[12], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[13]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[12]); + t->dp[35] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[13], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[14]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[13]); + t->dp[36] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[14], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[15]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[14]); + t->dp[37] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[15], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[16]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[15]); + t->dp[38] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[16], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[17]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[16]); + t->dp[39] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[17], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[18]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[17]); + t->dp[40] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[18], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[19]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[18]); + t->dp[41] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[19], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[20]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[19]); + t->dp[42] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[20], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[21]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[20]); + t->dp[43] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[21], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[22]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[21]); + t->dp[44] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD(l, h, o, a->dp[22], b->dp[23]); + SP_ASM_MUL_ADD(l, h, o, a->dp[23], b->dp[22]); + t->dp[45] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD_NO(l, h, a->dp[23], b->dp[23]); + t->dp[46] = l; + t->dp[47] = h; + t->used = 48; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 48 */ + + #if SP_INT_DIGITS >= 64 + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_32(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[4]; + #endif + sp_int* a1; + sp_int* b1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + sp_int_digit cb; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + b1 = &t[1]; + z0 = r; + z1 = &t[2]; + z2 = &t[3]; + + XMEMCPY(a1->dp, &a->dp[16], sizeof(sp_int_digit) * 16); + a1->used = 16; + XMEMCPY(b1->dp, &b->dp[16], sizeof(sp_int_digit) * 16); + b1->used = 16; + + /* z2 = a1 * b1 */ + err = _sp_mul_16(a1, b1, z2); + } + if (err == MP_OKAY) { + l = a1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, a->dp[0]); + a1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 16; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + /* b01 = b0 + b1 */ + l = b1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, b->dp[0]); + b1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 16; i++) { + SP_ASM_ADDC(l, h, b1->dp[i]); + SP_ASM_ADDC(l, h, b->dp[i]); + b1->dp[i] = l; + l = h; + h = 0; + } + cb = l; + + /* z0 = a0 * b0 */ + err = _sp_mul_16(a, b, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) * (b0 + b1) */ + err = _sp_mul_16(a1, b1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 32) + (z1 - z0 - z2) << 16) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 16 */ + z1->dp[32] = ca & cb; + z1->used = 33; + if (ca) { + l = 0; + h = 0; + for (i = 0; i < 16; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 16]); + SP_ASM_ADDC(l, h, b1->dp[i]); + z1->dp[i + 16] = l; + l = h; + h = 0; + } + z1->dp[32] += l; + } + if (cb) { + l = 0; + h = 0; + for (i = 0; i < 16; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 16]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 16] = l; + l = h; + h = 0; + } + z1->dp[32] += l; + } + /* z1 = z1 - z0 - z1 */ + l = 0; + h = 0; + for (i = 0; i < 32; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 16; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 16]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 16] = l; + l = h; + h = 0; + } + for (; i < 33; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 16] = l; + l = h; + h = 0; + } + /* r += z2 << 32 */ + l = 0; + h = 0; + for (i = 0; i < 17; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 32]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + for (; i < 32; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + r->used = 64; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 64 */ + + #if SP_INT_DIGITS >= 96 + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_48(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[4]; + #endif + sp_int* a1; + sp_int* b1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + sp_int_digit cb; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + b1 = &t[1]; + z0 = r; + z1 = &t[2]; + z2 = &t[3]; + + XMEMCPY(a1->dp, &a->dp[24], sizeof(sp_int_digit) * 24); + a1->used = 24; + XMEMCPY(b1->dp, &b->dp[24], sizeof(sp_int_digit) * 24); + b1->used = 24; + + /* z2 = a1 * b1 */ + err = _sp_mul_24(a1, b1, z2); + } + if (err == MP_OKAY) { + l = a1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, a->dp[0]); + a1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 24; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + /* b01 = b0 + b1 */ + l = b1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, b->dp[0]); + b1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 24; i++) { + SP_ASM_ADDC(l, h, b1->dp[i]); + SP_ASM_ADDC(l, h, b->dp[i]); + b1->dp[i] = l; + l = h; + h = 0; + } + cb = l; + + /* z0 = a0 * b0 */ + err = _sp_mul_24(a, b, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) * (b0 + b1) */ + err = _sp_mul_24(a1, b1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 48) + (z1 - z0 - z2) << 24) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 24 */ + z1->dp[48] = ca & cb; + z1->used = 49; + if (ca) { + l = 0; + h = 0; + for (i = 0; i < 24; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 24]); + SP_ASM_ADDC(l, h, b1->dp[i]); + z1->dp[i + 24] = l; + l = h; + h = 0; + } + z1->dp[48] += l; + } + if (cb) { + l = 0; + h = 0; + for (i = 0; i < 24; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 24]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 24] = l; + l = h; + h = 0; + } + z1->dp[48] += l; + } + /* z1 = z1 - z0 - z1 */ + l = 0; + h = 0; + for (i = 0; i < 48; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 24; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 24]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 24] = l; + l = h; + h = 0; + } + for (; i < 49; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 24] = l; + l = h; + h = 0; + } + /* r += z2 << 48 */ + l = 0; + h = 0; + for (i = 0; i < 25; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 48]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + for (; i < 48; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + r->used = 96; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 96 */ + + #if SP_INT_DIGITS >= 128 + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_64(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[4]; + #endif + sp_int* a1; + sp_int* b1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + sp_int_digit cb; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + b1 = &t[1]; + z0 = r; + z1 = &t[2]; + z2 = &t[3]; + + XMEMCPY(a1->dp, &a->dp[32], sizeof(sp_int_digit) * 32); + a1->used = 32; + XMEMCPY(b1->dp, &b->dp[32], sizeof(sp_int_digit) * 32); + b1->used = 32; + + /* z2 = a1 * b1 */ + err = _sp_mul_32(a1, b1, z2); + } + if (err == MP_OKAY) { + l = a1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, a->dp[0]); + a1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 32; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + /* b01 = b0 + b1 */ + l = b1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, b->dp[0]); + b1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 32; i++) { + SP_ASM_ADDC(l, h, b1->dp[i]); + SP_ASM_ADDC(l, h, b->dp[i]); + b1->dp[i] = l; + l = h; + h = 0; + } + cb = l; + + /* z0 = a0 * b0 */ + err = _sp_mul_32(a, b, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) * (b0 + b1) */ + err = _sp_mul_32(a1, b1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 64) + (z1 - z0 - z2) << 32) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 32 */ + z1->dp[64] = ca & cb; + z1->used = 65; + if (ca) { + l = 0; + h = 0; + for (i = 0; i < 32; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 32]); + SP_ASM_ADDC(l, h, b1->dp[i]); + z1->dp[i + 32] = l; + l = h; + h = 0; + } + z1->dp[64] += l; + } + if (cb) { + l = 0; + h = 0; + for (i = 0; i < 32; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 32]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 32] = l; + l = h; + h = 0; + } + z1->dp[64] += l; + } + /* z1 = z1 - z0 - z1 */ + l = 0; + h = 0; + for (i = 0; i < 64; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 32; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 32]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + for (; i < 65; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + /* r += z2 << 64 */ + l = 0; + h = 0; + for (i = 0; i < 33; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 64]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 64] = l; + l = h; + h = 0; + } + for (; i < 64; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 64] = l; + l = h; + h = 0; + } + r->used = 128; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 128 */ + + #if SP_INT_DIGITS >= 192 + /* Multiply a by b and store in r: r = a * b + * + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_mul_96(sp_int* a, sp_int* b, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[4]; + #endif + sp_int* a1; + sp_int* b1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + sp_int_digit cb; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + b1 = &t[1]; + z0 = r; + z1 = &t[2]; + z2 = &t[3]; + + XMEMCPY(a1->dp, &a->dp[48], sizeof(sp_int_digit) * 48); + a1->used = 48; + XMEMCPY(b1->dp, &b->dp[48], sizeof(sp_int_digit) * 48); + b1->used = 48; + + /* z2 = a1 * b1 */ + err = _sp_mul_48(a1, b1, z2); + } + if (err == MP_OKAY) { + l = a1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, a->dp[0]); + a1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 48; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + /* b01 = b0 + b1 */ + l = b1->dp[0]; + h = 0; + SP_ASM_ADDC(l, h, b->dp[0]); + b1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 48; i++) { + SP_ASM_ADDC(l, h, b1->dp[i]); + SP_ASM_ADDC(l, h, b->dp[i]); + b1->dp[i] = l; + l = h; + h = 0; + } + cb = l; + + /* z0 = a0 * b0 */ + err = _sp_mul_48(a, b, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) * (b0 + b1) */ + err = _sp_mul_48(a1, b1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 96) + (z1 - z0 - z2) << 48) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 48 */ + z1->dp[96] = ca & cb; + z1->used = 97; + if (ca) { + l = 0; + h = 0; + for (i = 0; i < 48; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 48]); + SP_ASM_ADDC(l, h, b1->dp[i]); + z1->dp[i + 48] = l; + l = h; + h = 0; + } + z1->dp[96] += l; + } + if (cb) { + l = 0; + h = 0; + for (i = 0; i < 48; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 48]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 48] = l; + l = h; + h = 0; + } + z1->dp[96] += l; + } + /* z1 = z1 - z0 - z1 */ + l = 0; + h = 0; + for (i = 0; i < 96; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 48; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 48]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + for (; i < 97; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + /* r += z2 << 96 */ + l = 0; + h = 0; + for (i = 0; i < 49; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 96]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 96] = l; + l = h; + h = 0; + } + for (; i < 96; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 96] = l; + l = h; + h = 0; + } + r->used = 192; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 192 */ + +#endif /* SQR_MUL_ASM && WOLFSSL_SP_INT_LARGE_COMBA */ +#endif /* !WOLFSSL_SP_SMALL */ /* Multiply a by b and store in r: r = a * b * - * a SP integer to multiply. - * b SP integer to multiply. - * r SP integer result. - * returns MP_OKAY always. + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b or is NULL; or the result will be too big for fixed + * data length. + * @return MP_MEM when dynamic memory allocation fails. */ int sp_mul(sp_int* a, sp_int* b, sp_int* r) { int err = MP_OKAY; - int i; -#ifdef WOLFSSL_SMALL_STACK - sp_int* t = NULL; - sp_int* tr; -#else - sp_int t[1]; - sp_int tr[1]; +#ifdef WOLFSSL_SP_INT_NEGATIVE + int sign; #endif + if ((a == NULL) || (b == NULL) || (r == NULL)) { + err = MP_VAL; + } + /* Need extra digit during calculation. */ - if (a->used + b->used > (SP_INT_DIGITS - 1)) + if ((err == MP_OKAY) && (a->used + b->used >= r->size)) { err = MP_VAL; - -#ifdef WOLFSSL_SMALL_STACK - if (err == MP_OKAY) { - t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); - if (t == NULL) - err = MP_MEM; - else - tr = &t[1]; } -#endif + + if (0 && (err == MP_OKAY)) { + sp_print(a, "a"); + sp_print(b, "b"); + } if (err == MP_OKAY) { - sp_init(t); - sp_init(tr); + #ifdef WOLFSSL_SP_INT_NEGATIVE + sign = a->sign ^ b->sign; + #endif - for (i = 0; i < b->used; i++) { - _sp_mul_d(a, b->dp[i], t, i); - sp_add(tr, t, tr); + if ((a->used == 0) || (b->used == 0)) { + _sp_zero(r); + } + else +#ifndef WOLFSSL_SP_SMALL +#ifndef WOLFSSL_HAVE_SP_ECC +#if SP_WORD_SIZE == 64 + if ((a->used == 4) && (b->used == 4)) { + err = _sp_mul_4(a, b, r); + } + else +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 64 +#ifdef SQR_MUL_ASM + if ((a->used == 6) && (b->used == 6)) { + err = _sp_mul_6(a, b, r); + } + else +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + if ((a->used == 8) && (b->used == 8)) { + err = _sp_mul_8(a, b, r); + } + else +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + if ((a->used == 12) && (b->used == 12)) { + err = _sp_mul_12(a, b, r); + } + else +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#endif /* WOLFSSL_HAVE_SP_ECC */ +#if defined(SQR_MUL_ASM) && defined(WOLFSSL_SP_INT_LARGE_COMBA) + #if SP_INT_DIGITS >= 32 + if ((a->used == 16) && (b->used == 16)) { + err = _sp_mul_16(a, b, r); + } + else + #endif /* SP_INT_DIGITS >= 32 */ + #if SP_INT_DIGITS >= 48 + if ((a->used == 24) && (b->used == 24)) { + err = _sp_mul_24(a, b, r); + } + else + #endif /* SP_INT_DIGITS >= 48 */ + #if SP_INT_DIGITS >= 64 + if ((a->used == 32) && (b->used == 32)) { + err = _sp_mul_32(a, b, r); + } + else + #endif /* SP_INT_DIGITS >= 64 */ + #if SP_INT_DIGITS >= 96 + if ((a->used == 48) && (b->used == 48)) { + err = _sp_mul_48(a, b, r); + } + else + #endif /* SP_INT_DIGITS >= 96 */ + #if SP_INT_DIGITS >= 128 + if ((a->used == 64) && (b->used == 64)) { + err = _sp_mul_64(a, b, r); + } + else + #endif /* SP_INT_DIGITS >= 128 */ + #if SP_INT_DIGITS >= 192 + if ((a->used == 96) && (b->used == 96)) { + err = _sp_mul_96(a, b, r); + } + else + #endif /* SP_INT_DIGITS >= 192 */ +#endif /* SQR_MUL_ASM && WOLFSSL_SP_INT_LARGE_COMBA */ +#endif /* !WOLFSSL_SP_SMALL */ + +#ifdef SQR_MUL_ASM + if (a->used == b->used) { + err = _sp_mul_nxn(a, b, r); + } + else +#endif + { + err = _sp_mul(a, b, r); } - sp_copy(tr, r); } -#ifdef WOLFSSL_SMALL_STACK - if (t != NULL) - XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); +#ifdef WOLFSSL_SP_INT_NEGATIVE + if (err == MP_OKAY) { + r->sign = (r->used == 0) ? MP_ZPOS : sign; + } #endif - return err; -} - -/* Square a mod m and store in r: r = (a * a) mod m - * - * a SP integer to square. - * m SP integer modulus. - * r SP integer result. - * returns MP_VAL when m is 0, MP_MEM when dynamic memory allocation fails, - * BAD_FUNC_ARG when a is to big and MP_OKAY otherwise. - */ -static int sp_sqrmod(sp_int* a, sp_int* m, sp_int* r) -{ - int err = MP_OKAY; - - /* Need extra digit during calculation. */ - if (a->used * 2 > (SP_INT_DIGITS - 1)) - err = MP_VAL; - - if (err == MP_OKAY) - err = sp_mul(a, a, r); - if (err == MP_OKAY) - err = sp_mod(r, m, r); + if (0 && (err == MP_OKAY)) { + sp_print(r, "rmul"); + } return err; } +/* END SP_MUL implementations. */ -#if defined(WOLFSSL_HAVE_SP_DH) || defined(WOLFSSL_KEY_GEN) /* Multiply a by b mod m and store in r: r = (a * b) mod m * - * a SP integer to multiply. - * b SP integer to multiply. - * m SP integer modulus. - * r SP integer result. - * returns MP_VAL when m is 0, MP_MEM when dynamic memory allocation fails and - * MP_OKAY otherwise. + * @param [in] a SP integer to multiply. + * @param [in] b SP integer to multiply. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b, m or r is NULL; m is 0; or a * b is too big for + * fixed data length. + * @return MP_MEM when dynamic memory allocation fails. */ int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) { @@ -1443,9 +7697,13 @@ int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) sp_int t[1]; #endif - /* Need extra digit during calculation. */ - if (a->used + b->used > (SP_INT_DIGITS - 1)) + if ((a == NULL) || (b == NULL) || (m == NULL) || (r == NULL)) { err = MP_VAL; + } + /* Need extra digit during calculation. */ + if ((err == MP_OKAY) && (a->used + b->used >= r->size)) { + err = MP_VAL; + } #ifdef WOLFSSL_SMALL_STACK if (err == MP_OKAY) { @@ -1455,6 +7713,9 @@ int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) } } #endif + if (err == MP_OKAY) { + err = sp_init(t); + } if (err == MP_OKAY) { err = sp_mul(a, b, t); } @@ -1463,233 +7724,25 @@ int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) } #ifdef WOLFSSL_SMALL_STACK - if (t != NULL) + if (t != NULL) { XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } #endif return err; } -#endif - -#ifdef WOLFSSL_SP_MOD_WORD_RP -/* Calculate the word w modulo the digit d into r: r = w mod d - * - * w SP integer word, dividend and result. - * d SP integer digit, modulus. - * - * returns MP_VAL when d is 0 and MP_OKAY otherwise. - */ -static WC_INLINE int sp_mod_word(sp_int_word *w, sp_int_digit d) { - sp_int_word x; - if (*w == 0) - return 0; - if (d == 0) - return MP_VAL; - - /* Russian Peasant algorithm for division, optimized: - * - * first, shift x leftward just enough to be greater than w/2. - * this can be done by counting the leading zeros of each, - * shifting so that x has one less leading zero, and then doing a - * final comparison. - * - */ -#ifdef __GNUC__ - { - int x_shift = ((int)__builtin_clzll(d) + (SP_WORD_SIZE - 1)); - if ((*w >> SP_WORD_SIZE) == 0) - x_shift -= -#if SP_WORD_SIZE == 64 - (int)__builtin_clzll((uint64_t)*w) -#elif SP_WORD_SIZE == 32 - (int)__builtin_clz((uint32_t)*w) -#else -#error unexpected SP_WORD_SIZE -#endif - + SP_WORD_SIZE; - else - x_shift -= -#if SP_WORD_SIZE == 64 - (int)__builtin_clzll((uint64_t)(*w >> SP_WORD_SIZE)) -#elif SP_WORD_SIZE == 32 - (int)__builtin_clz((uint32_t)(*w >> SP_WORD_SIZE)) -#else -#error unexpected SP_WORD_SIZE -#endif - ; - if (x_shift < 0) - x_shift = 0; - x = (sp_int_word)d << x_shift; - } - if (x <= (*w>>1)) - x <<= 1; -#else /* ! __GNUC__ */ - /* textbook logic */ - - x = (sp_int_word)d; - while (x <= (*w>>1)) - x <<= 1; -#endif /* __GNUC__ */ - - while (*w >= (sp_int_word)d) { - if (*w >= x) - *w -= x; - x >>= 1; - } - - return MP_OKAY; -} -#endif /* WOLFSSL_SP_MOD_WORD_RP */ - -/* Calculate a modulo the digit d into r: r = a mod d - * - * a SP integer, dividend. - * d SP integer digit, modulus. - * r SP integer digit, result. - * returns MP_VAL when d is 0 and MP_OKAY otherwise. - */ -static int sp_mod_d(sp_int* a, const sp_int_digit d, sp_int_digit* r) -{ - int err = MP_OKAY; - int i; - sp_int_word w = 0; - - if (d == 0) - err = MP_VAL; - - if (err == MP_OKAY) { - for (i = a->used - 1; i >= 0; i--) { - w = (w << SP_WORD_SIZE) | a->dp[i]; -#ifdef WOLFSSL_SP_MOD_WORD_RP - if (sp_mod_word(&w, d) == MP_VAL) { - err = MP_VAL; - break; - } -#else - { - sp_int_digit t = (sp_int_digit)(w / d); - w -= (sp_int_word)t * d; - } -#endif - } - - *r = (sp_int_digit)w; - } - - return err; -} - -/* Calculates the Greatest Common Denominator (GCD) of a and b into r. - * - * a SP integer operand. - * b SP integer operand. - * r SP integer result. - * returns MP_MEM when dynamic memory allocation fails and MP_OKAY otherwise. - */ -int sp_gcd(sp_int* a, sp_int* b, sp_int* r) -{ - int err = MP_OKAY; -#ifdef WOLFSSL_SMALL_STACK - sp_int* u = NULL; - sp_int* v; - sp_int* t; -#else - sp_int u[1], v[1], t[1]; -#endif - - if (sp_iszero(a)) - sp_copy(b, r); - else if (sp_iszero(b)) - sp_copy(a, r); - else { -#ifdef WOLFSSL_SMALL_STACK - u = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); - if (u == NULL) - err = MP_MEM; - else { - v = &u[1]; - t = &u[2]; - } -#endif - - if (err == MP_OKAY) { - sp_init(u); - sp_init(v); - sp_init(t); - - if (sp_cmp(a, b) != MP_LT) { - sp_copy(b, u); - /* First iteration - u = a, v = b */ - if (b->used == 1) { - err = sp_mod_d(a, b->dp[0], &v->dp[0]); - if (err == MP_OKAY) - v->used = (v->dp[0] != 0); - } - else - err = sp_mod(a, b, v); - } - else { - sp_copy(a, u); - /* First iteration - u = b, v = a */ - if (a->used == 1) { - err = sp_mod_d(b, a->dp[0], &v->dp[0]); - if (err == MP_OKAY) - v->used = (v->dp[0] != 0); - } - else - err = sp_mod(b, a, v); - } - } - - if (err == MP_OKAY) { - while (!sp_iszero(v)) { - if (v->used == 1) { - sp_mod_d(u, v->dp[0], &t->dp[0]); - t->used = (t->dp[0] != 0); - } - else - sp_mod(u, v, t); - sp_copy(v, u); - sp_copy(t, v); - } - sp_copy(u, r); - } - } - -#ifdef WOLFSSL_SMALL_STACK - if (u != NULL) - XFREE(u, NULL, DYNAMIC_TYPE_BIGINT); -#endif - - return err; -} - -/* Divides a by 2 and stores in r: r = a >> 1 - * - * a SP integer to divide. - * r SP integer result. - * returns MP_OKAY always. - */ -static int sp_div_2(sp_int* a, sp_int* r) -{ - int i; - - for (i = 0; i < a->used-1; i++) - r->dp[i] = (a->dp[i] >> 1) | (a->dp[i+1] << (SP_WORD_SIZE - 1)); - r->dp[i] = a->dp[i] >> 1; - r->used = i + 1; - sp_clamp(r); - - return MP_OKAY; -} - +#if defined(HAVE_ECC) || !defined(NO_DSA) || defined(OPENSSL_EXTRA) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) /* Calculates the multiplicative inverse in the field. * - * a SP integer to invert. - * m SP integer that is the modulus of the field. - * r SP integer result. - * returns MP_VAL when a or m is 0, MP_MEM when dynamic memory allocation fails - * and MP_OKAY otherwise. + * @param [in] a SP integer to find inverse of. + * @param [in] m SP integer this is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, m or r is NULL; a or m is zero; a and m are even or + * m is negative. + * @return MP_MEM when dynamic memory allocation fails. */ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) { @@ -1700,13 +7753,28 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) sp_int* b; sp_int* c; #else - sp_int u[1], v[1], b[1], c[1]; + sp_int u[1]; + sp_int v[1]; + sp_int b[1]; + sp_int c[1]; +#endif + + if ((a == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + +#ifdef WOLFSSL_SP_INT_NEGATIVE + if ((err == MP_OKAY) && (m->sign == MP_NEG)) { + err = MP_VAL; + } #endif #ifdef WOLFSSL_SMALL_STACK - u = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); - if (u == NULL) { - err = MP_MEM; + if (err == MP_OKAY) { + u = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); + if (u == NULL) { + err = MP_MEM; + } } #endif @@ -1718,17 +7786,25 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) #endif sp_init(v); - if (sp_cmp(a, m) != MP_LT) { + if (_sp_cmp_abs(a, m) != MP_LT) { err = sp_mod(a, m, v); a = v; } } +#ifdef WOLFSSL_SP_INT_NEGATIVE + if ((err == MP_OKAY) && (a->sign == MP_NEG)) { + /* Make 'a' positive */ + err = sp_add(m, a, v); + a = v; + } +#endif + /* 0 != n*m + 1 (+ve m), r*a mod 0 is always 0 (never 1) */ if ((err == MP_OKAY) && (sp_iszero(a) || sp_iszero(m))) { err = MP_VAL; } - /* r*2*x != n*2*y + 1 */ + /* r*2*x != n*2*y + 1 for integer x,y */ if ((err == MP_OKAY) && sp_iseven(a) && sp_iseven(m)) { err = MP_VAL; } @@ -1748,59 +7824,57 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) err = sp_mul(r, m, r); } if (err == MP_OKAY) { - sp_sub_d(r, 1, r); + _sp_sub_d(r, 1, r); sp_div(r, a, r, NULL); sp_sub(m, r, r); } } else { - if (err == MP_OKAY) { - sp_init(u); - sp_init(b); - sp_init(c); + sp_init(u); + sp_init(b); + sp_init(c); - sp_copy(m, u); - sp_copy(a, v); - sp_zero(b); - sp_set(c, 1); + sp_copy(m, u); + sp_copy(a, v); + _sp_zero(b); + sp_set(c, 1); - while (!sp_isone(v) && !sp_iszero(u)) { - if (sp_iseven(u)) { - sp_div_2(u, u); - if (sp_isodd(b)) { - sp_add(b, m, b); - } - sp_div_2(b, b); - } - else if (sp_iseven(v)) { - sp_div_2(v, v); - if (sp_isodd(c)) { - sp_add(c, m, c); - } - sp_div_2(c, c); - } - else if (sp_cmp(u, v) != MP_LT) { - sp_sub(u, v, u); - if (sp_cmp(b, c) == MP_LT) { - sp_add(b, m, b); - } - sp_sub(b, c, b); - } - else { - sp_sub(v, u, v); - if (sp_cmp(c, b) == MP_LT) { - sp_add(c, m, c); - } - sp_sub(c, b, c); + while (!sp_isone(v) && !sp_iszero(u)) { + if (sp_iseven(u)) { + sp_div_2(u, u); + if (sp_isodd(b)) { + sp_add(b, m, b); } + sp_div_2(b, b); } - if (sp_iszero(u)) { - err = MP_VAL; + else if (sp_iseven(v)) { + sp_div_2(v, v); + if (sp_isodd(c)) { + sp_add(c, m, c); + } + sp_div_2(c, c); + } + else if (_sp_cmp(u, v) != MP_LT) { + sp_sub(u, v, u); + if (_sp_cmp(b, c) == MP_LT) { + sp_add(b, m, b); + } + sp_sub(b, c, b); } else { - sp_copy(c, r); + sp_sub(v, u, v); + if (_sp_cmp(c, b) == MP_LT) { + sp_add(c, m, c); + } + sp_sub(c, b, c); } } + if (sp_iszero(u)) { + err = MP_VAL; + } + else { + sp_copy(c, r); + } } #ifdef WOLFSSL_SMALL_STACK @@ -1811,24 +7885,599 @@ int sp_invmod(sp_int* a, sp_int* m, sp_int* r) return err; } +#endif /* HAVE_ECC || !NO_DSA || OPENSSL_EXTRA || \ + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ -/* Calculates the Lowest Common Multiple (LCM) of a and b and stores in r. +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) + +#define CT_INV_MOD_PRE_CNT 8 + +/* Calculates the multiplicative inverse in the field - constant time. * - * a SP integer operand. - * b SP integer operand. - * r SP integer result. - * returns MP_MEM when dynamic memory allocation fails and MP_OKAY otherwise. + * Modulus (m) must be a prime and greater than 2. + * + * @param [in] a SP integer, Montogmery form, to find inverse of. + * @param [in] m SP integer this is the modulus. + * @param [out] r SP integer to hold result. + * @param [in] mp SP integer digit that is the bottom digit of inv(-m). + * + * @return MP_OKAY on success. + * @return MP_VAL when a, m or r is NULL; a is 0 or m is less than 3. + * @return MP_MEM when dynamic memory allocation fails. */ -int sp_lcm(sp_int* a, sp_int* b, sp_int* r) +int sp_invmod_mont_ct(sp_int* a, sp_int* m, sp_int* r, sp_int_digit mp) { - int err = MP_OKAY; + int err = MP_OKAY; + int i; + int j; #ifndef WOLFSSL_SMALL_STACK - sp_int t[2]; + sp_int t[1]; + sp_int e[1]; + sp_int pre[CT_INV_MOD_PRE_CNT]; #else - sp_int *t = NULL; + sp_int* t = NULL; + sp_int* e; + sp_int* pre; +#endif /* WOLFSSL_SMALL_STACK */ + + if ((a == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + + /* 0 != n*m + 1 (+ve m), r*a mod 0 is always 0 (never 1) */ + if ((err == MP_OKAY) && (sp_iszero(a) || sp_iszero(m) || + (m->used == 1 && m->dp[0] < 3))) { + err = MP_VAL; + } +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * (2 + CT_INV_MOD_PRE_CNT), NULL, + DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif /* WOLFSSL_SMALL_STACK */ + + if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + e = &t[1]; + pre = t + 2; +#endif /* WOLFSSL_SMALL_STACK */ + sp_init(t); + sp_init(e); + + sp_init(&pre[0]); + sp_copy(a, &pre[0]); + for (i = 1; (err == MP_OKAY) && (i < CT_INV_MOD_PRE_CNT); i++) { + sp_init(&pre[i]); + err = sp_sqr(&pre[i-1], &pre[i]); + if (err == MP_OKAY) { + err = _sp_mont_red(&pre[i], m, mp); + } + if (err == MP_OKAY) { + err = sp_mul(&pre[i], a, &pre[i]); + } + if (err == MP_OKAY) { + err = _sp_mont_red(&pre[i], m, mp); + } + } + } + + if (err == MP_OKAY) { + _sp_sub_d(m, 2, e); + for (i = sp_count_bits(e)-1, j = 0; i >= 0; i--, j++) { + if ((!sp_is_bit_set(e, i)) || (j == CT_INV_MOD_PRE_CNT)) { + break; + } + } + sp_copy(&pre[j-1], t); + for (j = 0; (err == MP_OKAY) && (i >= 0); i--) { + int set = sp_is_bit_set(e, i); + + if ((j == CT_INV_MOD_PRE_CNT) || ((!set) && j > 0)) { + err = sp_mul(t, &pre[j-1], t); + if (err == MP_OKAY) { + err = _sp_mont_red(t, m, mp); + } + j = 0; + } + if (err == MP_OKAY) { + err = sp_sqr(t, t); + if (err == MP_OKAY) { + err = _sp_mont_red(t, m, mp); + } + } + j += set; + } + } + if (err == MP_OKAY) { + if (j > 0) { + err = sp_mul(t, &pre[j-1], r); + if (err == MP_OKAY) { + err = _sp_mont_red(r, m, mp); + } + } + else { + sp_copy(t, r); + } + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif /* WOLFSSL_SMALL_STACK */ + return err; +} + +#endif /* WOLFSSL_SP_MATH_ALL && HAVE_ECC */ + + +/************************** + * Exponentiation functions + **************************/ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) +/* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * Process the exponent one bit at a time. + * Is constant time and can be cache attack resistant. + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] bits Number of bits in base to use. May be greater than + * count of bits in b. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ +static int _sp_exptmod_ex(sp_int* b, sp_int* e, int bits, sp_int* m, sp_int* r) +{ + int i; + int err = MP_OKAY; + int done = 0; + int j; + int y; + int seenTopBit = 0; +#ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; +#else +#ifdef WC_NO_CACHE_RESISTANT + sp_int t[2]; +#else + sp_int t[3]; +#endif #endif #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { +#ifdef WC_NO_CACHE_RESISTANT + t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); +#else + t = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); +#endif + if (t == NULL) { + err = MP_MEM; + } + } +#endif + if (err == MP_OKAY) { + sp_init(&t[0]); + sp_init(&t[1]); +#ifndef WC_NO_CACHE_RESISTANT + sp_init(&t[2]); +#endif + + /* Ensure base is less than exponent. */ + if (_sp_cmp(b, m) != MP_LT) { + err = sp_mod(b, m, &t[0]); + if ((err == MP_OKAY) && sp_iszero(t)) { + sp_set(r, 0); + done = 1; + } + } + else { + sp_copy(b, &t[0]); + } + } + + if ((!done) && (err == MP_OKAY)) { + /* t[0] is dummy value and t[1] is result */ + sp_copy(&t[0], &t[1]); + + for (i = bits - 1; (err == MP_OKAY) && (i >= 0); i--) { +#ifdef WC_NO_CACHE_RESISTANT + /* Square real result if seen the top bit. */ + err = sp_sqrmod(&t[seenTopBit], m, &t[seenTopBit]); + if (err == MP_OKAY) { + y = (e->dp[i >> SP_WORD_SHIFT] >> (i & SP_WORD_MASK)) & 1; + j = y & seenTopBit; + seenTopBit |= y; + /* Multiply real result if bit is set and seen the top bit. */ + err = sp_mulmod(&t[j], b, m, &t[j]); + } +#else + /* Square real result if seen the top bit. */ + sp_copy((sp_int*)(((size_t)&t[0] & sp_off_on_addr[seenTopBit^1]) + + ((size_t)&t[1] & sp_off_on_addr[seenTopBit ])), + &t[2]); + err = sp_sqrmod(&t[2], m, &t[2]); + sp_copy(&t[2], + (sp_int*)(((size_t)&t[0] & sp_off_on_addr[seenTopBit^1]) + + ((size_t)&t[1] & sp_off_on_addr[seenTopBit ]))); + if (err == MP_OKAY) { + y = (e->dp[i >> SP_WORD_SHIFT] >> (i & SP_WORD_MASK)) & 1; + j = y & seenTopBit; + seenTopBit |= y; + /* Multiply real result if bit is set and seen the top bit. */ + sp_copy((sp_int*)(((size_t)&t[0] & sp_off_on_addr[j^1]) + + ((size_t)&t[1] & sp_off_on_addr[j ])), + &t[2]); + err = sp_mulmod(&t[2], b, m, &t[2]); + sp_copy(&t[2], + (sp_int*)(((size_t)&t[0] & sp_off_on_addr[j^1]) + + ((size_t)&t[1] & sp_off_on_addr[j ]))); + } +#endif + } + } + if ((!done) && (err == MP_OKAY)) { + sp_copy(&t[1], r); + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH */ + +#ifdef WOLFSSL_SP_MATH_ALL +#ifndef WC_NO_HARDEN +#if !defined(WC_NO_CACHE_RESISTANT) +/* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * Process the exponent one bit at a time with base in montgomery form. + * Is constant time and cache attack resistant. + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] bits Number of bits in base to use. May be greater than + * count of bits in b. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ +static int _sp_exptmod_mont_ex(sp_int* b, sp_int* e, int bits, sp_int* m, + sp_int* r) +{ + int i; + int err = MP_OKAY; + int done = 0; + int j; + int y; + int seenTopBit = 0; +#ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; +#else + sp_int t[4]; +#endif + sp_int_digit mp; + +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif + if (err == MP_OKAY) { + sp_init_multi(&t[0], &t[1], &t[2], &t[3], NULL, NULL); + + /* Ensure base is less than exponent. */ + if (_sp_cmp(b, m) != MP_LT) { + err = sp_mod(b, m, &t[0]); + if ((err == MP_OKAY) && sp_iszero(&t[0])) { + sp_set(r, 0); + done = 1; + } + } + else { + sp_copy(b, &t[0]); + } + } + + + if ((!done) && (err == MP_OKAY)) { + err = sp_mont_setup(m, &mp); + if (err == MP_OKAY) { + err = sp_mont_norm(&t[1], m); + } + if (err == MP_OKAY) { + /* Convert to montgomery form. */ + err = sp_mulmod(&t[0], &t[1], m, &t[0]); + } + if (err == MP_OKAY) { + /* t[0] is fake working value and t[1] is real working value. */ + sp_copy(&t[0], &t[1]); + /* Montgomert form of base to multiply by. */ + sp_copy(&t[0], &t[2]); + } + + for (i = bits - 1; (err == MP_OKAY) && (i >= 0); i--) { + /* Square real working value if seen the top bit. */ + sp_copy((sp_int*)(((size_t)&t[0] & sp_off_on_addr[seenTopBit^1]) + + ((size_t)&t[1] & sp_off_on_addr[seenTopBit ])), + &t[3]); + err = sp_sqr(&t[3], &t[3]); + if (err == MP_OKAY) { + err = _sp_mont_red(&t[3], m, mp); + } + sp_copy(&t[3], + (sp_int*)(((size_t)&t[0] & sp_off_on_addr[seenTopBit^1]) + + ((size_t)&t[1] & sp_off_on_addr[seenTopBit ]))); + if (err == MP_OKAY) { + y = (e->dp[i >> SP_WORD_SHIFT] >> (i & SP_WORD_MASK)) & 1; + j = y & seenTopBit; + seenTopBit |= y; + /* Multiply real value if bit is set and seen the top bit. */ + sp_copy((sp_int*)(((size_t)&t[0] & sp_off_on_addr[j^1]) + + ((size_t)&t[1] & sp_off_on_addr[j ])), + &t[3]); + err = sp_mul(&t[3], &t[2], &t[3]); + if (err == MP_OKAY) { + err = _sp_mont_red(&t[3], m, mp); + } + sp_copy(&t[3], + (sp_int*)(((size_t)&t[0] & sp_off_on_addr[j^1]) + + ((size_t)&t[1] & sp_off_on_addr[j ]))); + } + } + if (err == MP_OKAY) { + /* Convert from montgomery form. */ + err = _sp_mont_red(&t[1], m, mp); + /* Reduction implementation returns number to range < m. */ + } + } + if ((!done) && (err == MP_OKAY)) { + sp_copy(&t[1], r); + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif + return err; +} +#else +/* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * Creates a window of precalculated exponents with base in montgomery form. + * Is constant time but NOT cache attack resistant. + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] bits Number of bits in base to use. May be greater than + * count of bits in b. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ +static int _sp_exptmod_mont_ex(sp_int* b, sp_int* e, int bits, sp_int* m, + sp_int* r) +{ + int i; + int j; + int c; + int y; + int winBits; + int preCnt; + int err = MP_OKAY; + int done = 0; + sp_int* t = NULL; + sp_int* tr = NULL; + sp_int_digit mp; + sp_int_digit n; + sp_int_digit mask; + + if (bits > 450) { + winBits = 6; + } + else if (bits <= 21) { + winBits = 1; + } + else if (bits <= 36) { + winBits = 3; + } + else if (bits <= 140) { + winBits = 4; + } + else { + winBits = 5; + } + preCnt = 1 << winBits; + mask = preCnt - 1; + + if (err == MP_OKAY) { + /* Allocate memory for window. */ + t = (sp_int*)XMALLOC(sizeof(sp_int) * (preCnt + 1), NULL, + DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + + if (err == MP_OKAY) { + /* Initialize window numbers and temporary result. */ + tr = t + preCnt; + for (i = 0; i < preCnt; i++) { + sp_init(&t[i]); + } + sp_init(tr); + + /* Ensure base is less than exponent. */ + if (_sp_cmp(b, m) != MP_LT) { + err = sp_mod(b, m, &t[1]); + if ((err == MP_OKAY) && sp_iszero(&t[1])) { + sp_set(r, 0); + done = 1; + } + } + else { + sp_copy(b, &t[1]); + } + } + + if ((!done) && (err == MP_OKAY)) { + err = sp_mont_setup(m, &mp); + if (err == MP_OKAY) { + /* Norm value is 1 in montgomery form. */ + err = sp_mont_norm(&t[0], m); + } + if (err == MP_OKAY) { + /* Convert base to montgomery form. */ + err = sp_mulmod(&t[1], &t[0], m, &t[1]); + } + + /* Pre-calculate values */ + for (i = 2; (i < preCnt) && (err == MP_OKAY); i++) { + if ((i & 1) == 0) { + err = sp_sqr(&t[i/2], &t[i]); + } + else { + err = sp_mul(&t[i-1], &t[1], &t[i]); + } + if (err == MP_OKAY) { + err = _sp_mont_red(&t[i], m, mp); + } + } + + if (err == MP_OKAY) { + /* Bits from the top that - possibly left over. */ + i = (bits - 1) >> SP_WORD_SHIFT; + n = e->dp[i--]; + c = bits & (SP_WORD_SIZE - 1); + if (c == 0) { + c = SP_WORD_SIZE; + } + c -= bits % winBits; + y = (int)(n >> c); + n <<= SP_WORD_SIZE - c; + /* Copy window number for top bits. */ + sp_copy(&t[y], tr); + for (; (i >= 0) || (c >= winBits); ) { + if (c == 0) { + /* Bits up to end of digit */ + n = e->dp[i--]; + y = (int)(n >> (SP_WORD_SIZE - winBits)); + n <<= winBits; + c = SP_WORD_SIZE - winBits; + } + else if (c < winBits) { + /* Bits to end of digit and part of next */ + y = (int)(n >> (SP_WORD_SIZE - winBits)); + n = e->dp[i--]; + c = winBits - c; + y |= (int)(n >> (SP_WORD_SIZE - c)); + n <<= c; + c = SP_WORD_SIZE - c; + } + else { + /* Bits from middle of digit */ + y = (int)((n >> (SP_WORD_SIZE - winBits)) & mask); + n <<= winBits; + c -= winBits; + } + + /* Square for number of bits in window. */ + for (j = 0; (j < winBits) && (err == MP_OKAY); j++) { + err = sp_sqr(tr, tr); + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + } + /* Multiply by window number for next set of bits. */ + if (err == MP_OKAY) { + err = sp_mul(tr, &t[y], tr); + } + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + } + } + + if (err == MP_OKAY) { + /* Convert from montgomery form. */ + err = _sp_mont_red(tr, m, mp); + /* Reduction implementation returns number to range < m. */ + } + } + if ((!done) && (err == MP_OKAY)) { + sp_copy(tr, r); + } + + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + return err; +} +#endif /* !WC_NO_CACHE_RESISTANT */ +#endif /* !WC_NO_HARDEN */ + +#if SP_WORD_SIZE <= 16 + #define EXP2_WINSIZE 2 +#elif SP_WORD_SIZE <= 32 + #define EXP2_WINSIZE 3 +#elif SP_WORD_SIZE <= 64 + #define EXP2_WINSIZE 4 +#elif SP_WORD_SIZE <= 128 + #define EXP2_WINSIZE 5 +#endif + +/* Internal. Exponentiates 2 to the power of e modulo m into r: r = 2 ^ e mod m + * Is constant time and cache attack resistant. + * + * @param [in] e SP integer that is the exponent. + * @param [in] digits Number of digits in base to use. May be greater than + * count of bits in b. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ +static int _sp_exptmod_base_2(sp_int* e, int digits, sp_int* m, sp_int* r) +{ + int i; + int j; + int c; + int y; + int err = MP_OKAY; +#ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + sp_int* tr = NULL; +#else + sp_int t[1]; + sp_int tr[1]; +#endif + sp_int_digit mp = 0, n; + + if (0) { + sp_print_int(2, "a"); + sp_print(e, "b"); + sp_print(m, "m"); + } + +#ifdef WOLFSSL_SMALL_STACK + /* Allocate memory for window. */ t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); if (t == NULL) { err = MP_MEM; @@ -1836,40 +8485,144 @@ int sp_lcm(sp_int* a, sp_int* b, sp_int* r) #endif if (err == MP_OKAY) { - sp_init(&t[0]); - sp_init(&t[1]); - err = sp_gcd(a, b, &t[0]); - if (err == MP_OKAY) { - if (sp_cmp(a, b) == MP_GT) { - err = sp_div(a, &t[0], &t[1], NULL); - if (err == MP_OKAY) - err = sp_mul(b, &t[1], r); +#ifdef WOLFSSL_SMALL_STACK + tr = t + 1; +#endif + sp_init(t); + sp_init(tr); + + if (m->used > 1) { + err = sp_mont_setup(m, &mp); + if (err == MP_OKAY) { + /* Norm value is 1 in montgomery form. */ + err = sp_mont_norm(tr, m); } - else { - err = sp_div(b, &t[0], &t[1], NULL); - if (err == MP_OKAY) - err = sp_mul(a, &t[1], r); + if (err == MP_OKAY) { + err = sp_mul_2d(m, 1 << EXP2_WINSIZE, t); } } + else { + err = sp_set(tr, 1); + } + + if (err == MP_OKAY) { + /* Bits from the top. */ + i = digits - 1; + n = e->dp[i--]; + c = SP_WORD_SIZE; +#if (EXP2_WINSIZE != 1) && (EXP2_WINSIZE != 2) && (EXP2_WINSIZE != 4) + c -= (digits * SP_WORD_SIZE) % EXP2_WINSIZE; + if (c != SP_WORD_SIZE) { + y = (int)(n >> c); + n <<= SP_WORD_SIZE - c; + } + else +#endif + { + y = 0; + } + + /* Multiply montgomery representation of 1 by 2 ^ top */ + err = sp_mul_2d(tr, y, tr); + } + if ((err == MP_OKAY) && (m->used > 1)) { + err = sp_add(tr, t, tr); + } + if (err == MP_OKAY) { + err = sp_mod(tr, m, tr); + } + if (err == MP_OKAY) { + for (; (i >= 0) || (c >= EXP2_WINSIZE); ) { + if (c == 0) { + /* Bits up to end of digit */ + n = e->dp[i--]; + y = (int)(n >> (SP_WORD_SIZE - EXP2_WINSIZE)); + n <<= EXP2_WINSIZE; + c = SP_WORD_SIZE - EXP2_WINSIZE; + } +#if (EXP2_WINSIZE != 1) && (EXP2_WINSIZE != 2) && (EXP2_WINSIZE != 4) + else if (c < EXP2_WINSIZE) { + /* Bits to end of digit and part of next */ + y = (int)(n >> (SP_WORD_SIZE - EXP2_WINSIZE)); + n = e->dp[i--]; + c = EXP2_WINSIZE - c; + y |= (int)(n >> (SP_WORD_SIZE - c)); + n <<= c; + c = SP_WORD_SIZE - c; + } +#endif + else { + /* Bits from middle of digit */ + y = (int)((n >> (SP_WORD_SIZE - EXP2_WINSIZE)) & + ((1 << EXP2_WINSIZE) - 1)); + n <<= EXP2_WINSIZE; + c -= EXP2_WINSIZE; + } + + /* Square for number of bits in window. */ + for (j = 0; (j < EXP2_WINSIZE) && (err == MP_OKAY); j++) { + err = sp_sqr(tr, tr); + if ((err == MP_OKAY) && (m->used > 1)) { + err = _sp_mont_red(tr, m, mp); + } + else { + err = sp_mod(tr, m, tr); + } + } + + if (err == MP_OKAY) { + /* then multiply by 2^y */ + err = sp_mul_2d(tr, y, tr); + } + if ((err == MP_OKAY) && (m->used > 1)) { + /* Add in value to make mod operation take same time */ + err = sp_add(tr, t, tr); + } + if (err == MP_OKAY) { + err = sp_mod(tr, m, tr); + } + } + } + + if ((err == MP_OKAY) && (m->used > 1)) { + /* Convert from montgomery form. */ + err = _sp_mont_red(tr, m, mp); + /* Reduction implementation returns number to range < m. */ + } + } + if (err == MP_OKAY) { + sp_copy(tr, r); } #ifdef WOLFSSL_SMALL_STACK - if (t != NULL) + if (t != NULL) { XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } #endif + + if (0) { + sp_print(r, "rme"); + } + return err; } +#endif /* WOLFSSL_SP_MATH_ALL */ +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) /* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m * - * b SP integer base. - * e SP integer exponent. - * m SP integer modulus. - * r SP integer result. - * returns MP_VAL when m is not 1024, 2048, 1536 or 3072 bits and otherwise - * MP_OKAY. + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] bits Number of bits in base to use. May be greater than + * count of bits in b. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when b, e, m or r is NULL; or m <= 0 or e is negative. + * @return MP_MEM when dynamic memory allocation fails. */ -int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) +int sp_exptmod_ex(sp_int* b, sp_int* e, int digits, sp_int* m, sp_int* r) { int err = MP_OKAY; int done = 0; @@ -1877,9 +8630,27 @@ int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) int bBits = sp_count_bits(b); int eBits = sp_count_bits(e); - if (sp_iszero(m)) { + if ((b == NULL) || (e == NULL) || (m == NULL) || (r == NULL)) { err = MP_VAL; } + + if (0 && (err == MP_OKAY)) { + sp_print(b, "a"); + sp_print(e, "b"); + sp_print(m, "m"); + } + + if (err != MP_OKAY) { + } + /* Handle special cases. */ + else if (sp_iszero(m)) { + err = MP_VAL; + } +#ifdef WOLFSSL_SP_INT_NEGATIVE + else if ((e->sign == MP_NEG) || (m->sign == MP_NEG)) { + err = MP_VAL; + } +#endif else if (sp_isone(m)) { sp_set(r, 0); done = 1; @@ -1893,12 +8664,15 @@ int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) done = 1; } /* Ensure SP integers have space for intermediate values. */ - else if (m->used * 2 > (SP_INT_DIGITS - 1)) { - err = BAD_FUNC_ARG; + else if (m->used * 2 >= r->size) { + err = MP_VAL; } - if (!done && (err == MP_OKAY)) { -#ifndef WOLFSSL_SP_NO_2048 + if ((!done) && (err == MP_OKAY)) { + /* Use code optimized for specific sizes if possible */ +#if defined(WOLFSSL_SP_MATH_ALL) && (defined(WOLFSSL_HAVE_SP_RSA) || \ + defined(WOLFSSL_HAVE_SP_DH)) + #ifndef WOLFSSL_SP_NO_2048 if ((mBits == 1024) && sp_isodd(m) && (bBits <= 1024) && (eBits <= 1024)) { err = sp_ModExp_1024(b, e, m, r); @@ -1910,8 +8684,8 @@ int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) done = 1; } else -#endif -#ifndef WOLFSSL_SP_NO_3072 + #endif + #ifndef WOLFSSL_SP_NO_3072 if ((mBits == 1536) && sp_isodd(m) && (bBits <= 1536) && (eBits <= 1536)) { err = sp_ModExp_1536(b, e, m, r); @@ -1923,72 +8697,40 @@ int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) done = 1; } else -#endif -#ifdef WOLFSSL_SP_4096 + #endif + #ifdef WOLFSSL_SP_4096 if ((mBits == 4096) && sp_isodd(m) && (bBits <= 4096) && (eBits <= 4096)) { err = sp_ModExp_4096(b, e, m, r); done = 1; } else + #endif #endif { } } -#if defined(WOLFSSL_HAVE_SP_DH) && defined(WOLFSSL_KEY_GEN) - if (!done && (err == MP_OKAY)) { - int i; - - #ifdef WOLFSSL_SMALL_STACK - sp_int* t = NULL; +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) +#if defined(WOLFSSL_SP_MATH_ALL) + if ((!done) && (err == MP_OKAY) && (b->used == 1) && (b->dp[0] == 2)) { + /* Use the generic base 2 implementation. */ + err = _sp_exptmod_base_2(e, digits, m, r); + } + else if ((!done) && (err == MP_OKAY) && (m->used > 1)) { + #ifndef WC_NO_HARDEN + err = _sp_exptmod_mont_ex(b, e, digits * SP_WORD_SIZE, m, r); #else - sp_int t[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK - if (!done && (err == MP_OKAY)) { - t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); - if (t == NULL) { - err = MP_MEM; - } - } - #endif - if (!done && (err == MP_OKAY)) { - sp_init(t); - - if (sp_cmp(b, m) != MP_LT) { - err = sp_mod(b, m, t); - if (err == MP_OKAY && sp_iszero(t)) { - sp_set(r, 0); - done = 1; - } - } - else { - sp_copy(b, t); - } - - if (!done && (err == MP_OKAY)) { - for (i = eBits-2; err == MP_OKAY && i >= 0; i--) { - err = sp_sqrmod(t, m, t); - if (err == MP_OKAY && (e->dp[i / SP_WORD_SIZE] >> - (i % SP_WORD_SIZE)) & 1) { - err = sp_mulmod(t, b, m, t); - } - } - } - } - if (!done && (err == MP_OKAY)) { - sp_copy(t, r); - } - - #ifdef WOLFSSL_SMALL_STACK - if (t != NULL) { - XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); - } + err = sp_exptmod_nct(b, e, m, r); #endif } + else +#endif + if ((!done) && (err == MP_OKAY)) { + /* Otherwise use the generic implementation. */ + err = _sp_exptmod_ex(b, e, digits * SP_WORD_SIZE, m, r); + } #else - if (!done && (err == MP_OKAY)) { + if ((!done) && (err == MP_OKAY)) { err = MP_VAL; } #endif @@ -1996,49 +8738,4332 @@ int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) (void)mBits; (void)bBits; (void)eBits; + (void)digits; + + if (0 && (err == MP_OKAY)) { + sp_print(r, "rme"); + } + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) +/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when b, e, m or r is NULL; or m <= 0 or e is negative. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r) +{ + int err = MP_OKAY; + + if ((b == NULL) || (e == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + err = sp_exptmod_ex(b, e, e->used, m, r); + } + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH */ + +#ifdef WOLFSSL_SP_MATH_ALL +#ifndef WOLFSSL_SP_SMALL +/* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * Creates a window of precalculated exponents with base in montgomery form. + * Sliding window and is NOT constant time. + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] bits Number of bits in base to use. May be greater than + * count of bits in b. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ +static int _sp_exptmod_nct(sp_int* b, sp_int* e, sp_int* m, sp_int* r) +{ + int i; + int j; + int c; + int y; + int bits; + int winBits; + int preCnt; + int err = MP_OKAY; + int done = 0; + sp_int* t = NULL; + sp_int* tr = NULL; + sp_int* bm = NULL; + sp_int_digit mp; + sp_int_digit n; + sp_int_digit mask; + + bits = sp_count_bits(e); + + if (bits > 450) { + winBits = 6; + } + else if (bits <= 21) { + winBits = 1; + } + else if (bits <= 36) { + winBits = 3; + } + else if (bits <= 140) { + winBits = 4; + } + else { + winBits = 5; + } + preCnt = 1 << (winBits - 1); + mask = preCnt - 1; + + if (err == MP_OKAY) { + /* Allocate memory for window. */ + t = (sp_int*)XMALLOC(sizeof(sp_int) * (preCnt + 2), NULL, + DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + + if (err == MP_OKAY) { + /* Initialize window numbers and temporary result. */ + tr = t + preCnt; + bm = t + preCnt + 1; + for (i = 0; i < preCnt; i++) { + sp_init(&t[i]); + } + sp_init(tr); + sp_init(bm); + + /* Ensure base is less than exponent. */ + if (_sp_cmp(b, m) != MP_LT) { + err = sp_mod(b, m, bm); + if ((err == MP_OKAY) && sp_iszero(bm)) { + sp_set(r, 0); + done = 1; + } + } + else { + sp_copy(b, bm); + } + } + + if ((!done) && (err == MP_OKAY)) { + err = sp_mont_setup(m, &mp); + if (err == MP_OKAY) { + err = sp_mont_norm(&t[0], m); + } + if (err == MP_OKAY) { + err = sp_mulmod(bm, &t[0], m, bm); + } + if (err == MP_OKAY) { + err = sp_copy(bm, &t[0]); + } + for (i = 1; (i < winBits) && (err == MP_OKAY); i++) { + err = sp_sqr(&t[0], &t[0]); + if (err == MP_OKAY) { + err = _sp_mont_red(&t[0], m, mp); + } + } + for (i = 1; (i < preCnt) && (err == MP_OKAY); i++) { + err = sp_mul(&t[i-1], bm, &t[i]); + if (err == MP_OKAY) { + err = _sp_mont_red(&t[i], m, mp); + } + } + + if (err == MP_OKAY) { + /* Find the top bit. */ + i = (bits - 1) >> SP_WORD_SHIFT; + n = e->dp[i--]; + c = bits % SP_WORD_SIZE; + if (c == 0) { + c = SP_WORD_SIZE; + } + /* Put top bit at highest offset in digit. */ + n <<= SP_WORD_SIZE - c; + + if (bits >= winBits) { + /* Top bit set. Copy from window. */ + if (c < winBits) { + /* Bits to end of digit and part of next */ + y = (int)((n >> (SP_WORD_SIZE - winBits)) & mask); + n = e->dp[i--]; + c = winBits - c; + y |= (int)(n >> (SP_WORD_SIZE - c)); + n <<= c; + c = SP_WORD_SIZE - c; + } + else { + /* Bits from middle of digit */ + y = (int)((n >> (SP_WORD_SIZE - winBits)) & mask); + n <<= winBits; + c -= winBits; + } + sp_copy(&t[y], tr); + } + else { + /* 1 in Montgomery form. */ + err = sp_mont_norm(tr, m); + } + while (err == MP_OKAY) { + /* Sqaure until we find bit that is 1 or there's less than a + * window of bits left. + */ + while ((i >= 0) || (c >= winBits)) { + sp_digit n2 = n; + int c2 = c; + int i2 = i; + + /* Make sure n2 has bits from the right digit. */ + if (c2 == 0) { + n2 = e->dp[i2--]; + c2 = SP_WORD_SIZE; + } + /* Mask off the next bit. */ + y = (int)((n2 >> (SP_WORD_SIZE - 1)) & 1); + if (y == 1) { + break; + } + + /* Square and update position. */ + err = sp_sqr(tr, tr); + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + n = n2 << 1; + c = c2 - 1; + i = i2; + } + + if (err == MP_OKAY) { + /* Check we have enough bits left for a window. */ + if ((i < 0) && (c < winBits)) { + break; + } + + if (c == 0) { + /* Bits up to end of digit */ + n = e->dp[i--]; + y = (int)(n >> (SP_WORD_SIZE - winBits)); + n <<= winBits; + c = SP_WORD_SIZE - winBits; + } + else if (c < winBits) { + /* Bits to end of digit and part of next */ + y = (int)(n >> (SP_WORD_SIZE - winBits)); + n = e->dp[i--]; + c = winBits - c; + y |= (int)(n >> (SP_WORD_SIZE - c)); + n <<= c; + c = SP_WORD_SIZE - c; + } + else { + /* Bits from middle of digit */ + y = (int)(n >> (SP_WORD_SIZE - winBits)); + n <<= winBits; + c -= winBits; + } + y &= mask; + } + + /* Square for number of bits in window. */ + for (j = 0; (j < winBits) && (err == MP_OKAY); j++) { + err = sp_sqr(tr, tr); + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + } + /* Multiply by window number for next set of bits. */ + if (err == MP_OKAY) { + err = sp_mul(tr, &t[y], tr); + } + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + } + if ((err == MP_OKAY) && (c > 0)) { + /* Handle remaining bits. + * Window values have top bit set and can't be used. */ + n = e->dp[0]; + for (--c; (err == MP_OKAY) && (c >= 0); c--) { + err = sp_sqr(tr, tr); + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + if ((err == MP_OKAY) && ((n >> c) & 1)) { + err = sp_mul(tr, bm, tr); + if (err == MP_OKAY) { + err = _sp_mont_red(tr, m, mp); + } + } + } + } + } + + if (err == MP_OKAY) { + /* Convert from montgomery form. */ + err = _sp_mont_red(tr, m, mp); + /* Reduction implementation returns number to range < m. */ + } + } + if ((!done) && (err == MP_OKAY)) { + sp_copy(tr, r); + } + + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + return err; +} +#else +/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * Non-constant time implementation. + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when b, e, m or r is NULL; or m <= 0 or e is negative. + * @return MP_MEM when dynamic memory allocation fails. + */ +static int _sp_exptmod_nct(sp_int* b, sp_int* e, sp_int* m, sp_int* r) +{ + int i; + int err = MP_OKAY; + int done = 0; + int y; + int bits = sp_count_bits(e); +#ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; +#else + sp_int t[2]; +#endif + sp_int_digit mp; + +#ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } +#endif + + if (err == MP_OKAY) { + sp_init(&t[0]); + sp_init(&t[1]); + + /* Ensure base is less than exponent. */ + if (_sp_cmp(b, m) != MP_LT) { + err = sp_mod(b, m, &t[0]); + if ((err == MP_OKAY) && sp_iszero(&t[0])) { + sp_set(r, 0); + done = 1; + } + } + else { + sp_copy(b, &t[0]); + } + } + + if ((!done) && (err == MP_OKAY)) { + err = sp_mont_setup(m, &mp); + if (err == MP_OKAY) { + err = sp_mont_norm(&t[1], m); + } + if (err == MP_OKAY) { + /* Convert to montgomery form. */ + err = sp_mulmod(&t[0], &t[1], m, &t[0]); + } + if (err == MP_OKAY) { + /* Montgomert form of base to multiply by. */ + sp_copy(&t[0], &t[1]); + } + + for (i = bits - 2; (err == MP_OKAY) && (i >= 0); i--) { + err = sp_sqr(&t[0], &t[0]); + if (err == MP_OKAY) { + err = _sp_mont_red(&t[0], m, mp); + } + if (err == MP_OKAY) { + y = (e->dp[i >> SP_WORD_SHIFT] >> (i & SP_WORD_MASK)) & 1; + if (y != 0) { + err = sp_mul(&t[0], &t[1], &t[0]); + if (err == MP_OKAY) { + err = _sp_mont_red(&t[0], m, mp); + } + } + } + } + if (err == MP_OKAY) { + /* Convert from montgomery form. */ + err = _sp_mont_red(&t[0], m, mp); + /* Reduction implementation returns number to range < m. */ + } + } + if ((!done) && (err == MP_OKAY)) { + sp_copy(&t[0], r); + } + +#ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } +#endif + return err; +} +#endif /* WOLFSSL_SP_SMALL */ + +/* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m + * Non-constant time implementation. + * + * @param [in] b SP integer that is the base. + * @param [in] e SP integer that is the exponent. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when b, e, m or r is NULL; or m <= 0 or e is negative. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_exptmod_nct(sp_int* b, sp_int* e, sp_int* m, sp_int* r) +{ + int err = MP_OKAY; + + if ((b == NULL) || (e == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + + if (0 && (err == MP_OKAY)) { + sp_print(b, "a"); + sp_print(e, "b"); + sp_print(m, "m"); + } + + if (err != MP_OKAY) { + } + /* Handle special cases. */ + else if (sp_iszero(m)) { + err = MP_VAL; + } +#ifdef WOLFSSL_SP_INT_NEGATIVE + else if ((e->sign == MP_NEG) || (m->sign == MP_NEG)) { + err = MP_VAL; + } +#endif + else if (sp_isone(m)) { + sp_set(r, 0); + } + else if (sp_iszero(e)) { + sp_set(r, 1); + } + else if (sp_iszero(b)) { + sp_set(r, 0); + } + /* Ensure SP integers have space for intermediate values. */ + else if (m->used * 2 >= r->size) { + err = MP_VAL; + } + else { + err = _sp_exptmod_nct(b, e, m, r); + } + + if (0 && (err == MP_OKAY)) { + sp_print(r, "rme"); + } return err; } +#endif /* WOLFSSL_SP_MATH_ALL */ +/*************** + * 2^e functions + ***************/ -/* Number of entries in array of number of least significant zero bits. */ -#define SP_LNZ_CNT 16 -/* Number of bits the array checks. */ -#define SP_LNZ_BITS 4 -/* Mask to apply to check with array. */ -#define SP_LNZ_MASK 0xf -/* Number of least significant zero bits in first SP_LNZ_CNT numbers. */ -static const int lnz[SP_LNZ_CNT] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Count the number of least significant zero bits. +#ifdef WOLFSSL_SP_MATH_ALL +/* Divide by 2^e: r = a >> e and rem = bits shifted out * - * a Number to check - * returns the count of least significant zero bits. + * @param [in] a SP integer to divide. + * @param [in] e Exponent bits (dividing by 2^e). + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer to hold result. + * @param [out] rem SP integer to hold remainder. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL. */ -static int sp_cnt_lsb(sp_int* a) +int sp_div_2d(sp_int* a, int e, sp_int* r, sp_int* rem) { - int i, j; - int cnt = 0; - int bc = 0; + int err = MP_OKAY; - if (!sp_iszero(a)) { - for (i = 0; i < a->used && a->dp[i] == 0; i++, cnt += SP_WORD_SIZE) { + if (a == NULL) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + int remBits = sp_count_bits(a) - e; + + if (remBits <= 0) { + /* Shifting down by more bits than in number. */ + sp_set(r, 0); + sp_copy(a, rem); } - - for (j = 0; j < SP_WORD_SIZE; j += SP_LNZ_BITS) { - bc = lnz[(a->dp[i] >> j) & SP_LNZ_MASK]; - if (bc != 4) { - bc += cnt + j; - break; + else { + if (rem != NULL) { + /* Copy a in to remainder. */ + sp_copy(a, rem); + } + /* Shift a down by into result. */ + sp_rshb(a, e, r); + if (rem != NULL) { + /* Set used and mask off top digit of remainder. */ + rem->used = (e + SP_WORD_SIZE - 1) >> SP_WORD_SHIFT; + e &= SP_WORD_MASK; + if (e > 0) { + rem->dp[rem->used - 1] &= (1 << e) - 1; + } + sp_clamp(rem); } } } - return bc; + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* The bottom e bits: r = a & ((1 << e) - 1) + * + * @param [in] a SP integer to reduce. + * @param [in] e Modulus bits (modulus equals 2^e). + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL. + */ +int sp_mod_2d(sp_int* a, int e, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + int digits = (e + SP_WORD_SIZE - 1) >> SP_WORD_SHIFT; + if (a != r) { + XMEMCPY(r->dp, a->dp, digits * sizeof(sp_int_digit)); + #ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = a->sign; + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + } + /* Set used and mask off top digit of result. */ + r->used = digits; + e &= SP_WORD_MASK; + if (e > 0) { + r->dp[r->used - 1] &= ((sp_int_digit)1 << e) - 1; + } + sp_clamp(r); + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* Multiply by 2^e: r = a << e + * + * @param [in] a SP integer to multiply. + * @param [in] e Multiplier bits (multiplier equals 2^e). + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL, or result is too big for fixed data + * length. + */ +int sp_mul_2d(sp_int* a, int e, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } + + if ((err == MP_OKAY) && (sp_count_bits(a) + e > r->size * SP_WORD_SIZE)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + /* Copy a into r as left shift function works on the number. */ + if (a != r) { + sp_copy(a, r); + } + + if (0) { + sp_print(a, "a"); + sp_print_int(e, "n"); + } + err = sp_lshb(r, e); + if (0) { + sp_print(r, "rsl"); + } + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + +/* START SP_SQR implementations */ +/* This code is generated. + * To generate: + * cd scripts/sp/sp_int + * ./gen.sh + * File sp_sqr.c contains code. + */ + +#if !defined(WOLFSSL_SP_MATH) || !defined(WOLFSSL_SP_SMALL) +#ifdef SQR_MUL_ASM + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + int i; + int j; + int k; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + if ((err == MP_OKAY) && (a->used > 1)) { + sp_int_digit l, h, o; + + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + h = 0; + o = 0; + for (k = 1; k < (a->used + 1) / 2; k++) { + i = k; + j = k - 1; + for (; (j >= 0); i++, j--) { + SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]); + } + t->dp[k * 2 - 1] = l; + l = h; + h = o; + o = 0; + + SP_ASM_SQR_ADD(l, h, o, a->dp[k]); + i = k + 1; + j = k - 1; + for (; (j >= 0); i++, j--) { + SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]); + } + t->dp[k * 2] = l; + l = h; + h = o; + o = 0; + } + for (; k < a->used; k++) { + i = k; + j = k - 1; + for (; (i < a->used); i++, j--) { + SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]); + } + t->dp[k * 2 - 1] = l; + l = h; + h = o; + o = 0; + + SP_ASM_SQR_ADD(l, h, o, a->dp[k]); + i = k + 1; + j = k - 1; + for (; (i < a->used); i++, j--) { + SP_ASM_MUL_ADD2(l, h, o, a->dp[i], a->dp[j]); + } + t->dp[k * 2] = l; + l = h; + h = o; + o = 0; + } + t->dp[k * 2 - 1] = l; + t->dp[k * 2] = h; + t->used = a->used * 2; + + sp_copy(t, r); + sp_clamp(r); + } + else if (err == MP_OKAY) { + sp_int_digit l; + + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + t->dp[1] = l; + t->used = a->used * 2; + + sp_copy(t, r); + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + #endif + + return err; + } +#else /* !SQR_MUL_ASM */ + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + int i; + int j; + int k; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + sp_int_word w, l, h; + + w = (sp_int_word)a->dp[0] * a->dp[0]; + t->dp[0] = (sp_int_digit)w; + l = (sp_int_digit)(w >> SP_WORD_SIZE); + h = 0; + for (k = 1; k <= (a->used - 1) * 2; k++) { + i = k / 2; + j = k - i; + if (i == j) { + w = (sp_int_word)a->dp[i] * a->dp[j]; + l += (sp_int_digit)w; + h += (sp_int_digit)(w >> SP_WORD_SIZE); + } + for (++i, --j; (i < a->used) && (j >= 0); i++, j--) { + w = (sp_int_word)a->dp[i] * a->dp[j]; + l += (sp_int_digit)w; + h += (sp_int_digit)(w >> SP_WORD_SIZE); + l += (sp_int_digit)w; + h += (sp_int_digit)(w >> SP_WORD_SIZE); + } + t->dp[k] = (sp_int_digit)l; + l >>= SP_WORD_SIZE; + l += (sp_int_digit)h; + h >>= SP_WORD_SIZE; + } + t->dp[k] = (sp_int_digit)l; + t->dp[k+1] = (sp_int_digit)h; + t->used = k + 2; + + sp_copy(t, r); + sp_clamp(r); + } + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + return err; + } +#endif /* SQR_MUL_ASM */ +#endif + +#ifndef WOLFSSL_SP_SMALL +#ifndef WOLFSSL_HAVE_SP_ECC +#if SP_WORD_SIZE == 64 +#ifndef SQR_MUL_ASM + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_4(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + #ifdef WOLFSSL_SMALL_STACK + sp_int_word* w = NULL; + #else + sp_int_word w[10]; + #endif + sp_int_digit* da = a->dp; + + #ifdef WOLFSSL_SMALL_STACK + w = (sp_int_word*)XMALLOC(sizeof(sp_word) * 10, NULL, + DYNAMIC_TYPE_BIGINT); + if (w == NULL) { + err = MP_MEM; + } + #endif + + + if (err == MP_OKAY) { + w[0] = (sp_int_word)da[0] * da[0]; + w[1] = (sp_int_word)da[0] * da[1]; + w[2] = (sp_int_word)da[0] * da[2]; + w[3] = (sp_int_word)da[1] * da[1]; + w[4] = (sp_int_word)da[0] * da[3]; + w[5] = (sp_int_word)da[1] * da[2]; + w[6] = (sp_int_word)da[1] * da[3]; + w[7] = (sp_int_word)da[2] * da[2]; + w[8] = (sp_int_word)da[2] * da[3]; + w[9] = (sp_int_word)da[3] * da[3]; + + r->dp[0] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[1]; + w[0] += (sp_int_digit)w[1]; + r->dp[1] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[1] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[1]; + w[0] += (sp_int_digit)w[1]; + w[0] += (sp_int_digit)w[2]; + w[0] += (sp_int_digit)w[2]; + w[0] += (sp_int_digit)w[3]; + r->dp[2] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[2] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[2]; + w[0] += (sp_int_digit)w[2]; + w[3] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[3]; + w[0] += (sp_int_digit)w[4]; + w[0] += (sp_int_digit)w[4]; + w[0] += (sp_int_digit)w[5]; + w[0] += (sp_int_digit)w[5]; + r->dp[3] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[4] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[4]; + w[0] += (sp_int_digit)w[4]; + w[5] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[5]; + w[0] += (sp_int_digit)w[5]; + w[0] += (sp_int_digit)w[6]; + w[0] += (sp_int_digit)w[6]; + w[0] += (sp_int_digit)w[7]; + r->dp[4] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[6] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[6]; + w[0] += (sp_int_digit)w[6]; + w[7] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[7]; + w[0] += (sp_int_digit)w[8]; + w[0] += (sp_int_digit)w[8]; + r->dp[5] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[8] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[8]; + w[0] += (sp_int_digit)w[8]; + w[0] += (sp_int_digit)w[9]; + r->dp[6] = w[0]; + w[0] >>= SP_WORD_SIZE; + w[9] >>= SP_WORD_SIZE; + w[0] += (sp_int_digit)w[9]; + r->dp[7] = w[0]; + + r->used = 8; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (w != NULL) { + XFREE(w, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + return err; + } +#else /* SQR_MUL_ASM */ + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_4(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + #ifdef WOLFSSL_SP_PPC + tl = 0; + th = 0; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[1]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[2]); + SP_ASM_SQR_ADD(l, h, o, a->dp[1]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[3]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[2]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[3]); + SP_ASM_SQR_ADD(l, h, o, a->dp[2]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[2], a->dp[3]); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_SQR_ADD_NO(l, h, a->dp[3]); + t->dp[6] = l; + t->dp[7] = h; + t->used = 8; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 64 +#ifdef SQR_MUL_ASM + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_6(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + sp_int_digit tl; + sp_int_digit th; + sp_int_digit to; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + #ifdef WOLFSSL_SP_PPC + tl = 0; + th = 0; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[1]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[2]); + SP_ASM_SQR_ADD(l, h, o, a->dp[1]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[3]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[2]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[4]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[3]); + SP_ASM_SQR_ADD(l, h, o, a->dp[2]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[4]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[5]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[2], a->dp[4]); + SP_ASM_SQR_ADD(l, h, o, a->dp[3]); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[2], a->dp[5]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[3], a->dp[4]); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[3], a->dp[5]); + SP_ASM_SQR_ADD(l, h, o, a->dp[4]); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[4], a->dp[5]); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_SQR_ADD_NO(l, h, a->dp[5]); + t->dp[10] = l; + t->dp[11] = h; + t->used = 12; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_8(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + sp_int_digit tl; + sp_int_digit th; + sp_int_digit to; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + #ifdef WOLFSSL_SP_PPC + tl = 0; + th = 0; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[1]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[2]); + SP_ASM_SQR_ADD(l, h, o, a->dp[1]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[3]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[2]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[4]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[3]); + SP_ASM_SQR_ADD(l, h, o, a->dp[2]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[4]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[4]); + SP_ASM_SQR_ADD(l, h, o, a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[1], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[5]); + SP_ASM_SQR_ADD(l, h, o, a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[2], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[3], a->dp[7]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[4], a->dp[6]); + SP_ASM_SQR_ADD(l, h, o, a->dp[5]); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[4], a->dp[7]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[5], a->dp[6]); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[5], a->dp[7]); + SP_ASM_SQR_ADD(l, h, o, a->dp[6]); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[6], a->dp[7]); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_SQR_ADD_NO(l, h, a->dp[7]); + t->dp[14] = l; + t->dp[15] = h; + t->used = 16; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_12(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + sp_int_digit tl; + sp_int_digit th; + sp_int_digit to; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + #ifdef WOLFSSL_SP_PPC + tl = 0; + th = 0; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[1]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[2]); + SP_ASM_SQR_ADD(l, h, o, a->dp[1]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[3]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[2]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[4]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[3]); + SP_ASM_SQR_ADD(l, h, o, a->dp[2]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[4]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[4]); + SP_ASM_SQR_ADD(l, h, o, a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[5]); + SP_ASM_SQR_ADD(l, h, o, a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[6]); + SP_ASM_SQR_ADD(l, h, o, a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[6]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[1], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[7]); + SP_ASM_SQR_ADD(l, h, o, a->dp[6]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[2], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[7]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[3], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[8]); + SP_ASM_SQR_ADD(l, h, o, a->dp[7]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[14] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[4], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[8]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[15] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[5], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[9]); + SP_ASM_SQR_ADD(l, h, o, a->dp[8]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[16] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[6], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[9]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[17] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[7], a->dp[11]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[8], a->dp[10]); + SP_ASM_SQR_ADD(l, h, o, a->dp[9]); + t->dp[18] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[8], a->dp[11]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[9], a->dp[10]); + t->dp[19] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[9], a->dp[11]); + SP_ASM_SQR_ADD(l, h, o, a->dp[10]); + t->dp[20] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[10], a->dp[11]); + t->dp[21] = l; + l = h; + h = o; + o = 0; + SP_ASM_SQR_ADD_NO(l, h, a->dp[11]); + t->dp[22] = l; + t->dp[23] = h; + t->used = 24; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#endif /* WOLFSSL_HAVE_SP_ECC */ + +#if defined(SQR_MUL_ASM) && defined(WOLFSSL_SP_INT_LARGE_COMBA) + #if SP_INT_DIGITS >= 32 + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_16(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + sp_int_digit tl; + sp_int_digit th; + sp_int_digit to; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + #ifdef WOLFSSL_SP_PPC + tl = 0; + th = 0; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[1]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[2]); + SP_ASM_SQR_ADD(l, h, o, a->dp[1]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[3]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[2]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[4]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[3]); + SP_ASM_SQR_ADD(l, h, o, a->dp[2]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[4]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[4]); + SP_ASM_SQR_ADD(l, h, o, a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[5]); + SP_ASM_SQR_ADD(l, h, o, a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[6]); + SP_ASM_SQR_ADD(l, h, o, a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[6]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[7]); + SP_ASM_SQR_ADD(l, h, o, a->dp[6]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[7]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[8]); + SP_ASM_SQR_ADD(l, h, o, a->dp[7]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[14] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[8]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[15] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[1], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[9]); + SP_ASM_SQR_ADD(l, h, o, a->dp[8]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[16] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[2], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[9]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[17] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[3], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[10]); + SP_ASM_SQR_ADD(l, h, o, a->dp[9]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[18] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[4], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[10]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[19] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[5], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[11]); + SP_ASM_SQR_ADD(l, h, o, a->dp[10]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[20] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[6], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[11]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[21] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[7], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[12]); + SP_ASM_SQR_ADD(l, h, o, a->dp[11]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[22] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[8], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[12]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[23] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[9], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[13]); + SP_ASM_SQR_ADD(l, h, o, a->dp[12]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[24] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[10], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[13]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[25] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[11], a->dp[15]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[12], a->dp[14]); + SP_ASM_SQR_ADD(l, h, o, a->dp[13]); + t->dp[26] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[12], a->dp[15]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[13], a->dp[14]); + t->dp[27] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[13], a->dp[15]); + SP_ASM_SQR_ADD(l, h, o, a->dp[14]); + t->dp[28] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[14], a->dp[15]); + t->dp[29] = l; + l = h; + h = o; + o = 0; + SP_ASM_SQR_ADD_NO(l, h, a->dp[15]); + t->dp[30] = l; + t->dp[31] = h; + t->used = 32; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 32 */ + + #if SP_INT_DIGITS >= 48 + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_24(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + sp_int_digit l; + sp_int_digit h; + sp_int_digit o; + sp_int_digit tl; + sp_int_digit th; + sp_int_digit to; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif + #ifdef WOLFSSL_SP_PPC + tl = 0; + th = 0; + #endif + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + h = 0; + o = 0; + SP_ASM_SQR(t->dp[0], l, a->dp[0]); + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[1]); + t->dp[1] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2_NO(l, h, o, a->dp[0], a->dp[2]); + SP_ASM_SQR_ADD(l, h, o, a->dp[1]); + t->dp[2] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[3]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[2]); + t->dp[3] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[0], a->dp[4]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[1], a->dp[3]); + SP_ASM_SQR_ADD(l, h, o, a->dp[2]); + t->dp[4] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[4]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[5] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[4]); + SP_ASM_SQR_ADD(l, h, o, a->dp[3]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[6] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[5]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[7] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[5]); + SP_ASM_SQR_ADD(l, h, o, a->dp[4]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[8] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[6]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[9] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[6]); + SP_ASM_SQR_ADD(l, h, o, a->dp[5]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[10] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[7]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[6]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[11] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[7]); + SP_ASM_SQR_ADD(l, h, o, a->dp[6]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[12] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[8]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[7]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[13] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[8]); + SP_ASM_SQR_ADD(l, h, o, a->dp[7]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[14] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[9]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[8]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[15] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[9]); + SP_ASM_SQR_ADD(l, h, o, a->dp[8]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[16] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[10]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[9]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[17] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[10]); + SP_ASM_SQR_ADD(l, h, o, a->dp[9]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[18] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[11]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[10]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[19] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[11]); + SP_ASM_SQR_ADD(l, h, o, a->dp[10]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[20] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[12]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[11]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[21] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[12]); + SP_ASM_SQR_ADD(l, h, o, a->dp[11]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[22] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[0], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[1], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[13]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[12]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[23] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[1], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[2], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[13]); + SP_ASM_SQR_ADD(l, h, o, a->dp[12]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[24] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[2], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[3], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[14]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[13]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[25] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[3], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[4], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[14]); + SP_ASM_SQR_ADD(l, h, o, a->dp[13]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[26] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[4], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[5], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[15]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[14]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[27] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[5], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[6], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[15]); + SP_ASM_SQR_ADD(l, h, o, a->dp[14]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[28] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[6], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[7], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[16]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[15]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[29] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[7], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[8], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[16]); + SP_ASM_SQR_ADD(l, h, o, a->dp[15]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[30] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[8], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[9], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[17]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[16]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[31] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[9], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[10], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[17]); + SP_ASM_SQR_ADD(l, h, o, a->dp[16]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[32] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[10], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[11], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[18]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[16], a->dp[17]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[33] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[11], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[12], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[16], a->dp[18]); + SP_ASM_SQR_ADD(l, h, o, a->dp[17]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[34] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[12], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[13], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[16], a->dp[19]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[17], a->dp[18]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[35] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[13], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[14], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[16], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[17], a->dp[19]); + SP_ASM_SQR_ADD(l, h, o, a->dp[18]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[36] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[14], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[15], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[16], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[17], a->dp[20]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[18], a->dp[19]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[37] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[15], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[16], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[17], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[18], a->dp[20]); + SP_ASM_SQR_ADD(l, h, o, a->dp[19]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[38] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[16], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[17], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[18], a->dp[21]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[19], a->dp[20]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[39] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[17], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[18], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[19], a->dp[21]); + SP_ASM_SQR_ADD(l, h, o, a->dp[20]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[40] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_SET(tl, th, to, a->dp[18], a->dp[23]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[19], a->dp[22]); + SP_ASM_MUL_ADD(tl, th, to, a->dp[20], a->dp[21]); + SP_ASM_ADD_DBL_3(l, h, o, tl, th, to); + t->dp[41] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[19], a->dp[23]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[20], a->dp[22]); + SP_ASM_SQR_ADD(l, h, o, a->dp[21]); + t->dp[42] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[20], a->dp[23]); + SP_ASM_MUL_ADD2(l, h, o, a->dp[21], a->dp[22]); + t->dp[43] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[21], a->dp[23]); + SP_ASM_SQR_ADD(l, h, o, a->dp[22]); + t->dp[44] = l; + l = h; + h = o; + o = 0; + SP_ASM_MUL_ADD2(l, h, o, a->dp[22], a->dp[23]); + t->dp[45] = l; + l = h; + h = o; + o = 0; + SP_ASM_SQR_ADD_NO(l, h, a->dp[23]); + t->dp[46] = l; + t->dp[47] = h; + t->used = 48; + sp_copy(t, r); + sp_clamp(t); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 48 */ + + #if SP_INT_DIGITS >= 64 + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_32(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[3]; + #endif + sp_int* a1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + z0 = r; + z1 = &t[1]; + z2 = &t[2]; + + XMEMCPY(a1->dp, &a->dp[16], sizeof(sp_int_digit) * 16); + a1->used = 16; + + /* z2 = a1 ^ 2 */ + err = _sp_sqr_16(a1, z2); + } + if (err == MP_OKAY) { + l = 0; + h = 0; + for (i = 0; i < 16; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + + /* z0 = a0 ^ 2 */ + err = _sp_sqr_16(a, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) ^ 2 */ + err = _sp_sqr_16(a1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 32) + (z1 - z0 - z2) << 16) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 16 */ + z1->dp[32] = ca; + if (ca) { + l = z1->dp[0 + 16]; + h = 0; + SP_ASM_ADDC(l, h, a1->dp[0]); + SP_ASM_ADDC(l, h, a1->dp[0]); + z1->dp[0 + 16] = l; + l = h; + h = 0; + for (i = 1; i < 16; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 16]); + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 16] = l; + l = h; + h = 0; + } + z1->dp[32] += l; + } + /* z1 = z1 - z0 - z1 */ + l = z1->dp[0]; + h = 0; + SP_ASM_SUBC(l, h, z0->dp[0]); + SP_ASM_SUBC(l, h, z2->dp[0]); + z1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 32; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 16; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 16]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 16] = l; + l = h; + h = 0; + } + for (; i < 33; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 16] = l; + l = h; + h = 0; + } + /* r += z2 << 32 */ + l = 0; + h = 0; + for (i = 0; i < 17; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 32]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + for (; i < 32; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + r->used = 64; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 64 */ + + #if SP_INT_DIGITS >= 96 + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_48(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[3]; + #endif + sp_int* a1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + z0 = r; + z1 = &t[1]; + z2 = &t[2]; + + XMEMCPY(a1->dp, &a->dp[24], sizeof(sp_int_digit) * 24); + a1->used = 24; + + /* z2 = a1 ^ 2 */ + err = _sp_sqr_24(a1, z2); + } + if (err == MP_OKAY) { + l = 0; + h = 0; + for (i = 0; i < 24; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + + /* z0 = a0 ^ 2 */ + err = _sp_sqr_24(a, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) ^ 2 */ + err = _sp_sqr_24(a1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 48) + (z1 - z0 - z2) << 24) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 24 */ + z1->dp[48] = ca; + if (ca) { + l = z1->dp[0 + 24]; + h = 0; + SP_ASM_ADDC(l, h, a1->dp[0]); + SP_ASM_ADDC(l, h, a1->dp[0]); + z1->dp[0 + 24] = l; + l = h; + h = 0; + for (i = 1; i < 24; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 24]); + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 24] = l; + l = h; + h = 0; + } + z1->dp[48] += l; + } + /* z1 = z1 - z0 - z1 */ + l = z1->dp[0]; + h = 0; + SP_ASM_SUBC(l, h, z0->dp[0]); + SP_ASM_SUBC(l, h, z2->dp[0]); + z1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 48; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 24; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 24]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 24] = l; + l = h; + h = 0; + } + for (; i < 49; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 24] = l; + l = h; + h = 0; + } + /* r += z2 << 48 */ + l = 0; + h = 0; + for (i = 0; i < 25; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 48]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + for (; i < 48; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + r->used = 96; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 96 */ + + #if SP_INT_DIGITS >= 128 + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_64(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[3]; + #endif + sp_int* a1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + z0 = r; + z1 = &t[1]; + z2 = &t[2]; + + XMEMCPY(a1->dp, &a->dp[32], sizeof(sp_int_digit) * 32); + a1->used = 32; + + /* z2 = a1 ^ 2 */ + err = _sp_sqr_32(a1, z2); + } + if (err == MP_OKAY) { + l = 0; + h = 0; + for (i = 0; i < 32; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + + /* z0 = a0 ^ 2 */ + err = _sp_sqr_32(a, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) ^ 2 */ + err = _sp_sqr_32(a1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 64) + (z1 - z0 - z2) << 32) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 32 */ + z1->dp[64] = ca; + if (ca) { + l = z1->dp[0 + 32]; + h = 0; + SP_ASM_ADDC(l, h, a1->dp[0]); + SP_ASM_ADDC(l, h, a1->dp[0]); + z1->dp[0 + 32] = l; + l = h; + h = 0; + for (i = 1; i < 32; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 32]); + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 32] = l; + l = h; + h = 0; + } + z1->dp[64] += l; + } + /* z1 = z1 - z0 - z1 */ + l = z1->dp[0]; + h = 0; + SP_ASM_SUBC(l, h, z0->dp[0]); + SP_ASM_SUBC(l, h, z2->dp[0]); + z1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 64; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 32; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 32]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + for (; i < 65; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 32] = l; + l = h; + h = 0; + } + /* r += z2 << 64 */ + l = 0; + h = 0; + for (i = 0; i < 33; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 64]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 64] = l; + l = h; + h = 0; + } + for (; i < 64; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 64] = l; + l = h; + h = 0; + } + r->used = 128; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 128 */ + + #if SP_INT_DIGITS >= 192 + /* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. + */ + static int _sp_sqr_96(sp_int* a, sp_int* r) + { + int err = MP_OKAY; + int i; + sp_int_digit l; + sp_int_digit h; + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[3]; + #endif + sp_int* a1; + sp_int* z0; + sp_int* z1; + sp_int* z2; + sp_int_digit ca; + + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif + + if (err == MP_OKAY) { + a1 = &t[0]; + z0 = r; + z1 = &t[1]; + z2 = &t[2]; + + XMEMCPY(a1->dp, &a->dp[48], sizeof(sp_int_digit) * 48); + a1->used = 48; + + /* z2 = a1 ^ 2 */ + err = _sp_sqr_48(a1, z2); + } + if (err == MP_OKAY) { + l = 0; + h = 0; + for (i = 0; i < 48; i++) { + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a->dp[i]); + a1->dp[i] = l; + l = h; + h = 0; + } + ca = l; + + /* z0 = a0 ^ 2 */ + err = _sp_sqr_48(a, z0); + } + if (err == MP_OKAY) { + /* z1 = (a0 + a1) ^ 2 */ + err = _sp_sqr_48(a1, z1); + } + if (err == MP_OKAY) { + /* r = (z2 << 96) + (z1 - z0 - z2) << 48) + z0 */ + /* r = z0 */ + /* r += (z1 - z0 - z2) << 48 */ + z1->dp[96] = ca; + if (ca) { + l = z1->dp[0 + 48]; + h = 0; + SP_ASM_ADDC(l, h, a1->dp[0]); + SP_ASM_ADDC(l, h, a1->dp[0]); + z1->dp[0 + 48] = l; + l = h; + h = 0; + for (i = 1; i < 48; i++) { + SP_ASM_ADDC(l, h, z1->dp[i + 48]); + SP_ASM_ADDC(l, h, a1->dp[i]); + SP_ASM_ADDC(l, h, a1->dp[i]); + z1->dp[i + 48] = l; + l = h; + h = 0; + } + z1->dp[96] += l; + } + /* z1 = z1 - z0 - z1 */ + l = z1->dp[0]; + h = 0; + SP_ASM_SUBC(l, h, z0->dp[0]); + SP_ASM_SUBC(l, h, z2->dp[0]); + z1->dp[0] = l; + l = h; + h = 0; + for (i = 1; i < 96; i++) { + l += z1->dp[i]; + SP_ASM_SUBC(l, h, z0->dp[i]); + SP_ASM_SUBC(l, h, z2->dp[i]); + z1->dp[i] = l; + l = h; + h = 0; + } + z1->dp[i] += l; + /* r += z1 << 16 */ + l = 0; + h = 0; + for (i = 0; i < 48; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 48]); + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + for (; i < 97; i++) { + SP_ASM_ADDC(l, h, z1->dp[i]); + r->dp[i + 48] = l; + l = h; + h = 0; + } + /* r += z2 << 96 */ + l = 0; + h = 0; + for (i = 0; i < 49; i++) { + SP_ASM_ADDC(l, h, r->dp[i + 96]); + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 96] = l; + l = h; + h = 0; + } + for (; i < 96; i++) { + SP_ASM_ADDC(l, h, z2->dp[i]); + r->dp[i + 96] = l; + l = h; + h = 0; + } + r->used = 192; + sp_clamp(r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif + + return err; + } + #endif /* SP_INT_DIGITS >= 192 */ + +#endif /* SQR_MUL_ASM && WOLFSSL_SP_INT_LARGE_COMBA */ +#endif /* !WOLFSSL_SP_SMALL */ + +/* Square a and store in r. r = a * a + * + * @param [in] a SP integer to square. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL, or the result will be too big for fixed + * data length. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_sqr(sp_int* a, sp_int* r) +{ +#if defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_SP_SMALL) + return sp_mul(a, a, r); +#else + int err = MP_OKAY; + + if ((a == NULL) || (r == NULL)) { + err = MP_VAL; + } + /* Need extra digit during calculation. */ + if ((err == MP_OKAY) && (a->used * 2 >= r->size)) { + err = MP_VAL; + } + + if (0 && (err == MP_OKAY)) { + sp_print(a, "a"); + } + + if (err == MP_OKAY) { + if (a->used == 0) { + _sp_zero(r); + } + else +#ifndef WOLFSSL_SP_SMALL +#ifndef WOLFSSL_HAVE_SP_ECC +#if SP_WORD_SIZE == 64 + if (a->used == 4) { + err = _sp_sqr_4(a, r); + } + else +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 64 +#ifdef SQR_MUL_ASM + if (a->used == 6) { + err = _sp_sqr_6(a, r); + } + else +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 64 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + if (a->used == 8) { + err = _sp_sqr_8(a, r); + } + else +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#if SP_WORD_SIZE == 32 +#ifdef SQR_MUL_ASM + if (a->used == 12) { + err = _sp_sqr_12(a, r); + } + else +#endif /* SQR_MUL_ASM */ +#endif /* SP_WORD_SIZE == 32 */ +#endif /* WOLFSSL_HAVE_SP_ECC */ +#if defined(SQR_MUL_ASM) && defined(WOLFSSL_SP_INT_LARGE_COMBA) + #if SP_INT_DIGITS >= 32 + if (a->used == 16) { + err = _sp_sqr_16(a, r); + } + else + #endif /* SP_INT_DIGITS >= 32 */ + #if SP_INT_DIGITS >= 48 + if (a->used == 24) { + err = _sp_sqr_24(a, r); + } + else + #endif /* SP_INT_DIGITS >= 48 */ + #if SP_INT_DIGITS >= 64 + if (a->used == 32) { + err = _sp_sqr_32(a, r); + } + else + #endif /* SP_INT_DIGITS >= 64 */ + #if SP_INT_DIGITS >= 96 + if (a->used == 48) { + err = _sp_sqr_48(a, r); + } + else + #endif /* SP_INT_DIGITS >= 96 */ + #if SP_INT_DIGITS >= 128 + if (a->used == 64) { + err = _sp_sqr_64(a, r); + } + else + #endif /* SP_INT_DIGITS >= 128 */ + #if SP_INT_DIGITS >= 192 + if (a->used == 96) { + err = _sp_sqr_96(a, r); + } + else + #endif /* SP_INT_DIGITS >= 192 */ +#endif /* SQR_MUL_ASM && WOLFSSL_SP_INT_LARGE_COMBA */ +#endif /* !WOLFSSL_SP_SMALL */ + { + err = _sp_sqr(a, r); + } + } + +#ifdef WOLFSSL_SP_INT_NEGATIVE + if (err == MP_OKAY) { + r->sign = MP_ZPOS; + } +#endif + + if (0 && (err == MP_OKAY)) { + sp_print(r, "rsqr"); + } + + return err; +#endif +} +/* END SP_SQR implementations */ +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || HAVE_ECC || + * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Square a mod m and store in r: r = (a * a) mod m + * + * @param [in] a SP integer to square. + * @param [in] m SP integer that is the modulus. + * @param [out] r SP integer result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, m or r is NULL; or m is 0; or a squared is too big + * for fixed data length. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_sqrmod(sp_int* a, sp_int* m, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (m == NULL) || (r == NULL)) { + err = MP_VAL; + } + /* Need extra digit during calculation. */ + if ((err == MP_OKAY) && (a->used * 2 >= r->size)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + err = sp_sqr(a, r); + } + if (err == MP_OKAY) { + err = sp_mod(r, m, r); + } + + return err; +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY */ + +/********************** + * Montogmery functions + **********************/ + +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Reduce a number in montgomery form. + * + * Assumes a and m are not NULL and m is not 0. + * + * @param [in,out] a SP integer to Montgomery reduce. + * @param [in] m SP integer that is the modulus. + * @param [in] mp SP integer digit that is the bottom digit of inv(-m). + * + * @return MP_OKAY on success. + */ +static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) +{ +#if !defined(SQR_MUL_ASM) + int i; + int bits; + sp_int_word w; + sp_int_digit mu; + + if (0) { + sp_print(a, "a"); + sp_print(m, "m"); + } + + bits = sp_count_bits(m); + + for (i = a->used; i < m->used * 2; i++) { + a->dp[i] = 0; + } + + if (m->used == 1) { + mu = mp * a->dp[0]; + w = a->dp[0]; + w += (sp_int_word)mu * m->dp[0]; + a->dp[0] = (sp_int_digit)w; + w >>= SP_WORD_SIZE; + w += a->dp[1]; + a->dp[1] = (sp_int_digit)w; + w >>= SP_WORD_SIZE; + a->dp[2] = (sp_int_digit)w; + a->used = 2; + /* mp is SP_WORD_SIZE */ + bits = SP_WORD_SIZE; + } + else { + sp_int_digit mask = (1UL << (bits & (SP_WORD_SIZE - 1))) - 1; + sp_int_word o = 0; + w = 0; + for (i = 0; i < m->used; i++) { + int j; + + mu = mp * a->dp[i]; + if ((i == m->used - 1) && (mask != 0)) { + mu &= mask; + } + w = a->dp[i]; + w += (sp_int_word)mu * m->dp[0]; + a->dp[i] = (sp_int_digit)w; + w >>= SP_WORD_SIZE; + for (j = 1; j < m->used - 1; j++) { + w += a->dp[i + j]; + w += (sp_int_word)mu * m->dp[j]; + a->dp[i + j] = (sp_int_digit)w; + w >>= SP_WORD_SIZE; + } + w += o; + w += a->dp[i + j]; + o = (sp_int_digit)(w >> SP_WORD_SIZE); + w = ((sp_int_word)mu * m->dp[j]) + (sp_int_digit)w; + a->dp[i + j] = (sp_int_digit)w; + w >>= SP_WORD_SIZE; + o += w; + } + o += a->dp[m->used * 2 - 1]; + a->dp[m->used * 2 - 1] = (sp_int_digit)o; + o >>= SP_WORD_SIZE; + a->dp[m->used * 2] = (sp_int_digit)o; + a->used = m->used * 2 + 1; + } + + sp_clamp(a); + sp_rshb(a, bits, a); + + if (_sp_cmp(a, m) != MP_LT) { + sp_sub(a, m, a); + } + + if (0) { + sp_print(a, "rr"); + } + + return MP_OKAY; +#else /* !SQR_MUL_ASM */ + int i; + int j; + int bits; + sp_int_digit mu; + sp_int_digit o; + sp_int_digit mask; + + bits = sp_count_bits(m); + mask = (1UL << (bits & (SP_WORD_SIZE - 1))) - 1; + + for (i = a->used; i < m->used * 2; i++) { + a->dp[i] = 0; + } + + if (m->used <= 1) { + sp_int_word w; + + mu = mp * a->dp[0]; + w = a->dp[0]; + w += (sp_int_word)mu * m->dp[0]; + a->dp[0] = w; + w >>= SP_WORD_SIZE; + w += a->dp[1]; + a->dp[1] = w; + w >>= SP_WORD_SIZE; + a->dp[2] = w; + a->used = m->used * 2; + /* mp is SP_WORD_SIZE */ + bits = SP_WORD_SIZE; + } +#ifndef WOLFSSL_HAVE_SP_ECC +#if SP_WORD_SIZE == 64 + else if (m->used == 4) { + sp_int_digit l; + sp_int_digit h; + + l = 0; + h = 0; + o = 0; + for (i = 0; i < 4; i++) { + mu = mp * a->dp[i]; + if ((i == 3) && (mask != 0)) { + mu &= mask; + } + l = a->dp[i]; + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[0]); + a->dp[i] = l; + l = h; + h = 0; + SP_ASM_ADDC(l, h, a->dp[i + 1]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[1]); + a->dp[i + 1] = l; + l = h; + h = 0; + SP_ASM_ADDC(l, h, a->dp[i + 2]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[2]); + a->dp[i + 2] = l; + l = h; + h = 0; + SP_ASM_ADDC_REG(l, h, o); + SP_ASM_ADDC(l, h, a->dp[i + 3]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[3]); + a->dp[i + 3] = l; + o = h; + l = h; + h = 0; + } + SP_ASM_ADDC(l, h, a->dp[7]); + a->dp[7] = l; + a->dp[8] = h; + a->used = 9; + } + else if (m->used == 6) { + sp_int_digit l; + sp_int_digit h; + + l = 0; + h = 0; + o = 0; + for (i = 0; i < 6; i++) { + mu = mp * a->dp[i]; + if ((i == 5) && (mask != 0)) { + mu &= mask; + } + l = a->dp[i]; + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[0]); + a->dp[i] = l; + l = h; + h = 0; + SP_ASM_ADDC(l, h, a->dp[i + 1]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[1]); + a->dp[i + 1] = l; + l = h; + h = 0; + SP_ASM_ADDC(l, h, a->dp[i + 2]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[2]); + a->dp[i + 2] = l; + l = h; + h = 0; + SP_ASM_ADDC(l, h, a->dp[i + 3]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[3]); + a->dp[i + 3] = l; + l = h; + h = 0; + SP_ASM_ADDC(l, h, a->dp[i + 4]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[4]); + a->dp[i + 4] = l; + l = h; + h = 0; + SP_ASM_ADDC_REG(l, h, o); + SP_ASM_ADDC(l, h, a->dp[i + 5]); + SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[5]); + a->dp[i + 5] = l; + o = h; + l = h; + h = 0; + } + SP_ASM_ADDC(l, h, a->dp[11]); + a->dp[11] = l; + a->dp[12] = h; + a->used = 13; + } +#endif /* SP_WORD_SIZE == 64 */ +#endif /* WOLFSSL_HAVE_SP_ECC */ + else { + sp_int_digit l; + sp_int_digit h; + sp_int_digit o2; + sp_int_digit* ad; + sp_int_digit* md; + + o = 0; + o2 = 0; + ad = a->dp; + for (i = 0; i < m->used; i++, ad++) { + md = m->dp; + mu = mp * ad[0]; + if ((i == m->used - 1) && (mask != 0)) { + mu &= mask; + } + l = ad[0]; + h = 0; + SP_ASM_MUL_ADD_NO(l, h, mu, *(md++)); + ad[0] = l; + l = h; + for (j = 1; j + 1 < m->used - 1; j += 2) { + h = 0; + SP_ASM_ADDC(l, h, ad[j + 0]); + SP_ASM_MUL_ADD_NO(l, h, mu, *(md++)); + ad[j + 0] = l; + l = 0; + SP_ASM_ADDC(h, l, ad[j + 1]); + SP_ASM_MUL_ADD_NO(h, l, mu, *(md++)); + ad[j + 1] = h; + } + for (; j < m->used - 1; j++) { + h = 0; + SP_ASM_ADDC(l, h, ad[j]); + SP_ASM_MUL_ADD_NO(l, h, mu, *(md++)); + ad[j] = l; + l = h; + } + h = o2; + o2 = 0; + SP_ASM_ADDC_REG(l, h, o); + SP_ASM_ADDC(l, h, ad[j]); + SP_ASM_MUL_ADD(l, h, o2, mu, *md); + ad[j] = l; + o = h; + } + l = o; + h = o2; + SP_ASM_ADDC(l, h, a->dp[m->used * 2 - 1]); + a->dp[m->used * 2 - 1] = l; + a->dp[m->used * 2] = h; + a->used = m->used * 2 + 1; + } + + sp_clamp(a); + sp_rshb(a, bits, a); + + if (_sp_cmp(a, m) != MP_LT) { + sp_sub(a, m, a); + } + + return MP_OKAY; +#endif /* !SQR_MUL_ASM */ +} +#endif /* WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY */ + +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Reduce a number in montgomery form. + * + * @param [in,out] a SP integer to Montgomery reduce. + * @param [in] m SP integer that is the modulus. + * @param [in] mp SP integer digit that is the bottom digit of inv(-m). + * + * @return MP_OKAY on success. + * @return MP_VAL when a or m is NULL or m is zero. + */ +int sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) +{ + int err; + + if ((a == NULL) || (m == NULL) || sp_iszero(m)) { + err = MP_VAL; + } + else { + err = _sp_mont_red(a, m, mp); + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || !WOLFSSL_RSA_VERIFY_ONLY */ + +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Calculate the bottom digit of the inverse of negative m. + * + * Used when performing Montgomery Reduction. + * + * @param [in] m SP integer that is the modulus. + * @param [out] mp SP integer digit that is the bottom digit of inv(-m). + * + * @return MP_OKAY on success. + * @return MP_VAL when m or rho is NULL. + */ +int sp_mont_setup(sp_int* m, sp_int_digit* rho) +{ + int err = MP_OKAY; + + if ((m == NULL) || (rho == NULL)) { + err = MP_VAL; + } + if ((err == MP_OKAY) && !sp_isodd(m)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + sp_int_digit x; + sp_int_digit b; + + b = m->dp[0]; + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ + #if SP_WORD_SIZE >= 16 + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ + #if SP_WORD_SIZE >= 32 + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ + #if SP_WORD_SIZE >= 64 + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ + #endif /* SP_WORD_SIZE >= 64 */ + #endif /* SP_WORD_SIZE >= 32 */ + #endif /* SP_WORD_SIZE >= 16 */ + + /* rho = -1/m mod b */ + *rho = -x; + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || !WOLFSSL_RSA_VERIFY_ONLY */ + +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Calculate the normalization value of m. + * norm = 2^k - m, where k is the number of bits in m + * + * @param [out] norm SP integer that normalises numbers into Montgomery + * form. + * @param [in] m SP integer that is the modulus. + * + * @return MP_OKAY on success. + * @return MP_VAL when norm or m is NULL, or number of bits in m is maximual. + */ +int sp_mont_norm(sp_int* norm, sp_int* m) +{ + int err = MP_OKAY; + int bits = 0; + + if ((norm == NULL) || (m == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + bits = sp_count_bits(m); + if (bits == m->size * SP_WORD_SIZE) { + err = MP_VAL; + } + } + if (err == MP_OKAY) { + if (bits < SP_WORD_SIZE) { + bits = SP_WORD_SIZE; + } + _sp_zero(norm); + sp_set_bit(norm, bits); + err = sp_sub(norm, m, norm); + } + if ((err == MP_OKAY) && (bits == SP_WORD_SIZE)) { + norm->dp[0] %= m->dp[0]; + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || !WOLFSSL_RSA_VERIFY_ONLY */ + +/********************************* + * To and from binary and strings. + *********************************/ + +/* Calculate the number of 8-bit values required to represent the + * multi-precision number. + * + * When a is NULL, return s 0. + * + * @param [in] a SP integer. + * + * @return The count of 8-bit values. + */ +int sp_unsigned_bin_size(sp_int* a) +{ + int cnt = 0; + + if (a != NULL) { + cnt = (sp_count_bits(a) + 7) / 8; + } + + return cnt; } +/* Convert a number as an array of bytes in big-endian format to a + * multi-precision number. + * + * @param [out] a SP integer. + * @param [in] in Array of bytes. + * @param [in] inSz Number of data bytes in array. + * + * @return MP_OKAY on success. + * @return MP_VAL when the number is too big to fit in an SP. + */ +int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz) +{ + int err = MP_OKAY; + + if ((a == NULL) || ((in == NULL) && (inSz > 0))) { + err = MP_VAL; + } + + /* Extra digit added to SP_INT_DIGITS to be used in calculations. */ + if ((err == MP_OKAY) && (inSz > ((word32)a->size - 1) * SP_WORD_SIZEOF)) { + err = MP_VAL; + } + +#ifndef LITTLE_ENDIAN_ORDER + if (err == MP_OKAY) { + int i; + int j; + int s; + + for (i = inSz-1,j = 0; i > SP_WORD_SIZEOF-1; i -= SP_WORD_SIZEOF,j++) { + a->dp[j] = *(sp_int_digit*)(in + i - (SP_WORD_SIZEOF - 1)); + } + a->dp[j] = 0; + for (s = 0; i >= 0; i--,s += 8) { + a->dp[j] |= ((sp_int_digit)in[i]) << s; + } + a->used = j + 1; + sp_clamp(a); + } +#else + if (err == MP_OKAY) { + int i; + int j; + + a->used = (inSz + SP_WORD_SIZEOF - 1) / SP_WORD_SIZEOF; + + for (i = inSz-1, j = 0; i >= SP_WORD_SIZEOF - 1; i -= SP_WORD_SIZEOF) { + a->dp[j] = ((sp_int_digit)in[i - 0] << 0); + #if SP_WORD_SIZE >= 16 + a->dp[j] |= ((sp_int_digit)in[i - 1] << 8); + #endif + #if SP_WORD_SIZE >= 32 + a->dp[j] |= ((sp_int_digit)in[i - 2] << 16) | + ((sp_int_digit)in[i - 3] << 24); + #endif + #if SP_WORD_SIZE >= 64 + a->dp[j] |= ((sp_int_digit)in[i - 4] << 32) | + ((sp_int_digit)in[i - 5] << 40) | + ((sp_int_digit)in[i - 6] << 48) | + ((sp_int_digit)in[i - 7] << 56); + #endif + j++; + } + a->dp[j] = 0; + + #if SP_WORD_SIZE >= 16 + if (i >= 0) { + byte *d = (byte*)a->dp; + + a->dp[a->used - 1] = 0; + switch (i) { + case 6: d[inSz - 1 - 6] = in[6]; FALL_THROUGH; + case 5: d[inSz - 1 - 5] = in[5]; FALL_THROUGH; + case 4: d[inSz - 1 - 4] = in[4]; FALL_THROUGH; + case 3: d[inSz - 1 - 3] = in[3]; FALL_THROUGH; + case 2: d[inSz - 1 - 2] = in[2]; FALL_THROUGH; + case 1: d[inSz - 1 - 1] = in[1]; FALL_THROUGH; + case 0: d[inSz - 1 - 0] = in[0]; + } + } + #endif + + sp_clamp(a); + } +#endif /* LITTLE_ENDIAN_ORDER */ + + return err; +} + +#if (!defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING)) && \ + !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Convert the multi-precision number to an array of bytes in big-endian format. + * + * The array must be large enough for encoded number - use mp_unsigned_bin_size + * to calculate the number of bytes required. + * + * @param [in] a SP integer. + * @param [out] out Array to put encoding into. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or out is NULL. + */ +int sp_to_unsigned_bin(sp_int* a, byte* out) +{ + return sp_to_unsigned_bin_len(a, out, sp_unsigned_bin_size(a)); +} +#endif /* (!NO_DH || HAVE_ECC || WC_RSA_BLINDING) && !WOLFSSL_RSA_VERIFY_ONLY */ + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +/* Convert the multi-precision number to an array of bytes in big-endian format. + * + * The array must be large enough for encoded number - use mp_unsigned_bin_size + * to calculate the number of bytes required. + * Front-pads the output array with zeros make number the size of the array. + * + * @param [in] a SP integer. + * @param [out] out Array to put encoding into. + * @param [in] outSz Size of the array in bytes. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or out is NULL. + */ +int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz) +{ + int err = MP_OKAY; + + if ((a == NULL) || (out == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + int j = outSz - 1; + + if (!sp_iszero(a)) { + int i; + for (i = 0; (j >= 0) && (i < a->used); i++) { + int b; + for (b = 0; b < SP_WORD_SIZE; b += 8) { + out[j--] = a->dp[i] >> b; + if (j < 0) { + break; + } + } + } + } + for (; j >= 0; j--) { + out[j] = 0; + } + } + + return err; +} +#endif /* !WOLFSSL_RSA_VERIFY_ONLY */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* Store the number in big-endian format in array at an offset. + * The array must be large enough for encoded number - use mp_unsigned_bin_size + * to calculate the number of bytes required. + * + * @param [in] o Offset into array o start encoding. + * @param [in] a SP integer. + * @param [out] out Array to put encoding into. + * + * @return Index of next byte after data. + * @return MP_VAL when a or out is NULL. + */ +int sp_to_unsigned_bin_at_pos(int o, sp_int*a, unsigned char* out) +{ + int ret = sp_to_unsigned_bin(a, out + o); + + if (ret == MP_OKAY) { + ret = o + sp_unsigned_bin_size(a); + } + + return ret; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) +/* Convert hexadecimal number as string in big-endian format to a + * multi-precision number. + * + * Negative values supported when compiled with WOLFSSL_SP_INT_NEGATIVE. + * + * @param [out] a SP integer. + * @param [in] in NUL terminated string. + * + * @return MP_OKAY on success. + * @return MP_VAL when radix not supported, value is negative, or a character + * is not valid. + */ +static int _sp_read_radix_16(sp_int* a, const char* in) +{ + int err = MP_OKAY; + int i; + int s = 0; + int j = 0; + +#ifdef WOLFSSL_SP_INT_NEGATIVE + if (*in == '-') { + a->sign = MP_NEG; + in++; + } +#endif + + while (*in == '0') { + in++; + } + + a->dp[0] = 0; + for (i = (int)(XSTRLEN(in) - 1); i >= 0; i--) { + char ch = in[i]; + if ((ch >= '0') && (ch <= '9')) { + ch -= '0'; + } + else if ((ch >= 'A') && (ch <= 'F')) { + ch -= 'A' - 10; + } + else if ((ch >= 'a') && (ch <= 'f')) { + ch -= 'a' - 10; + } + else { + err = MP_VAL; + break; + } + + if (s == SP_WORD_SIZE) { + j++; + if (j >= a->size) { + err = MP_VAL; + break; + } + s = 0; + a->dp[j] = 0; + } + + a->dp[j] |= ((sp_int_digit)ch) << s; + s += 4; + } + + if (err == MP_OKAY) { + a->used = j + 1; + sp_clamp(a); + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || HAVE_ECC */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* Convert decimal number as string in big-endian format to a multi-precision + * number. + * + * Negative values supported when compiled with WOLFSSL_SP_INT_NEGATIVE. + * + * @param [out] a SP integer. + * @param [in] in NUL terminated string. + * + * @return MP_OKAY on success. + * @return MP_VAL when radix not supported, value is negative, or a character + * is not valid. + */ +static int _sp_read_radix_10(sp_int* a, const char* in) +{ + int err = MP_OKAY; + int i; + int len; + char ch; + +#ifdef WOLFSSL_SP_INT_NEGATIVE + if (*in == '-') { + a->sign = MP_NEG; + in++; + } +#endif /* WOLFSSL_SP_INT_NEGATIVE */ + + while (*in == '0') { + in++; + } + + a->dp[0] = 0; + a->used = 0; + len = (int)XSTRLEN(in); + for (i = 0; i < len; i++) { + ch = in[i]; + if ((ch >= '0') && (ch <= '9')) { + ch -= '0'; + } + else { + err = MP_VAL; + break; + } + if (a->used + 1 > a->size) { + err = MP_VAL; + break; + } + _sp_mul_d(a, 10, a, 0); + (void)_sp_add_d(a, ch, a); + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) +/* Convert a number as string in big-endian format to a big number. + * Only supports base-16 (hexadecimal) and base-10 (decimal). + * + * Negative values supported when WOLFSSL_SP_INT_NEGATIVE is defined. + * + * @param [out] a SP integer. + * @param [in] in NUL terminated string. + * @param [in] radix Number of values in a digit. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or in is NULL, radix not supported, value is negative, + * or a character is not valid. + */ +int sp_read_radix(sp_int* a, const char* in, int radix) +{ + int err = MP_OKAY; + + if ((a == NULL) || (in == NULL)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + #ifndef WOLFSSL_SP_INT_NEGATIVE + if (*in == '-') { + err = MP_VAL; + } + else + #endif + if (radix == 16) { + err = _sp_read_radix_16(a, in); + } + #ifdef WOLFSSL_SP_MATH_ALL + else if (radix == 10) { + err = _sp_read_radix_10(a, in); + } + #endif + else { + err = MP_VAL; + } + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || HAVE_ECC */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WC_MP_TO_RADIX) +/* Hex string characters. */ +static const char sp_hex_char[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/* Put the big-endian, hex string encoding of a into str. + * + * Assumes str is large enough for result. + * Use sp_radix_size() to calculate required length. + * + * @param [in] a SP integer to convert. + * @param [out] str String to hold hex string result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or str is NULL. + */ +int sp_tohex(sp_int* a, char* str) +{ + int err = MP_OKAY; + int i; + int j; + + if ((a == NULL) || (str == NULL)) { + err = MP_VAL; + } + if (err == MP_OKAY) { + /* quick out if its zero */ + if (sp_iszero(a) == MP_YES) { + #ifndef WC_DISABLE_RADIX_ZERO_PAD + *str++ = '0'; + #endif /* WC_DISABLE_RADIX_ZERO_PAD */ + *str++ = '0'; + *str = '\0'; + } + else { + #ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == MP_NEG) { + *str = '-'; + str++; + } + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + + i = a->used - 1; + #ifndef WC_DISABLE_RADIX_ZERO_PAD + for (j = SP_WORD_SIZE - 8; j >= 0; j -= 8) { + if (((a->dp[i] >> j) & 0xff) != 0) + break; + } + j += 4; + #else + for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4) { + if (((a->dp[i] >> j) & 0xf) != 0) + break; + } + #endif /* WC_DISABLE_RADIX_ZERO_PAD */ + for (; j >= 0; j -= 4) { + *(str++) = sp_hex_char[(a->dp[i] >> j) & 0xf]; + } + for (--i; i >= 0; i--) { + for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4) { + *(str++) = sp_hex_char[(a->dp[i] >> j) & 0xf]; + } + } + *str = '\0'; + } + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WC_MP_TO_RADIX */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) +/* Put the big-endian, decimal string encoding of a into str. + * + * Assumes str is large enough for result. + * Use sp_radix_size() to calculate required length. + * + * @param [in] a SP integer to convert. + * @param [out] str String to hold hex string result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or str is NULL. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_todecimal(sp_int* a, char* str) +{ + int err = MP_OKAY; + int i; + int j; + sp_int_digit d; + + if ((a == NULL) || (str == NULL)) { + err = MP_VAL; + } + /* quick out if its zero */ + else if (sp_iszero(a) == MP_YES) { + *str++ = '0'; + *str = '\0'; + } + else { + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif /* WOLFSSL_SMALL_STACK */ + + #ifdef WOLFSSL_SMALL_STACK + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + #endif /* WOLFSSL_SMALL_STACK */ + if (err == MP_OKAY) { + sp_copy(a, t); + + #ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == MP_NEG) { + *str = '-'; + str++; + } + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + + i = 0; + while (!sp_iszero(t)) { + sp_div_d(t, 10, t, &d); + str[i++] = '0' + d; + } + str[i] = '\0'; + + for (j = 0; j <= (i - 1) / 2; j++) { + int c = str[j]; + str[j] = str[i - 1 - j]; + str[i - 1 - j] = c; + } + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif /* WOLFSSL_SMALL_STACK */ + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_KEY_GEN || HAVE_COMP_KEY */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* Put the string version, big-endian, of a in str using the given radix. + * + * @param [in] a SP integer to convert. + * @param [out] str String to hold hex string result. + * @param [in] radix Base of character. + * Valid values: MP_RADIX_HEX, MP_RADIX_DEC. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or str is NULL, or radix not supported. + */ +int sp_toradix(sp_int* a, char* str, int radix) +{ + int err = MP_OKAY; + + if ((a == NULL) || (str == NULL)) { + err = MP_VAL; + } + else if (radix == MP_RADIX_HEX) { + err = sp_tohex(a, str); + } +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) + else if (radix == MP_RADIX_DEC) { + err = sp_todecimal(a, str); + } +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_KEY_GEN || HAVE_COMP_KEY */ + else { + err = MP_VAL; + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +#ifdef WOLFSSL_SP_MATH_ALL +/* Calculate the length of the string version, big-endian, of a using the given + * radix. + * + * @param [in] a SP integer to convert. + * @param [in] radix Base of character. + * Valid values: MP_RADIX_HEX, MP_RADIX_DEC. + * @param [out] size The number of characters in encoding. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or size is NULL, or radix not supported. + */ +int sp_radix_size(sp_int* a, int radix, int* size) +{ + int err = MP_OKAY; + + if ((a == NULL) || (size == NULL)) { + err = MP_VAL; + } + else if (radix == MP_RADIX_HEX) { + if (a->used == 0) { + #ifndef WC_DISABLE_RADIX_ZERO_PAD + /* 00 and '\0' */ + *size = 2 + 1; + #else + /* Zero and '\0' */ + *size = 1 + 1; + #endif /* WC_DISABLE_RADIX_ZERO_PAD */ + } + else { + int nibbles = (sp_count_bits(a) + 3) / 4; + #ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == MP_NEG) { + nibbles++; + } + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + #ifndef WC_DISABLE_RADIX_ZERO_PAD + if (nibbles & 1) { + nibbles++; + } + #endif /* WC_DISABLE_RADIX_ZERO_PAD */ + /* One more for \0 */ + *size = nibbles + 1; + } + } +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) + else if (radix == MP_RADIX_DEC) { + int i; + sp_int_digit d; + + /* quick out if its zero */ + if (sp_iszero(a) == MP_YES) { + /* Zero and '\0' */ + *size = 1 + 1; + } + else { + #ifdef WOLFSSL_SMALL_STACK + sp_int* t = NULL; + #else + sp_int t[1]; + #endif /* WOLFSSL_SMALL_STACK */ + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif /* WOLFSSL_SMALL_STACK */ + if (err == MP_OKAY) { + sp_copy(a, t); + + for (i = 0; !sp_iszero(t); i++) { + sp_div_d(t, 10, t, &d); + } + #ifdef WOLFSSL_SP_INT_NEGATIVE + if (a->sign == MP_NEG) { + i++; + } + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + /* One more for \0 */ + *size = i + 1; + } + + #ifdef WOLFSSL_SMALL_STACK + if (t != NULL) { + XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif /* WOLFSSL_SMALL_STACK */ + } + } +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_KEY_GEN || HAVE_COMP_KEY */ + else { + err = MP_VAL; + } + + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL */ + +/*************************************** + * Prime number generation and checking. + ***************************************/ + +#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_DH) || !defined(NO_DSA)) && \ + !defined(WC_NO_RNG) +/* Generate a random prime for RSA only. + * + * @param [out] r SP integer to hold result. + * @param [in] len Number of bytes in prime. + * @param [in] rng Random number generator. + * @param [in] heap Heap hint. Unused. + * + * @return MP_OKAY on success + * @return MP_VAL when r or rng is NULL, length is not supported or random + * number generator fails. + */ +int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap) +{ + static const int USE_BBS = 1; + int err = MP_OKAY, type; + int isPrime = MP_NO; +#ifdef WOLFSSL_SP_MATH_ALL + int bits; +#endif /* WOLFSSL_SP_MATH_ALL */ + + (void)heap; + + if ((r == NULL) || (rng == NULL)) { + err = MP_VAL; + } + + if (err == MP_OKAY) { + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } + else { + type = 0; + } + + #ifndef WOLFSSL_SP_MATH_ALL + /* For minimal maths, support only what's in SP and needed for DH. */ + #if defined(WOLFSSL_HAVE_SP_DH) && defined(WOLFSSL_KEY_GEN) + if (len == 32) { + } + else + #endif /* WOLFSSL_HAVE_SP_DH && WOLFSSL_KEY_GEN */ + /* Generate RSA primes that are half the modulus length. */ + #ifndef WOLFSSL_SP_NO_3072 + if ((len != 128) && (len != 192)) + #else + if (len != 128) + #endif /* WOLFSSL_SP_NO_3072 */ + { + err = MP_VAL; + } + #endif /* !WOLFSSL_SP_MATH_ALL */ + + #ifdef WOLFSSL_SP_INT_NEGATIVE + r->sign = MP_ZPOS; + #endif /* WOLFSSL_SP_INT_NEGATIVE */ + r->used = (len + SP_WORD_SIZEOF - 1) / SP_WORD_SIZEOF; + #ifdef WOLFSSL_SP_MATH_ALL + bits = (len * 8) & SP_WORD_MASK; + #endif /* WOLFSSL_SP_MATH_ALL */ + } + + /* Assume the candidate is probably prime and then test until + * it is proven composite. */ + while (err == MP_OKAY && isPrime == MP_NO) { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif /* SHOW_GEN */ + /* generate value */ + err = wc_RNG_GenerateBlock(rng, (byte*)r->dp, len); + if (err != 0) { + err = MP_VAL; + break; + } +#ifndef LITTLE_ENDIAN_ORDER + if (((len * 8) & SP_WORD_MASK) != 0) { + r->dp[r->used-1] >>= SP_WORD_SIZE - ((len * 8) & SP_WORD_MASK); + } +#endif /* LITTLE_ENDIAN_ORDER */ +#ifdef WOLFSSL_SP_MATH_ALL + if (bits > 0) { + r->dp[r->used - 1] &= (1L << bits) - 1; + } +#endif /* WOLFSSL_SP_MATH_ALL */ + + /* munge bits */ +#ifndef LITTLE_ENDIAN_ORDER + ((byte*)(r->dp + r->used - 1))[0] |= 0x80 | 0x40; +#else + ((byte*)r->dp)[len-1] |= 0x80 | 0x40; +#endif /* LITTLE_ENDIAN_ORDER */ + r->dp[0] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* test */ + /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance + * of a 1024-bit candidate being a false positive, when it is our + * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.) + * Using 8 because we've always used 8 */ + sp_prime_is_prime_ex(r, 8, &isPrime, rng); + } + + return err; +} +#endif /* WOLFSSL_KEY_GEN && (!NO_DH || !NO_DSA) && !WC_NO_RNG */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 * @@ -2046,18 +13071,22 @@ static int sp_cnt_lsb(sp_int* a) * Randomly the chance of error is no more than 1/4 and often * very much lower. * - * a SP integer to check. - * b SP integer small prime. - * result Whether a is likely prime: MP_YES or MP_NO. - * n1 SP integer operand. - * y SP integer operand. - * r SP integer operand. - * returns MP_VAL when a is not 1024, 2048, 1536 or 3072 and MP_OKAY otherwise. + * @param [in] a SP integer to check. + * @param [in] b SP integer that is a small prime. + * @param [out] result MP_YES when number is likey prime. + * MP_NO otherwise. + * @param [in] n1 SP integer temporary. + * @param [in] y SP integer temporary. + * @param [in] r SP integer temporary. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. */ -static int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result, - sp_int *n1, sp_int *y, sp_int *r) +static int sp_prime_miller_rabin_ex(sp_int* a, sp_int* b, int* result, + sp_int* n1, sp_int* y, sp_int* r) { - int s, j; + int s; + int j; int err = MP_OKAY; /* default */ @@ -2066,10 +13095,10 @@ static int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result, /* ensure b > 1 */ if (sp_cmp_d(b, 1) == MP_GT) { /* get n1 = a - 1 */ - sp_copy(a, n1); - sp_sub_d(n1, 1, n1); + (void)sp_copy(a, n1); + _sp_sub_d(n1, 1, n1); /* set 2**s * r = n1 */ - sp_copy(n1, r); + (void)sp_copy(n1, r); /* count the number of least significant bits * which are zero @@ -2080,8 +13109,6 @@ static int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result, sp_rshb(r, s, r); /* compute y = b**r mod a */ - sp_zero(y); - err = sp_exptmod(b, r, a, y); if (err == MP_OKAY) { @@ -2089,11 +13116,14 @@ static int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result, *result = MP_YES; /* if y != 1 and y != n1 do */ - if (sp_cmp_d(y, 1) != MP_EQ && sp_cmp(y, n1) != MP_EQ) { + if ((sp_cmp_d(y, 1) != MP_EQ) && (_sp_cmp(y, n1) != MP_EQ)) { j = 1; /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && sp_cmp(y, n1) != MP_EQ) { - sp_sqrmod(y, a, y); + while ((j <= (s - 1)) && (_sp_cmp(y, n1) != MP_EQ)) { + err = sp_sqrmod(y, a, y); + if (err != MP_OKAY) { + break; + } /* if y == 1 then composite */ if (sp_cmp_d(y, 1) == MP_EQ) { @@ -2104,8 +13134,9 @@ static int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result, } /* if y != n1 then composite */ - if (*result == MP_YES && sp_cmp(y, n1) != MP_EQ) + if ((*result == MP_YES) && (_sp_cmp(y, n1) != MP_EQ)) { *result = MP_NO; + } } } } @@ -2120,30 +13151,37 @@ static int sp_prime_miller_rabin_ex(sp_int * a, sp_int * b, int *result, * Randomly the chance of error is no more than 1/4 and often * very much lower. * - * a SP integer to check. - * b SP integer small prime. - * result Whether a is likely prime: MP_YES or MP_NO. - * returns MP_MEM when dynamic memory allocation fails, MP_VAL when a is not - * 1024, 2048, 1536 or 3072 and MP_OKAY otherwise. + * @param [in] a SP integer to check. + * @param [in] b SP integer that is a small prime. + * @param [out] result MP_YES when number is likey prime. + * MP_NO otherwise. + * + * @return MP_OKAY on success. + * @return MP_MEM when dynamic memory allocation fails. */ -static int sp_prime_miller_rabin(sp_int * a, sp_int * b, int *result) +static int sp_prime_miller_rabin(sp_int* a, sp_int* b, int* result) { int err = MP_OKAY; #ifndef WOLFSSL_SMALL_STACK - sp_int n1[1], y[1], r[1]; + sp_int n1[1]; + sp_int y[1]; + sp_int r[1]; #else - sp_int *n1 = NULL, *y, *r; -#endif + sp_int *n1 = NULL; + sp_int *y; + sp_int *r; +#endif /* WOLFSSL_SMALL_STACK */ #ifdef WOLFSSL_SMALL_STACK n1 = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); - if (n1 == NULL) + if (n1 == NULL) { err = MP_MEM; + } else { y = &n1[1]; r = &n1[2]; } -#endif +#endif /* WOLFSSL_SMALL_STACK */ if (err == MP_OKAY) { sp_init(n1); @@ -2158,17 +13196,32 @@ static int sp_prime_miller_rabin(sp_int * a, sp_int * b, int *result) } #ifdef WOLFSSL_SMALL_STACK - if (n1 != NULL) + if (n1 != NULL) { XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT); -#endif + } +#endif /* WOLFSSL_SMALL_STACK */ return err; } +#if SP_WORD_SIZE == 8 +/* Number of pre-computed primes. First n primes - fitting in a digit. */ +#define SP_PRIME_SIZE 54 + +static const sp_int_digit primes[SP_PRIME_SIZE] = { + 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11, 0x13, + 0x17, 0x1D, 0x1F, 0x25, 0x29, 0x2B, 0x2F, 0x35, + 0x3B, 0x3D, 0x43, 0x47, 0x49, 0x4F, 0x53, 0x59, + 0x61, 0x65, 0x67, 0x6B, 0x6D, 0x71, 0x7F, 0x83, + 0x89, 0x8B, 0x95, 0x97, 0x9D, 0xA3, 0xA7, 0xAD, + 0xB3, 0xB5, 0xBF, 0xC1, 0xC5, 0xC7, 0xD3, 0xDF, + 0xE3, 0xE5, 0xE9, 0xEF, 0xF1, 0xFB +}; +#else /* Number of pre-computed primes. First n primes. */ #define SP_PRIME_SIZE 256 -/* a few primes */ +/* The first 256 primes. */ static const sp_int_digit primes[SP_PRIME_SIZE] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, @@ -2206,20 +13259,22 @@ static const sp_int_digit primes[SP_PRIME_SIZE] = { 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 }; - +#endif /* Check whether a is prime. * Checks against a number of small primes and does t iterations of * Miller-Rabin. * - * a SP integer to check. - * t Number of iterations of Muller-Rabin to perform. - * result MP_YES when prime. - * MP_NO when not prime. - * returns MP_VAL when t is out of range, MP_MEM when dynamic memory allocation - * fails and otherwise MP_OKAY. + * @param [in] a SP integer to check. + * @param [in] t Number of iterations of Miller-Rabin test to perform. + * @param [out] result MP_YES when number is prime. + * MP_NO otherwise. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or result is NULL, or t is out of range. + * @return MP_MEM when dynamic memory allocation fails. */ -int sp_prime_is_prime(sp_int *a, int t, int* result) +int sp_prime_is_prime(sp_int* a, int t, int* result) { int err = MP_OKAY; int i; @@ -2228,20 +13283,27 @@ int sp_prime_is_prime(sp_int *a, int t, int* result) sp_int b[1]; #else sp_int *b = NULL; -#endif +#endif /* WOLFSSL_SMALL_STACK */ sp_int_digit d; - if (t <= 0 || t > SP_PRIME_SIZE) { + if ((a == NULL) || (result == NULL)) { + if (result != NULL) { + *result = MP_NO; + } + err = MP_VAL; + } + + if ((err == MP_OKAY) && ((t <= 0) || (t > SP_PRIME_SIZE))) { *result = MP_NO; err = MP_VAL; } - if (sp_isone(a)) { + if ((err == MP_OKAY) && sp_isone(a)) { *result = MP_NO; - return MP_OKAY; + haveRes = 1; } - if (err == MP_OKAY && a->used == 1) { + if ((err == MP_OKAY) && (!haveRes) && (a->used == 1)) { /* check against primes table */ for (i = 0; i < SP_PRIME_SIZE; i++) { if (sp_cmp_d(a, primes[i]) == MP_EQ) { @@ -2252,11 +13314,11 @@ int sp_prime_is_prime(sp_int *a, int t, int* result) } } - if (err == MP_OKAY && !haveRes) { + if ((err == MP_OKAY) && (!haveRes)) { /* do trial division */ for (i = 0; i < SP_PRIME_SIZE; i++) { err = sp_mod_d(a, primes[i], &d); - if (err != MP_OKAY || d == 0) { + if ((err != MP_OKAY) || (d == 0)) { *result = MP_NO; haveRes = 1; break; @@ -2265,27 +13327,30 @@ int sp_prime_is_prime(sp_int *a, int t, int* result) } #ifdef WOLFSSL_SMALL_STACK - if (err == MP_OKAY && !haveRes) { + if ((err == MP_OKAY) && (!haveRes)) { b = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); - if (b == NULL) + if (b == NULL) { err = MP_MEM; + } } -#endif +#endif /* WOLFSSL_SMALL_STACK */ - if (err == MP_OKAY && !haveRes) { + if ((err == MP_OKAY) && (!haveRes)) { /* now do 't' miller rabins */ sp_init(b); for (i = 0; i < t; i++) { sp_set(b, primes[i]); err = sp_prime_miller_rabin(a, b, result); - if (err != MP_OKAY || *result == MP_NO) + if ((err != MP_OKAY) || (*result == MP_NO)) { break; + } } } #ifdef WOLFSSL_SMALL_STACK - if (b != NULL) + if (b != NULL) { XFREE(b, NULL, DYNAMIC_TYPE_BIGINT); + } #endif return err; @@ -2295,13 +13360,15 @@ int sp_prime_is_prime(sp_int *a, int t, int* result) * Checks against a number of small primes and does t iterations of * Miller-Rabin. * - * a SP integer to check. - * t Number of iterations of Muller-Rabin to perform. - * result MP_YES when prime. - * MP_NO when not prime. - * rng Random number generator. - * returns MP_VAL when t is out of range, MP_MEM when dynamic memory allocation - * fails and otherwise MP_OKAY. + * @param [in] a SP integer to check. + * @param [in] t Number of iterations of Miller-Rabin test to perform. + * @param [out] result MP_YES when number is prime. + * MP_NO otherwise. + * @param [in] rng Random number generator for Miller-Rabin testing. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, result or rng is NULL. + * @return MP_MEM when dynamic memory allocation fails. */ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) { @@ -2311,24 +13378,30 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) int i; #ifndef WC_NO_RNG #ifndef WOLFSSL_SMALL_STACK - sp_int b[1], c[1], n1[1], y[1], r[1]; + sp_int b[1]; + sp_int c[1]; + sp_int n1[1]; + sp_int y[1]; + sp_int r[1]; #else - sp_int *b = NULL, *c = NULL, *n1 = NULL, *y = NULL, *r = NULL; - #endif - word32 baseSz; -#endif + sp_int *b = NULL; + sp_int *c = NULL; + sp_int *n1 = NULL; + sp_int *y = NULL; + sp_int *r = NULL; + #endif /* WOLFSSL_SMALL_STACK */ +#endif /* WC_NO_RNG */ - if (a == NULL || result == NULL || rng == NULL) + if ((a == NULL) || (result == NULL) || (rng == NULL)) { err = MP_VAL; - - if (err == MP_OKAY) { - if (sp_isone(a)) { - *result = MP_NO; - return MP_OKAY; - } } - if (err == MP_OKAY && a->used == 1) { + if ((err == MP_OKAY) && sp_isone(a)) { + ret = MP_NO; + haveRes = 1; + } + + if ((err == MP_OKAY) && (!haveRes) && (a->used == 1)) { /* check against primes table */ for (i = 0; i < SP_PRIME_SIZE; i++) { if (sp_cmp_d(a, primes[i]) == MP_EQ) { @@ -2339,13 +13412,13 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) } } - if (err == MP_OKAY && !haveRes) { + if ((err == MP_OKAY) && (!haveRes)) { sp_int_digit d; /* do trial division */ for (i = 0; i < SP_PRIME_SIZE; i++) { err = sp_mod_d(a, primes[i], &d); - if (err != MP_OKAY || d == 0) { + if ((err != MP_OKAY) || (d == 0)) { ret = MP_NO; haveRes = 1; break; @@ -2357,42 +13430,55 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) /* now do a miller rabin with up to t random numbers, this should * give a (1/4)^t chance of a false prime. */ #ifdef WOLFSSL_SMALL_STACK - if (err == MP_OKAY && !haveRes) { + if ((err == MP_OKAY) && (!haveRes)) { b = (sp_int*)XMALLOC(sizeof(sp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT); if (b == NULL) { err = MP_MEM; } else { - c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4]; + c = &b[1]; + n1 = &b[2]; + y = &b[3]; + r = &b[4]; } } - #endif + #endif /* WOLFSSL_SMALL_STACK */ - if (err == MP_OKAY && !haveRes) { + if ((err == MP_OKAY) && (!haveRes)) { sp_init(b); sp_init(c); sp_init(n1); sp_init(y); sp_init(r); - err = sp_sub_d(a, 2, c); + _sp_sub_d(a, 2, c); } - if (err == MP_OKAY && !haveRes) { - baseSz = (sp_count_bits(a) + 7) / 8; + if ((err == MP_OKAY) && (!haveRes)) { + int bits = sp_count_bits(a); + word32 baseSz = (bits + 7) / 8; + + bits &= SP_WORD_MASK; while (t > 0) { err = wc_RNG_GenerateBlock(rng, (byte*)b->dp, baseSz); - if (err != MP_OKAY) + if (err != MP_OKAY) { break; + } b->used = a->used; + /* Ensure the top word has no more bits than necessary. */ + if (bits > 0) { + b->dp[b->used - 1] &= (1L << bits) - 1; + } - if (sp_cmp_d(b, 2) != MP_GT || sp_cmp(b, c) != MP_LT) + if ((sp_cmp_d(b, 2) != MP_GT) || (_sp_cmp(b, c) != MP_LT)) { continue; + } err = sp_prime_miller_rabin_ex(a, b, &ret, n1, y, r); - if (err != MP_OKAY || ret == MP_NO) + if ((err != MP_OKAY) || (ret == MP_NO)) { break; + } t--; } @@ -2407,69 +13493,223 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) #ifdef WOLFSSL_SMALL_STACK if (b != NULL) XFREE(b, NULL, DYNAMIC_TYPE_BIGINT); - #endif + #endif /* WOLFSSL_SMALL_STACK */ #else (void)t; #endif /* !WC_NO_RNG */ - if (result != NULL) + if (result != NULL) { *result = ret; + } + return err; +} +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && defined(FP_ECC)) + +/* Calculates the Greatest Common Denominator (GCD) of a and b into r. + * + * @param [in] a SP integer of first operand. + * @param [in] b SP integer of second operand. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b or r is NULL. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_gcd(sp_int* a, sp_int* b, sp_int* r) +{ + int err = MP_OKAY; + + if ((a == NULL) || (b == NULL) || (r == NULL)) { + err = MP_VAL; + } + else if (sp_iszero(a)) { + if (sp_iszero(b)) { + err = MP_VAL; + } + else { + sp_copy(b, r); + } + } + else if (sp_iszero(b)) { + sp_copy(a, r); + } + else { + #ifdef WOLFSSL_SMALL_STACK + sp_int* u = NULL; + sp_int* v; + sp_int* t; + #else + sp_int u[1]; + sp_int v[1]; + sp_int t[1]; + #endif /* WOLFSSL_SMALL_STACK */ + + #ifdef WOLFSSL_SMALL_STACK + u = (sp_int*)XMALLOC(sizeof(sp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT); + if (u == NULL) { + err = MP_MEM; + } + else { + v = &u[1]; + t = &u[2]; + } + #endif /* WOLFSSL_SMALL_STACK */ + + if (err == MP_OKAY) { + sp_init(u); + sp_init(v); + sp_init(t); + + if (_sp_cmp(a, b) != MP_LT) { + sp_copy(b, u); + /* First iteration - u = a, v = b */ + if (b->used == 1) { + err = sp_mod_d(a, b->dp[0], &v->dp[0]); + if (err == MP_OKAY) { + v->used = (v->dp[0] != 0); + } + } + else { + err = sp_mod(a, b, v); + } + } + else { + sp_copy(a, u); + /* First iteration - u = b, v = a */ + if (a->used == 1) { + err = sp_mod_d(b, a->dp[0], &v->dp[0]); + if (err == MP_OKAY) { + v->used = (v->dp[0] != 0); + } + } + else { + err = sp_mod(b, a, v); + } + } + } + + if (err == MP_OKAY) { +#ifdef WOLFSSL_SP_INT_NEGATIVE + u->sign = MP_ZPOS; + v->sign = MP_ZPOS; +#endif /* WOLFSSL_SP_INT_NEGATIVE */ + + while (!sp_iszero(v)) { + if (v->used == 1) { + err = sp_mod_d(u, v->dp[0], &t->dp[0]); + if (err == MP_OKAY) { + t->used = (t->dp[0] != 0); + } + } + else { + sp_mod(u, v, t); + } + sp_copy(v, u); + sp_copy(t, v); + } + sp_copy(u, r); + } + + #ifdef WOLFSSL_SMALL_STACK + if (u != NULL) { + XFREE(u, NULL, DYNAMIC_TYPE_BIGINT); + } + #endif /* WOLFSSL_SMALL_STACK */ + } + return err; } -#ifndef NO_DH -int sp_exch(sp_int* a, sp_int* b) -{ - int err = MP_OKAY; -#ifndef WOLFSSL_SMALL_STACK - sp_int t[1]; -#else - sp_int *t = NULL; -#endif +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || (HAVE_ECC && FP_ECC) */ -#ifdef WOLFSSL_SMALL_STACK - t = (sp_int*)XMALLOC(sizeof(sp_int), NULL, DYNAMIC_TYPE_BIGINT); - if (t == NULL) - err = MP_MEM; -#endif +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) + +/* Calculates the Lowest Common Multiple (LCM) of a and b and stores in r. + * + * @param [in] a SP integer of first operand. + * @param [in] b SP integer of second operand. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a, b or r is NULL; or a or b is zero. + * @return MP_MEM when dynamic memory allocation fails. + */ +int sp_lcm(sp_int* a, sp_int* b, sp_int* r) +{ + int err = MP_OKAY; +#ifndef WOLFSSL_SMALL_STACK + sp_int t[2]; +#else + sp_int* t = NULL; +#endif /* WOLFSSL_SMALL_STACK */ + + if ((a == NULL) || (b == NULL) || (r == NULL)) { + err = MP_VAL; + } + + if ((err == MP_OKAY) && (mp_iszero(a) || mp_iszero(b))) { + err = MP_VAL; + } + #ifdef WOLFSSL_SMALL_STACK + if (err == MP_OKAY) { + t = (sp_int*)XMALLOC(sizeof(sp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT); + if (t == NULL) { + err = MP_MEM; + } + } + #endif /* WOLFSSL_SMALL_STACK */ if (err == MP_OKAY) { - *t = *a; - *a = *b; - *b = *t; + sp_init(&t[0]); + sp_init(&t[1]); + + err = sp_gcd(a, b, &t[0]); + if (err == MP_OKAY) { + if (_sp_cmp_abs(a, b) == MP_GT) { + err = sp_div(a, &t[0], &t[1], NULL); + if (err == MP_OKAY) { + err = sp_mul(b, &t[1], r); + } + } + else { + err = sp_div(b, &t[0], &t[1], NULL); + if (err == MP_OKAY) { + err = sp_mul(a, &t[1], r); + } + } + } } #ifdef WOLFSSL_SMALL_STACK - if (t != NULL) + if (t != NULL) { XFREE(t, NULL, DYNAMIC_TYPE_BIGINT); -#endif - return MP_OKAY; -} -#endif -#endif + } +#endif /* WOLFSSL_SMALL_STACK */ -#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) -/* Multiply a by digit n and put result into r. r = a * n - * - * a SP integer to be multiplied. - * n Number to multiply by. - * r SP integer result. - * returns MP_OKAY always. - */ -int sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r) -{ - _sp_mul_d(a, n, r, 0); - return MP_OKAY; + return err; } -#endif + +#endif /* !NO_RSA && WOLFSSL_KEY_GEN */ /* Returns the run time settings. * - * returns the settings value. + * @return Settings value. */ word32 CheckRunTimeSettings(void) { return CTC_SETTINGS; } -#endif /* WOLFSSL_SP_MATH */ +/* Returns the fast math settings. + * + * @return Setting - number of bits in a digit. + */ +word32 CheckRunTimeFastMath(void) +{ + return SP_WORD_SIZE; +} + +#endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */ diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index 8c16f2e7c..d8cf27bed 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -696,7 +696,7 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz); if (!r) r = mp_iszero(&temp2) == MP_YES ? SRP_BAD_KEY_E : 0; if (!r) r = mp_cmp(&temp2, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0; - if (!r) r = mp_sub(&temp2, &s, &temp1); + if (!r) r = mp_submod(&temp2, &s, &srp->N, &temp1); /* temp2 = a + u * x */ if (!r) r = mp_mulmod(&u, &srp->auth, &srp->N, &s); diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 9a9a6f219..282f4ae54 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -86,19 +86,19 @@ WOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, #endif -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL) /* math settings check */ word32 CheckRunTimeSettings(void) { return CTC_SETTINGS; } -#endif /* math settings size check */ word32 CheckRunTimeFastMath(void) { return FP_SIZE; } +#endif /* Functions */ @@ -2790,7 +2790,7 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) #endif if (fp_iszero(G)) { - fp_set(G, 0); + fp_set(Y, 0); return FP_OKAY; } @@ -3557,14 +3557,15 @@ int fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c) b += excess; } - /* If we know the endianness of this architecture, and we're using - 32-bit fp_digits, we can optimize this */ -#if (defined(LITTLE_ENDIAN_ORDER) || defined(BIG_ENDIAN_ORDER)) && \ - defined(FP_32BIT) - /* But not for both simultaneously */ +/* Not both endian simultaneously */ #if defined(LITTLE_ENDIAN_ORDER) && defined(BIG_ENDIAN_ORDER) #error Both LITTLE_ENDIAN_ORDER and BIG_ENDIAN_ORDER defined. #endif + +#if (defined(LITTLE_ENDIAN_ORDER) || defined(BIG_ENDIAN_ORDER)) +#ifdef FP_32BIT + /* If we know the endianness of this architecture, and we're using + 32-bit fp_digits, we can optimize this */ { unsigned char *pd = (unsigned char *)a->dp; @@ -3575,10 +3576,10 @@ int fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c) /* Use Duff's device to unroll the loop. */ int idx = (c - 1) & ~3; switch (c % 4) { - case 0: do { pd[idx+0] = *b++; // fallthrough - case 3: pd[idx+1] = *b++; // fallthrough - case 2: pd[idx+2] = *b++; // fallthrough - case 1: pd[idx+3] = *b++; // fallthrough + case 0: do { pd[idx+0] = *b++; FALL_THROUGH; + case 3: pd[idx+1] = *b++; FALL_THROUGH; + case 2: pd[idx+2] = *b++; FALL_THROUGH; + case 1: pd[idx+3] = *b++; idx -= 4; } while ((c -= 4) > 0); } @@ -3589,6 +3590,38 @@ int fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c) } #endif } +#elif defined(FP_64BIT) + /* If we know the endianness of this architecture, and we're using + 64-bit fp_digits, we can optimize this */ + { + unsigned char *pd = (unsigned char *)a->dp; + + a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit); + /* read the bytes in */ +#ifdef BIG_ENDIAN_ORDER + { + /* Use Duff's device to unroll the loop. */ + int idx = (c - 1) & ~7; + switch (c % 8) { + case 0: do { pd[idx+0] = *b++; FALL_THROUGH; + case 7: pd[idx+1] = *b++; FALL_THROUGH; + case 6: pd[idx+2] = *b++; FALL_THROUGH; + case 5: pd[idx+3] = *b++; FALL_THROUGH; + case 4: pd[idx+4] = *b++; FALL_THROUGH; + case 3: pd[idx+5] = *b++; FALL_THROUGH; + case 2: pd[idx+6] = *b++; FALL_THROUGH; + case 1: pd[idx+7] = *b++; + idx -= 8; + } while ((c -= 8) > 0); + } + } +#else + for (c -= 1; c >= 0; c -= 1) { + pd[c] = *b++; + } +#endif + } +#endif #else /* read the bytes in */ for (; c > 0; c--) { @@ -4721,21 +4754,21 @@ static int fp_prime_miller_rabin_ex(fp_int * a, fp_int * b, int *result, #if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \ defined(WOLFSSL_HAVE_SP_DH) #ifndef WOLFSSL_SP_NO_2048 - if (fp_count_bits(a) == 1024) + if (fp_count_bits(a) == 1024 && fp_isodd(a)) sp_ModExp_1024(b, r, a, y); - else if (fp_count_bits(a) == 2048) + else if (fp_count_bits(a) == 2048 && fp_isodd(a)) sp_ModExp_2048(b, r, a, y); else #endif #ifndef WOLFSSL_SP_NO_3072 - if (fp_count_bits(a) == 1536) + if (fp_count_bits(a) == 1536 && fp_isodd(a)) sp_ModExp_1536(b, r, a, y); - else if (fp_count_bits(a) == 3072) + else if (fp_count_bits(a) == 3072 && fp_isodd(a)) sp_ModExp_3072(b, r, a, y); else #endif #ifdef WOLFSSL_SP_4096 - if (fp_count_bits(a) == 4096) + if (fp_count_bits(a) == 4096 && fp_isodd(a)) sp_ModExp_4096(b, r, a, y); else #endif @@ -5401,6 +5434,9 @@ static int fp_read_radix(fp_int *a, const char *str, int radix) break; } } + if (y >= radix) { + return FP_VAL; + } /* if the char was found in the map * and is less than the given radix add it @@ -5520,7 +5556,12 @@ int mp_radix_size (mp_int *a, int radix, int *size) } if (fp_iszero(a) == MP_YES) { - *size = 2; +#ifndef WC_DISABLE_RADIX_ZERO_PAD + if (radix == 16) + *size = 3; + else +#endif + *size = 2; return FP_OKAY; } @@ -5591,6 +5632,10 @@ int mp_toradix (mp_int *a, char *str, int radix) /* quick out if its zero */ if (fp_iszero(a) == FP_YES) { +#ifndef WC_DISABLE_RADIX_ZERO_PAD + if (radix == 16) + *str++ = '0'; +#endif *str++ = '0'; *str = '\0'; return FP_OKAY; diff --git a/wolfcrypt/src/wolfmath.c b/wolfcrypt/src/wolfmath.c index 42243380b..1fec1e070 100644 --- a/wolfcrypt/src/wolfmath.c +++ b/wolfcrypt/src/wolfmath.c @@ -71,7 +71,7 @@ #endif -#if !defined(WOLFSSL_SP_MATH) +#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) int get_digit_count(mp_int* a) { if (a == NULL) @@ -156,7 +156,7 @@ int mp_rand(mp_int* a, int digits, WC_RNG* rng) ret = mp_set_bit(a, digits * DIGIT_BIT - 1); } #else -#if defined(WOLFSSL_SP_MATH) +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) if ((ret == MP_OKAY) && (digits > SP_INT_DIGITS)) #else if ((ret == MP_OKAY) && (digits > FP_SIZE)) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a4b67678a..cd85a33a5 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -1330,7 +1330,7 @@ initDefaultName(); #endif /* NO_MAIN_DRIVER */ /* helper to save DER, convert to PEM and save PEM */ -#if !defined(NO_ASN) && (defined(HAVE_ECC) || \ +#if !defined(NO_ASN) && (defined(HAVE_ECC) || !defined(NO_DSA) || \ (!defined(NO_RSA) && (defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN)))) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) @@ -3368,64 +3368,106 @@ static int hash_test(void) hashType = wc_OidGetHash(ret); if (exp_ret == 0 && hashType != typesGood[i]) - return -3348 - i; + return -3338 - i; #endif /* !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) */ } for (i = 0; i < (int)(sizeof(typesHashBad)/sizeof(*typesHashBad)); i++) { ret = wc_Hash(typesHashBad[i], data, sizeof(data), out, sizeof(out)); if (ret != BAD_FUNC_ARG && ret != BUFFER_E) - return -3358 - i; + return -3348 - i; } #if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) ret = wc_HashGetOID(WC_HASH_TYPE_MD2); #ifdef WOLFSSL_MD2 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3368; + return -3358; #else if (ret != HASH_TYPE_E) - return -3369; + return -3359; #endif hashType = wc_OidGetHash(646); /* Md2h */ #ifdef WOLFSSL_MD2 if (hashType != WC_HASH_TYPE_MD2) - return -3370; + return -3360; #else if (hashType != WC_HASH_TYPE_NONE) - return -3371; + return -3361; #endif ret = wc_HashGetOID(WC_HASH_TYPE_MD5_SHA); #ifndef NO_MD5 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3372; + return -3362; #else if (ret != HASH_TYPE_E) - return -3373; + return -3363; #endif ret = wc_HashGetOID(WC_HASH_TYPE_MD4); if (ret != BAD_FUNC_ARG) - return -3374; + return -3364; ret = wc_HashGetOID(WC_HASH_TYPE_NONE); if (ret != BAD_FUNC_ARG) - return -3375; + return -3365; hashType = wc_OidGetHash(0); if (hashType != WC_HASH_TYPE_NONE) - return -3376; + return -3366; #endif /* !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) */ ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD2); #ifdef WOLFSSL_MD2 + if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) + return -3367; +#else + if (ret != HASH_TYPE_E) + return -3368; +#endif + ret = wc_HashGetDigestSize(WC_HASH_TYPE_MD2); +#ifdef WOLFSSL_MD2 + if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) + return -3369; +#else + if (ret != HASH_TYPE_E) + return -3370; +#endif + + ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD4); +#ifndef NO_MD4 + if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) + return -3371; +#else + if (ret != HASH_TYPE_E) + return -3372; +#endif + ret = wc_HashGetDigestSize(WC_HASH_TYPE_MD4); +#ifndef NO_MD4 + if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) + return -3373; +#else + if (ret != HASH_TYPE_E) + return -3374; +#endif + ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD5_SHA); +#if !defined(NO_MD5) && !defined(NO_SHA) + if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) + return -3375; +#else + if (ret != HASH_TYPE_E) + return -3376; +#endif + + ret = wc_HashGetBlockSize(WC_HASH_TYPE_BLAKE2B); +#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) return -3377; #else if (ret != HASH_TYPE_E) return -3378; #endif - ret = wc_HashGetDigestSize(WC_HASH_TYPE_MD2); -#ifdef WOLFSSL_MD2 + ret = wc_HashGetDigestSize(WC_HASH_TYPE_BLAKE2B); +#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) return -3379; #else @@ -3433,94 +3475,52 @@ static int hash_test(void) return -3380; #endif - ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD4); -#ifndef NO_MD4 - if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3381; -#else - if (ret != HASH_TYPE_E) - return -3382; -#endif - ret = wc_HashGetDigestSize(WC_HASH_TYPE_MD4); -#ifndef NO_MD4 - if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3383; -#else - if (ret != HASH_TYPE_E) - return -3384; -#endif - ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD5_SHA); -#if !defined(NO_MD5) && !defined(NO_SHA) - if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3385; -#else - if (ret != HASH_TYPE_E) - return -3386; -#endif - - ret = wc_HashGetBlockSize(WC_HASH_TYPE_BLAKE2B); -#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) - if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3387; -#else - if (ret != HASH_TYPE_E) - return -3388; -#endif - ret = wc_HashGetDigestSize(WC_HASH_TYPE_BLAKE2B); -#if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) - if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3389; -#else - if (ret != HASH_TYPE_E) - return -3390; -#endif - ret = wc_HashGetBlockSize(WC_HASH_TYPE_NONE); if (ret != BAD_FUNC_ARG) - return -3391; + return -3381; ret = wc_HashGetDigestSize(WC_HASH_TYPE_NONE); if (ret != BAD_FUNC_ARG) - return -3392; + return -3382; #if !defined(NO_CERTS) && !defined(NO_ASN) #if defined(WOLFSSL_MD2) && !defined(HAVE_SELFTEST) ret = wc_GetCTC_HashOID(MD2); if (ret == 0) - return -3393; + return -3383; #endif #ifndef NO_MD5 ret = wc_GetCTC_HashOID(WC_MD5); if (ret == 0) - return -3394; + return -3384; #endif #ifndef NO_SHA ret = wc_GetCTC_HashOID(WC_SHA); if (ret == 0) - return -3395; + return -3385; #endif #ifdef WOLFSSL_SHA224 ret = wc_GetCTC_HashOID(WC_SHA224); if (ret == 0) - return -3396; + return -3386; #endif #ifndef NO_SHA256 ret = wc_GetCTC_HashOID(WC_SHA256); if (ret == 0) - return -3397; + return -3387; #endif #ifdef WOLFSSL_SHA384 ret = wc_GetCTC_HashOID(WC_SHA384); if (ret == 0) - return -3398; + return -3388; #endif #ifdef WOLFSSL_SHA512 ret = wc_GetCTC_HashOID(WC_SHA512); if (ret == 0) - return -3399; + return -3389; #endif ret = wc_GetCTC_HashOID(-1); if (ret != 0) - return -3400; + return -3390; #endif return 0; @@ -3578,30 +3578,30 @@ static int hmac_md5_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) { - return -3500; + return -3400; } ret = wc_HmacSetKey(&hmac, WC_MD5, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3501; + return -3401; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3502; + return -3402; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3503; + return -3403; if (XMEMCMP(hash, test_hmac[i].output, WC_MD5_DIGEST_SIZE) != 0) - return -3504 - i; + return -3404 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_MD5) != WC_MD5_DIGEST_SIZE) - return -3514; + return -3414; #endif return 0; @@ -3661,29 +3661,29 @@ static int hmac_sha_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3600; + return -3500; ret = wc_HmacSetKey(&hmac, WC_SHA, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3601; + return -3501; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3602; + return -3502; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3603; + return -3503; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA_DIGEST_SIZE) != 0) - return -3604 - i; + return -3504 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA) != WC_SHA_DIGEST_SIZE) - return -3614; + return -3514; #endif return 0; @@ -3756,29 +3756,29 @@ static int hmac_sha224_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3700; + return -3600; ret = wc_HmacSetKey(&hmac, WC_SHA224, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3701; + return -3601; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3702; + return -3602; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3703; + return -3603; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA224_DIGEST_SIZE) != 0) - return -3704 - i; + return -3604 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA224) != WC_SHA224_DIGEST_SIZE) - return -3714; + return -3614; #endif return 0; @@ -3856,36 +3856,36 @@ static int hmac_sha256_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3800 - i; + return -3700 - i; ret = wc_HmacSetKey(&hmac, WC_SHA256, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3810 - i; + return -3710 - i; if (test_hmac[i].input != NULL) { ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3820 - i; + return -3720 - i; } ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3830 - i; + return -3730 - i; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA256_DIGEST_SIZE) != 0) - return -3840 - i; + return -3740 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA256) != WC_SHA256_DIGEST_SIZE) - return -3850; + return -3750; if (wc_HmacSizeByType(20) != BAD_FUNC_ARG) - return -3851; + return -3751; #endif if (wolfSSL_GetHmacMaxSize() != WC_MAX_DIGEST_SIZE) - return -3852; + return -3752; return 0; } @@ -3969,29 +3969,29 @@ static int hmac_sha384_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3900; + return -3800; ret = wc_HmacSetKey(&hmac, WC_SHA384, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3901; + return -3801; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3902; + return -3802; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3903; + return -3803; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA384_DIGEST_SIZE) != 0) - return -3904 - i; + return -3804 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA384) != WC_SHA384_DIGEST_SIZE) - return -3914; + return -3814; #endif return 0; @@ -4080,29 +4080,29 @@ static int hmac_sha512_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -4000; + return -3900; ret = wc_HmacSetKey(&hmac, WC_SHA512, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -4001; + return -3901; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -4002; + return -3902; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -4003; + return -3903; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA512_DIGEST_SIZE) != 0) - return -4004 - i; + return -3904 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA512) != WC_SHA512_DIGEST_SIZE) - return -4014; + return -3914; #endif return 0; @@ -4250,21 +4250,21 @@ static int hmac_sha3_test(void) for (; i < iMax; i++) { for (j = 0; j < jMax; j++) { if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -4100; + return -4000; ret = wc_HmacSetKey(&hmac, hashType[j], (byte*)key[i], (word32)XSTRLEN(key[i])); if (ret != 0) - return -4101; + return -4001; ret = wc_HmacUpdate(&hmac, (byte*)input[i], (word32)XSTRLEN(input[i])); if (ret != 0) - return -4102; + return -4002; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -4103; + return -4003; if (XMEMCMP(hash, output[(i*jMax) + j], hashSz[j]) != 0) - return -4104; + return -4004; wc_HmacFree(&hmac); @@ -4274,7 +4274,7 @@ static int hmac_sha3_test(void) #ifndef HAVE_FIPS ret = wc_HmacSizeByType(hashType[j]); if (ret != hashSz[j]) - return -4105; + return -4005; #endif } } @@ -4395,28 +4395,28 @@ static int rc2_ecb_test(void) ret = wc_Rc2SetKey(&enc, (byte*)test_rc2[i].key, test_rc2[i].keyLen, NULL, test_rc2[i].effectiveKeyBits); if (ret != 0) { - return -4106; + return -4100; } /* ECB encrypt */ ret = wc_Rc2EcbEncrypt(&enc, cipher, (byte*)test_rc2[i].input, (word32)test_rc2[i].outLen); if (ret != 0) { - return -4107; + return -4101; } if (XMEMCMP(cipher, test_rc2[i].output, test_rc2[i].outLen)) { - return -4108; + return -4102; } /* ECB decrypt */ ret = wc_Rc2EcbDecrypt(&enc, plain, cipher, RC2_BLOCK_SIZE); if (ret != 0) { - return -4109; + return -4103; } if (XMEMCMP(plain, test_rc2[i].input, RC2_BLOCK_SIZE)) { - return -4110; + return -4104; } } @@ -4573,32 +4573,32 @@ static int rc2_cbc_test(void) ret = wc_Rc2SetKey(&rc2, (byte*)test_rc2[j].key, test_rc2[j].keyLen, (byte*)test_rc2[j].iv, test_rc2[j].effectiveKeyBits); if (ret != 0) { - return -4111; + return -4200; } ret = wc_Rc2CbcEncrypt(&rc2, cipher, (byte*)test_rc2[j].input, test_rc2[j].inLen); if (ret != 0) { - return -4112; + return -4201; } if (XMEMCMP(cipher, (byte*)test_rc2[j].output, test_rc2[j].outLen)) { - return -4113; + return -4202; } /* reset IV for decrypt, since overriden by encrypt operation */ ret = wc_Rc2SetIV(&rc2, (byte*)test_rc2[j].iv); if (ret != 0) { - return -4114; + return -4203; } ret = wc_Rc2CbcDecrypt(&rc2, plain, cipher, test_rc2[j].outLen); if (ret != 0) { - return -4115; + return -4204; } if (XMEMCMP(plain, (byte*)test_rc2[j].input, test_rc2[j].inLen)) { - return -4116; + return -4205; } } @@ -4671,9 +4671,9 @@ static int arc4_test(void) keylen = 4; if (wc_Arc4Init(&enc, HEAP_HINT, devId) != 0) - return -4200; + return -4400; if (wc_Arc4Init(&dec, HEAP_HINT, devId) != 0) - return -4201; + return -4401; wc_Arc4SetKey(&enc, (byte*)keys[i], keylen); wc_Arc4SetKey(&dec, (byte*)keys[i], keylen); @@ -4683,10 +4683,10 @@ static int arc4_test(void) wc_Arc4Process(&dec, plain, cipher, (word32)test_arc4[i].outLen); if (XMEMCMP(plain, test_arc4[i].input, test_arc4[i].outLen)) - return -4202 - i; + return -4402 - i; if (XMEMCMP(cipher, test_arc4[i].output, test_arc4[i].outLen)) - return -4212 - i; + return -4412 - i; wc_Arc4Free(&enc); wc_Arc4Free(&dec); @@ -4733,7 +4733,7 @@ static int hc128_test(void) HC128 *enc = (HC128 *)XMALLOC(sizeof *enc, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); HC128 *dec = (HC128 *)XMALLOC(sizeof *enc, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if ((! enc) || (! dec)) { - ERROR_OUT(-4322, out); + ERROR_OUT(-4500, out); } #endif @@ -4774,22 +4774,22 @@ static int hc128_test(void) XMEMCPY(plain, test_hc128[i].input, test_hc128[i].outLen); if (wc_Hc128_Process(enc, cipher, plain, (word32)test_hc128[i].outLen) != 0) { - ret = -4300; + ret = -4501; goto out; } if (wc_Hc128_Process(dec, plain, cipher, (word32)test_hc128[i].outLen) != 0) { - ret = -4301; + ret = -4502; goto out; } if (XMEMCMP(plain, test_hc128[i].input, test_hc128[i].outLen)) { - ret = -4302 - i; + ret = -4503 - i; goto out; } if (XMEMCMP(cipher, test_hc128[i].output, test_hc128[i].outLen)) { - ret = -4312 - i; + ret = -4513 - i; goto out; } } @@ -4875,10 +4875,10 @@ static int rabbit_test(void) wc_RabbitProcess(&dec, plain, cipher, (word32)test_rabbit[i].outLen); if (XMEMCMP(plain, test_rabbit[i].input, test_rabbit[i].outLen)) - return -4400 - i; + return -4600 - i; if (XMEMCMP(cipher, test_rabbit[i].output, test_rabbit[i].outLen)) - return -4410 - i; + return -4610 - i; } return 0; @@ -5131,10 +5131,10 @@ static int chacha_test(void) return ret; if (XMEMCMP(test_chacha[i], cipher, 8)) - return -4500 - i; + return -4700 - i; if (XMEMCMP(plain, input, 8)) - return -4510 - i; + return -4710 - i; } /* test of starting at a different counter @@ -5160,7 +5160,7 @@ static int chacha_test(void) return ret; if (XMEMCMP(plain + 64, sliver, 64)) - return -4520; + return -4720; #ifndef BENCH_EMBEDDED /* test of encrypting more data */ @@ -5183,10 +5183,10 @@ static int chacha_test(void) return ret; if (XMEMCMP(plain_big, input_big, CHACHA_BIG_TEST_SIZE)) - return -4521; + return -4721; if (XMEMCMP(cipher_big, cipher_big_result, CHACHA_BIG_TEST_SIZE)) - return -4522; + return -4722; for (i = 0; i < 18; ++i) { /* this will test all paths */ @@ -5210,10 +5210,10 @@ static int chacha_test(void) return ret; if (XMEMCMP(plain_big, input_big, block_size)) - return -4523-i; + return -4723-i; if (XMEMCMP(cipher_big, cipher_big_result, block_size)) - return -4524-i; + return -4724-i; } /* Streaming test */ @@ -5222,40 +5222,40 @@ static int chacha_test(void) ret = wc_Chacha_SetKey(&enc, keys[0], keySz); if (ret != 0) - return -4550; + return -4725; ret = wc_Chacha_SetKey(&dec, keys[0], keySz); if (ret != 0) - return -4551; + return -4726; ret = wc_Chacha_SetIV(&enc, ivs[2], 0); if (ret != 0) - return -4552; + return -4727; ret = wc_Chacha_SetIV(&dec, ivs[2], 0); if (ret != 0) - return -4553; + return -4728; for (j = 0; j < CHACHA_BIG_TEST_SIZE - i; j+= i) { ret = wc_Chacha_Process(&enc, cipher_big + j, plain_big + j, i); if (ret != 0) - return -4554; + return -4729; ret = wc_Chacha_Process(&dec, plain_big + j, cipher_big + j, i); if (ret != 0) - return -4555; + return -4730; } rem = CHACHA_BIG_TEST_SIZE - j; ret = wc_Chacha_Process(&enc, cipher_big + j, plain_big + j, rem); if (ret != 0) - return -4556; + return -4731; ret = wc_Chacha_Process(&dec, plain_big + j, cipher_big + j, rem); if (ret != 0) - return -4557; + return -4732; if (XMEMCMP(plain_big, input_big, CHACHA_BIG_TEST_SIZE)) - return -4558; + return -4733; if (XMEMCMP(cipher_big, cipher_big_result, CHACHA_BIG_TEST_SIZE)) - return -4559; + return -4734; } #ifdef WOLFSSL_SMALL_STACK @@ -5436,33 +5436,33 @@ static int poly1305_test(void) for (i = 0; i < 6; i++) { ret = wc_Poly1305SetKey(&enc, keys[i], 32); if (ret != 0) - return -4600 - i; + return -4800 - i; ret = wc_Poly1305Update(&enc, msgs[i], szm[i]); if (ret != 0) - return -4610 - i; + return -4810 - i; ret = wc_Poly1305Final(&enc, tag); if (ret != 0) - return -4620 - i; + return -4820 - i; if (XMEMCMP(tag, tests[i], sizeof(tag))) - return -4630 - i; + return -4830 - i; } /* Check TLS MAC function from 2.8.2 https://tools.ietf.org/html/rfc7539 */ XMEMSET(tag, 0, sizeof(tag)); ret = wc_Poly1305SetKey(&enc, key4, sizeof(key4)); if (ret != 0) - return -4640; + return -4840; ret = wc_Poly1305_MAC(&enc, additional, sizeof(additional), (byte*)msg4, sizeof(msg4), tag, sizeof(tag)); if (ret != 0) - return -4641; + return -4841; if (XMEMCMP(tag, correct4, sizeof(tag))) - return -4642; + return -4842; /* Check fail of TLS MAC function if altering additional data */ XMEMSET(tag, 0, sizeof(tag)); @@ -5470,10 +5470,10 @@ static int poly1305_test(void) ret = wc_Poly1305_MAC(&enc, additional, sizeof(additional), (byte*)msg4, sizeof(msg4), tag, sizeof(tag)); if (ret != 0) - return -4643; + return -4843; if (XMEMCMP(tag, correct4, sizeof(tag)) == 0) - return -4644; + return -4844; return 0; @@ -5669,53 +5669,53 @@ static int chacha20_poly1305_aead_test(void) err = wc_ChaCha20Poly1305_Encrypt(NULL, iv1, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4700; + return -4900; err = wc_ChaCha20Poly1305_Encrypt(key1, NULL, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4701; + return -4901; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), NULL, sizeof(plaintext1), generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4702; + return -4902; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), NULL, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4703; + return -4903; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), generatedCiphertext, NULL); if (err != BAD_FUNC_ARG) - return -4704; + return -4904; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1, 0, generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4705; + return -4905; /* Decrypt */ err = wc_ChaCha20Poly1305_Decrypt(NULL, iv2, aad2, sizeof(aad2), cipher2, sizeof(cipher2), authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4706; + return -4906; err = wc_ChaCha20Poly1305_Decrypt(key2, NULL, aad2, sizeof(aad2), cipher2, sizeof(cipher2), authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4707; + return -4907; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), NULL, sizeof(cipher2), authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4708; + return -4908; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2, sizeof(cipher2), NULL, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4709; + return -4909; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2, sizeof(cipher2), authTag2, NULL); if (err != BAD_FUNC_ARG) - return -4710; + return -4910; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2, 0, authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4711; + return -4911; /* Test #1 */ @@ -5729,10 +5729,10 @@ static int chacha20_poly1305_aead_test(void) /* -- Check the ciphertext and authtag */ if (XMEMCMP(generatedCiphertext, cipher1, sizeof(cipher1))) { - return -4712; + return -4912; } if (XMEMCMP(generatedAuthTag, authTag1, sizeof(authTag1))) { - return -4713; + return -4913; } /* -- Verify decryption works */ @@ -5744,7 +5744,7 @@ static int chacha20_poly1305_aead_test(void) return err; } if (XMEMCMP(generatedPlaintext, plaintext1, sizeof(plaintext1))) { - return -4714; + return -4914; } @@ -5763,10 +5763,10 @@ static int chacha20_poly1305_aead_test(void) /* -- Check the ciphertext and authtag */ if (XMEMCMP(generatedCiphertext, cipher2, sizeof(cipher2))) { - return -4715; + return -4915; } if (XMEMCMP(generatedAuthTag, authTag2, sizeof(authTag2))) { - return -4716; + return -4916; } /* -- Verify decryption works */ @@ -5779,7 +5779,7 @@ static int chacha20_poly1305_aead_test(void) } if (XMEMCMP(generatedPlaintext, plaintext2, sizeof(plaintext2))) { - return -4717; + return -4917; } @@ -5787,67 +5787,67 @@ static int chacha20_poly1305_aead_test(void) err = wc_ChaCha20Poly1305_Init(NULL, key1, iv1, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) - return -4718; + return -4918; err = wc_ChaCha20Poly1305_Init(&aead, NULL, iv1, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) - return -4719; + return -4919; err = wc_ChaCha20Poly1305_Init(&aead, key1, NULL, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) - return -4720; + return -4920; err = wc_ChaCha20Poly1305_UpdateAad(NULL, aad1, sizeof(aad1)); if (err != BAD_FUNC_ARG) - return -4721; + return -4921; err = wc_ChaCha20Poly1305_UpdateAad(&aead, NULL, sizeof(aad1)); if (err != BAD_FUNC_ARG) - return -4722; + return -4922; err = wc_ChaCha20Poly1305_UpdateData(NULL, generatedPlaintext, generatedPlaintext, sizeof(plaintext1)); if (err != BAD_FUNC_ARG) - return -4723; + return -4923; err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext, NULL, sizeof(plaintext1)); if (err != BAD_FUNC_ARG) - return -4724; + return -4924; err = wc_ChaCha20Poly1305_UpdateData(&aead, NULL, generatedPlaintext, sizeof(plaintext1)); if (err != BAD_FUNC_ARG) - return -4725; + return -4925; err = wc_ChaCha20Poly1305_Final(NULL, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4726; + return -4926; err = wc_ChaCha20Poly1305_Final(&aead, NULL); if (err != BAD_FUNC_ARG) - return -4727; + return -4927; /* AEAD init/update/final - bad state tests */ - /* clear struct - make valgrind happy to resolve - "Conditional jump or move depends on uninitialised value(s)". + /* clear struct - make valgrind happy to resolve + "Conditional jump or move depends on uninitialised value(s)". The enum is "int" size and aead.state is "byte" */ /* The wc_ChaCha20Poly1305_Init function does this normally */ XMEMSET(&aead, 0, sizeof(aead)); aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != BAD_STATE_E) - return -4728; + return -4928; aead.state = CHACHA20_POLY1305_STATE_DATA; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != BAD_STATE_E) - return -4729; + return -4929; aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext, generatedPlaintext, sizeof(plaintext1)); if (err != BAD_STATE_E) - return -4730; + return -4930; aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag); if (err != BAD_STATE_E) - return -4731; + return -4931; aead.state = CHACHA20_POLY1305_STATE_READY; err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag); if (err != BAD_STATE_E) - return -4732; + return -4932; XMEMSET(generatedCiphertext, 0, sizeof(generatedCiphertext)); XMEMSET(generatedAuthTag, 0, sizeof(generatedAuthTag)); @@ -5857,10 +5857,10 @@ static int chacha20_poly1305_aead_test(void) err = wc_ChaCha20Poly1305_Init(&aead, key1, iv1, CHACHA20_POLY1305_AEAD_ENCRYPT); if (err != 0) - return -4733; + return -4933; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != 0) - return -4734; + return -4934; #ifdef TEST_SMALL_CHACHA_CHUNKS /* test doing data in smaller chunks */ for (testLen=0; testLen= 2)) @@ -9481,7 +9481,7 @@ static int gmac_test(void) wc_GmacSetKey(&gmac, k2, sizeof(k2)); wc_GmacUpdate(&gmac, iv2, sizeof(iv2), a2, sizeof(a2), tag, sizeof(t2)); if (XMEMCMP(t2, tag, sizeof(t2)) != 0) - return -6201; + return -6401; #if !defined(WC_NO_RNG) && !defined(HAVE_SELFTEST) && !defined(NO_AES_DECRYPT) { @@ -9496,30 +9496,30 @@ static int gmac_test(void) #ifndef HAVE_FIPS if (wc_InitRng_ex(&rng, HEAP_HINT, devId) != 0) - return -6202; + return -6402; #else if (wc_InitRng(&rng) != 0) - return -6203; + return -6403; #endif if (wc_GmacVerify(k1, sizeof(k1), iv1, sizeof(iv1), a1, sizeof(a1), t1, sizeof(t1)) != 0) - return -6204; + return -6404; if (wc_GmacVerify(k1, sizeof(k1), iv1, sizeof(iv1), a1, sizeof(a1), badT, sizeof(badT)) != AES_GCM_AUTH_E) - return -6205; + return -6405; if (wc_GmacVerify(k2, sizeof(k2), iv2, sizeof(iv2), a2, sizeof(a2), t2, sizeof(t2)) != 0) - return -6206; + return -6406; XMEMSET(tag, 0, sizeof(tag)); XMEMSET(iv, 0, sizeof(iv)); if (wc_Gmac(k1, sizeof(k1), iv, sizeof(iv), a1, sizeof(a1), tag, sizeof(tag), &rng) != 0) - return -6207; + return -6407; if (wc_GmacVerify(k1, sizeof(k1), iv, sizeof(iv), a1, sizeof(a1), tag, sizeof(tag)) != 0) - return -6208; + return -6408; wc_FreeRng(&rng); } #endif /* !WC_NO_RNG && !HAVE_SELFTEST && !NO_AES_DECRYPT */ @@ -9626,37 +9626,37 @@ static int aesccm_test(void) result = wc_AesCcmSetKey(&enc, k, sizeof(k)); if (result != 0) - return -6300; + return -6500; /* AES-CCM encrypt and decrypt both use AES encrypt internally */ result = wc_AesCcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), t2, sizeof(t2), a, sizeof(a)); if (result != 0) - return -6301; + return -6501; if (XMEMCMP(c, c2, sizeof(c2))) - return -6302; + return -6502; if (XMEMCMP(t, t2, sizeof(t2))) - return -6303; + return -6503; result = wc_AesCcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv), t2, sizeof(t2), a, sizeof(a)); if (result != 0) - return -6304; + return -6504; if (XMEMCMP(p, p2, sizeof(p2))) - return -6305; + return -6505; /* Test the authentication failure */ t2[0]++; /* Corrupt the authentication tag. */ result = wc_AesCcmDecrypt(&enc, p2, c, sizeof(p2), iv, sizeof(iv), t2, sizeof(t2), a, sizeof(a)); if (result == 0) - return -6306; + return -6506; /* Clear c2 to compare against p2. p2 should be set to zero in case of * authentication fail. */ XMEMSET(c2, 0, sizeof(c2)); if (XMEMCMP(p2, c2, sizeof(p2))) - return -6307; + return -6507; XMEMSET(&enc, 0, sizeof(Aes)); /* clear context */ XMEMSET(t2, 0, sizeof(t2)); @@ -9668,32 +9668,32 @@ static int aesccm_test(void) /* selftest build does not have wc_AesCcmSetNonce() or * wc_AesCcmEncrypt_ex() */ if (wc_AesCcmSetKey(&enc, k, sizeof(k)) != 0) - return -6308; + return -6508; if (wc_AesCcmSetNonce(&enc, iv, sizeof(iv)) != 0) - return -6309; + return -6509; if (wc_AesCcmEncrypt_ex(&enc, c2, p, sizeof(c2), iv2, sizeof(iv2), t2, sizeof(t2), a, sizeof(a)) != 0) - return -6310; + return -6510; if (XMEMCMP(iv, iv2, sizeof(iv2))) - return -6311; + return -6511; if (XMEMCMP(c, c2, sizeof(c2))) - return -6312; + return -6512; if (XMEMCMP(t, t2, sizeof(t2))) - return -6313; + return -6513; #endif #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) /* test fail on invalid IV sizes */ result = wc_AesCcmSetKey(&enc, k, sizeof(k)); if (result != 0) - return -6314; + return -6514; /* AES-CCM encrypt and decrypt both use AES encrypt internally */ result = wc_AesCcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), t2, 1, a, sizeof(a)); if (result == 0) { - return -6315; + return -6515; } #endif @@ -9701,18 +9701,18 @@ static int aesccm_test(void) result = wc_AesCcmEncrypt(&enc, cl2, pl, sizeof(cl2), iv, sizeof(iv), tl2, sizeof(tl2), a, sizeof(a)); if (result != 0) - return -6301; + return -6516; if (XMEMCMP(cl, cl2, sizeof(cl2))) - return -6302; + return -6517; if (XMEMCMP(tl, tl2, sizeof(tl2))) - return -6303; + return -6518; result = wc_AesCcmDecrypt(&enc, pl2, cl2, sizeof(pl2), iv, sizeof(iv), tl2, sizeof(tl2), a, sizeof(a)); if (result != 0) - return -6304; + return -6519; if (XMEMCMP(pl, pl2, sizeof(pl2))) - return -6305; + return -6520; return 0; } @@ -9901,20 +9901,20 @@ static int aeskeywrap_test(void) output, sizeof(output), NULL); if ( (wrapSz < 0) || (wrapSz != (int)test_wrap[i].verifyLen) ) - return -6400; + return -6600; if (XMEMCMP(output, test_wrap[i].verify, test_wrap[i].verifyLen) != 0) - return -6401; + return -6601; plainSz = wc_AesKeyUnWrap((byte*)test_wrap[i].kek, test_wrap[i].kekLen, output, wrapSz, plain, sizeof(plain), NULL); if ( (plainSz < 0) || (plainSz != (int)test_wrap[i].dataLen) ) - return -6402; + return -6602; if (XMEMCMP(plain, test_wrap[i].data, test_wrap[i].dataLen) != 0) - return -6403 - i; + return -6603 - i; } return 0; @@ -10107,24 +10107,24 @@ static int camellia_test(void) /* Setting the IV and checking it was actually set. */ ret = wc_CamelliaSetIV(&cam, ivc); if (ret != 0 || XMEMCMP(cam.reg, ivc, CAMELLIA_BLOCK_SIZE)) - return -6500; + return -6700; /* Setting the IV to NULL should be same as all zeros IV */ if (wc_CamelliaSetIV(&cam, NULL) != 0 || XMEMCMP(cam.reg, ive, CAMELLIA_BLOCK_SIZE)) - return -6501; + return -6701; /* First parameter should never be null */ if (wc_CamelliaSetIV(NULL, NULL) == 0) - return -6502; + return -6702; /* First parameter should never be null, check it fails */ if (wc_CamelliaSetKey(NULL, k1, sizeof(k1), NULL) == 0) - return -6503; + return -6703; /* Key should have a size of 16, 24, or 32 */ if (wc_CamelliaSetKey(&cam, k1, 0, NULL) == 0) - return -6504; + return -6704; return 0; } @@ -10201,14 +10201,14 @@ static int idea_test(void) NULL, IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6600; + return -6800; } /* Data encryption */ ret = wc_IdeaCipher(&idea, data, v1_plain[i]); if (ret != 0 || XMEMCMP(&v1_cipher[i], data, IDEA_BLOCK_SIZE)) { printf("Bad encryption\n"); - return -6601; + return -6801; } /* Set decryption key */ @@ -10217,14 +10217,14 @@ static int idea_test(void) NULL, IDEA_DECRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (dec) failed\n"); - return -6602; + return -6802; } /* Data decryption */ ret = wc_IdeaCipher(&idea, data, data); if (ret != 0 || XMEMCMP(v1_plain[i], data, IDEA_BLOCK_SIZE)) { printf("Bad decryption\n"); - return -6603; + return -6803; } /* Set encryption key */ @@ -10233,7 +10233,7 @@ static int idea_test(void) v_key[i], IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6604; + return -6804; } XMEMSET(msg_enc, 0, sizeof(msg_enc)); @@ -10241,7 +10241,7 @@ static int idea_test(void) (word32)XSTRLEN(message)+1); if (ret != 0) { printf("wc_IdeaCbcEncrypt failed\n"); - return -6605; + return -6805; } /* Set decryption key */ @@ -10250,7 +10250,7 @@ static int idea_test(void) v_key[i], IDEA_DECRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (dec) failed\n"); - return -6606; + return -6806; } XMEMSET(msg_dec, 0, sizeof(msg_dec)); @@ -10258,12 +10258,12 @@ static int idea_test(void) (word32)XSTRLEN(message)+1); if (ret != 0) { printf("wc_IdeaCbcDecrypt failed\n"); - return -6607; + return -6807; } if (XMEMCMP(message, msg_dec, (word32)XSTRLEN(message))) { printf("Bad CBC decryption\n"); - return -6608; + return -6808; } } @@ -10274,7 +10274,7 @@ static int idea_test(void) NULL, IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6609; + return -6809; } /* 100 times data encryption */ @@ -10282,13 +10282,13 @@ static int idea_test(void) for (j = 0; j < 100; j++) { ret = wc_IdeaCipher(&idea, data, data); if (ret != 0) { - return -6610; + return -6810; } } if (XMEMCMP(v1_cipher_100[i], data, IDEA_BLOCK_SIZE)) { printf("Bad encryption (100 times)\n"); - return -6611; + return -6811; } /* 1000 times data encryption */ @@ -10296,13 +10296,13 @@ static int idea_test(void) for (j = 0; j < 1000; j++) { ret = wc_IdeaCipher(&idea, data, data); if (ret != 0) { - return -6612; + return -6812; } } if (XMEMCMP(v1_cipher_1000[i], data, IDEA_BLOCK_SIZE)) { printf("Bad encryption (100 times)\n"); - return -6613; + return -6813; } } @@ -10320,30 +10320,30 @@ static int idea_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -6614; + return -6814; for (i = 0; i < 1000; i++) { /* random key */ ret = wc_RNG_GenerateBlock(&rng, key, sizeof(key)); if (ret != 0) - return -6615; + return -6815; /* random iv */ ret = wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)); if (ret != 0) - return -6616; + return -6816; /* random data */ ret = wc_RNG_GenerateBlock(&rng, rnd, sizeof(rnd)); if (ret != 0) - return -6617; + return -6817; /* Set encryption key */ XMEMSET(&idea, 0, sizeof(Idea)); ret = wc_IdeaSetKey(&idea, key, IDEA_KEY_SIZE, iv, IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6618; + return -6818; } /* Data encryption */ @@ -10351,7 +10351,7 @@ static int idea_test(void) ret = wc_IdeaCbcEncrypt(&idea, enc, rnd, sizeof(rnd)); if (ret != 0) { printf("wc_IdeaCbcEncrypt failed\n"); - return -6619; + return -6819; } /* Set decryption key */ @@ -10359,7 +10359,7 @@ static int idea_test(void) ret = wc_IdeaSetKey(&idea, key, IDEA_KEY_SIZE, iv, IDEA_DECRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6620; + return -6820; } /* Data decryption */ @@ -10367,12 +10367,12 @@ static int idea_test(void) ret = wc_IdeaCbcDecrypt(&idea, dec, enc, sizeof(enc)); if (ret != 0) { printf("wc_IdeaCbcDecrypt failed\n"); - return -6621; + return -6821; } if (XMEMCMP(rnd, dec, sizeof(rnd))) { printf("Bad CBC decryption\n"); - return -6622; + return -6822; } } @@ -10386,7 +10386,7 @@ static int idea_test(void) #ifdef HAVE_XCHACHA static int XChaCha_test(void) { - int ret = -1; + int ret = -6830; static const byte Plaintext[] = { 0x54, 0x68, 0x65, 0x20, 0x64, 0x68, 0x6f, 0x6c, 0x65, 0x20, 0x28, 0x70, 0x72, 0x6f, 0x6e, 0x6f, /* The dhole (prono */ @@ -10456,25 +10456,25 @@ static int XChaCha_test(void) { ret = wc_XChacha_SetKey(chacha, Key, sizeof Key, IV, sizeof IV, 0); if (ret < 0) - ERROR_OUT(-4770, out); + ERROR_OUT(-6831, out); ret = wc_Chacha_Process(chacha, buf1, Plaintext, sizeof Plaintext); if (ret < 0) - ERROR_OUT(-4771, out); + ERROR_OUT(-6832, out); if (XMEMCMP(buf1, Ciphertext, sizeof Plaintext)) - ERROR_OUT(-4772, out); + ERROR_OUT(-6833, out); ret = wc_XChacha_SetKey(chacha, Key, sizeof Key, IV, sizeof IV, 0); if (ret < 0) - ERROR_OUT(-4773, out); + ERROR_OUT(-6834, out); ret = wc_Chacha_Process(chacha, buf2, buf1, sizeof Plaintext); if (ret < 0) - ERROR_OUT(-4774, out); + ERROR_OUT(-6835, out); if (XMEMCMP(buf2, Plaintext, sizeof Plaintext)) - ERROR_OUT(-4775, out); + ERROR_OUT(-6836, out); out: @@ -10545,13 +10545,13 @@ static int XChaCha20Poly1305_test(void) { Key, sizeof Key); if (ret < 0) - ERROR_OUT(-4760, out); + ERROR_OUT(-6840, out); if (XMEMCMP(buf1, Ciphertext, sizeof Plaintext)) - ERROR_OUT(-4761, out); + ERROR_OUT(-6841, out); if (XMEMCMP(buf1 + sizeof Plaintext, Tag, CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE)) - ERROR_OUT(-4762, out); + ERROR_OUT(-6842, out); ret = wc_XChaCha20Poly1305_Decrypt(buf2, sizeof Plaintext, buf1, sizeof Plaintext + sizeof Tag, @@ -10560,10 +10560,10 @@ static int XChaCha20Poly1305_test(void) { Key, sizeof Key); if (ret < 0) - ERROR_OUT(-4763, out); + ERROR_OUT(-6843, out); if (XMEMCMP(buf2, Plaintext, sizeof Plaintext)) - ERROR_OUT(-4764, out); + ERROR_OUT(-6844, out); out: @@ -10586,7 +10586,7 @@ static int _rng_test(WC_RNG* rng, int errorOffset) ret = wc_RNG_GenerateBlock(rng, block, sizeof(block)); if (ret != 0) { - ret = -6623; + ret = -6850; goto exit; } @@ -10598,36 +10598,36 @@ static int _rng_test(WC_RNG* rng, int errorOffset) } /* All zeros count check */ if (ret >= (int)sizeof(block)) { - ret = -6624; + ret = -6851; goto exit; } ret = wc_RNG_GenerateByte(rng, block); if (ret != 0) { - ret = -6625; + ret = -6852; goto exit; } /* Parameter validation testing. */ ret = wc_RNG_GenerateBlock(NULL, block, sizeof(block)); if (ret != BAD_FUNC_ARG) { - ret = -6626; + ret = -6853; goto exit; } ret = wc_RNG_GenerateBlock(rng, NULL, sizeof(block)); if (ret != BAD_FUNC_ARG) { - ret = -6627; + ret = -6854; goto exit; } ret = wc_RNG_GenerateByte(NULL, block); if (ret != BAD_FUNC_ARG) { - ret = -6628; + ret = -6855; goto exit; } ret = wc_RNG_GenerateByte(rng, NULL); if (ret != BAD_FUNC_ARG) { - ret = -6629; + ret = -6856; goto exit; } @@ -10654,7 +10654,7 @@ static int random_rng_test(void) #else ret = wc_InitRng(rng); #endif - if (ret != 0) return -6700; + if (ret != 0) return -6900; ret = _rng_test(rng, -6300); @@ -10668,7 +10668,7 @@ static int random_rng_test(void) byte nonce[8] = { 0 }; /* Test dynamic RNG. */ rng = wc_rng_new(nonce, (word32)sizeof(nonce), HEAP_HINT); - if (rng == NULL) return -6701; + if (rng == NULL) return -6901; ret = _rng_test(rng, -6310); @@ -10738,19 +10738,19 @@ static int random_test(void) ret = wc_RNG_HealthTest(0, test1Entropy, sizeof(test1Entropy), NULL, 0, output, sizeof(output)); if (ret != 0) - return -6800; + return -7000; if (XMEMCMP(test1Output, output, sizeof(output)) != 0) - return -6801; + return -7001; ret = wc_RNG_HealthTest(1, test2EntropyA, sizeof(test2EntropyA), test2EntropyB, sizeof(test2EntropyB), output, sizeof(output)); if (ret != 0) - return -6802; + return -7002; if (XMEMCMP(test2Output, output, sizeof(output)) != 0) - return -6803; + return -7003; /* Basic RNG generate block test */ if ((ret = random_rng_test()) != 0) @@ -10767,7 +10767,7 @@ static int random_test(void) XMEMSET(output, 1, outputSz); ret = wc_RNG_TestSeed(output, outputSz); if (ret == 0) - return -6804; + return -7004; /* Every byte of the entropy scratch is different, * entropy is a single byte that shouldn't match. */ @@ -10776,14 +10776,14 @@ static int random_test(void) output[i] = (byte)i; ret = wc_RNG_TestSeed(output, outputSz); if (ret != 0) - return -6805; + return -7005; outputSz = sizeof(output); for (i = 0; i < outputSz; i++) output[i] = (byte)i; ret = wc_RNG_TestSeed(output, outputSz); if (ret != 0) - return -6806; + return -7006; } #endif return 0; @@ -10813,7 +10813,7 @@ static int simple_mem_test(int sz) b = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (b == NULL) { - return -6900; + return -7110; } /* utilize memory */ for (i = 0; i < sz; i++) { @@ -10822,7 +10822,7 @@ static int simple_mem_test(int sz) /* read back and verify */ for (i = 0; i < sz; i++) { if (b[i] != (byte)i) { - ret = -6901; + ret = -7111; break; } } @@ -10852,84 +10852,84 @@ static int memory_test(void) #ifdef WOLFSSL_STATIC_MEMORY /* check macro settings */ if (sizeof(size)/sizeof(word32) != WOLFMEM_MAX_BUCKETS) { - return -7000; + return -7200; } if (sizeof(dist)/sizeof(word32) != WOLFMEM_MAX_BUCKETS) { - return -7001; + return -7201; } for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { if ((size[i] % WOLFSSL_STATIC_ALIGN) != 0) { /* each element in array should be divisible by alignment size */ - return -7002; + return -7202; } } for (i = 1; i < WOLFMEM_MAX_BUCKETS; i++) { if (size[i - 1] >= size[i]) { - return -7003; /* sizes should be in increasing order */ + return -7203; /* sizes should be in increasing order */ } } /* check that padding size returned is possible */ if (wolfSSL_MemoryPaddingSz() < WOLFSSL_STATIC_ALIGN) { - return -7004; /* no room for wc_Memory struct */ + return -7204; /* no room for wc_Memory struct */ } if (wolfSSL_MemoryPaddingSz() < 0) { - return -7005; + return -7205; } if (wolfSSL_MemoryPaddingSz() % WOLFSSL_STATIC_ALIGN != 0) { - return -7006; /* not aligned! */ + return -7206; /* not aligned! */ } /* check function to return optimum buffer size (rounded down) */ ret = wolfSSL_StaticBufferSz(buffer, sizeof(buffer), WOLFMEM_GENERAL); if ((ret - pad) % WOLFSSL_STATIC_ALIGN != 0) { - return -7007; /* not aligned! */ + return -7207; /* not aligned! */ } if (ret < 0) { - return -7008; + return -7208; } if ((unsigned int)ret > sizeof(buffer)) { - return -7009; /* did not round down as expected */ + return -7209; /* did not round down as expected */ } if (ret != wolfSSL_StaticBufferSz(buffer, ret, WOLFMEM_GENERAL)) { - return -7010; /* return value changed when using suggested value */ + return -7210; /* return value changed when using suggested value */ } ret = wolfSSL_MemoryPaddingSz(); ret += pad; /* add space that is going to be needed if buffer not aligned */ if (wolfSSL_StaticBufferSz(buffer, size[0] + ret + 1, WOLFMEM_GENERAL) != (ret + (int)size[0])) { - return -7011; /* did not round down to nearest bucket value */ + return -7211; /* did not round down to nearest bucket value */ } ret = wolfSSL_StaticBufferSz(buffer, sizeof(buffer), WOLFMEM_IO_POOL); if ((ret - pad) < 0) { - return -7012; + return -7212; } if (((ret - pad) % (WOLFMEM_IO_SZ + wolfSSL_MemoryPaddingSz())) != 0) { - return -7013; /* not even chunks of memory for IO size */ + return -7213; /* not even chunks of memory for IO size */ } if (((ret - pad) % WOLFSSL_STATIC_ALIGN) != 0) { - return -7014; /* memory not aligned */ + return -7214; /* memory not aligned */ } /* check for passing bad or unknown arguments to functions */ if (wolfSSL_StaticBufferSz(NULL, 1, WOLFMEM_GENERAL) > 0) { - return -7015; + return -7215; } if (wolfSSL_StaticBufferSz(buffer, 1, WOLFMEM_GENERAL) != 0) { - return -7016; /* should round to 0 since struct + bucket will not fit */ + return -7216; /* should round to 0 since struct + bucket will not fit */ } (void)dist; /* avoid static analysis warning of variable not used */ @@ -10959,7 +10959,7 @@ static int memory_test(void) DYNAMIC_TYPE_TMP_BUFFER); } if (b == NULL) { - return -7017; + return -7217; } XFREE(b, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -11318,7 +11318,7 @@ static int cert_asn1_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); FreeDecodedCert(&cert); if (ret != 0) { - ERROR_OUT(-7100, done); + ERROR_OUT(-7300, done); } /* Bad issuer name */ @@ -11334,7 +11334,7 @@ static int cert_asn1_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); FreeDecodedCert(&cert); if (ret != ASN_PARSE_E) { - ERROR_OUT(-7101, done); + ERROR_OUT(-7301, done); } XFREE(badCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); badCert = NULL; @@ -11357,7 +11357,7 @@ static int cert_test(void) tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) - return -7200; + return -7400; /* Certificate with Name Constraints extension. */ #ifdef FREESCALE_MQX @@ -11366,14 +11366,14 @@ static int cert_test(void) file = XFOPEN("./certs/test/cert-ext-nc.der", "rb"); #endif if (!file) { - ERROR_OUT(-7201, done); + ERROR_OUT(-7401, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); InitDecodedCert(&cert, tmp, (word32)bytes, 0); ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-7202, done); + ERROR_OUT(-7402, done); } FreeDecodedCert(&cert); @@ -11384,14 +11384,14 @@ static int cert_test(void) file = XFOPEN("./certs/test/cert-ext-ia.der", "rb"); #endif if (!file) { - ERROR_OUT(-7203, done); + ERROR_OUT(-7403, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); InitDecodedCert(&cert, tmp, (word32)bytes, 0); ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-7204, done); + ERROR_OUT(-7404, done); } FreeDecodedCert(&cert); @@ -11402,7 +11402,7 @@ static int cert_test(void) file = XFOPEN("./certs/test/cert-ext-nct.der", "rb"); #endif if (!file) { - ERROR_OUT(-7203, done); + ERROR_OUT(-7405, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); @@ -11410,11 +11410,11 @@ static int cert_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); #ifndef IGNORE_NETSCAPE_CERT_TYPE if (ret != 0) { - ERROR_OUT(-7204, done); + ERROR_OUT(-7406, done); } #else if (ret != ASN_CRIT_EXT_E) { - ERROR_OUT(-7205, done); + ERROR_OUT(-7407, done); } ret = 0; #endif @@ -11468,13 +11468,13 @@ static int certext_test(void) tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) - return -7300; + return -7500; /* load othercert.der (Cert signed by an authority) */ file = XFOPEN(otherCertDerFile, "rb"); if (!file) { XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - return -7301; + return -7501; } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -11484,34 +11484,34 @@ static int certext_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) - return -7302; + return -7502; /* check the SKID from a RSA certificate */ if (XMEMCMP(skid_rsa, cert.extSubjKeyId, sizeof(cert.extSubjKeyId))) - return -7303; + return -7503; /* check the AKID from an RSA certificate */ if (XMEMCMP(akid_rsa, cert.extAuthKeyId, sizeof(cert.extAuthKeyId))) - return -7304; + return -7504; /* check the Key Usage from an RSA certificate */ if (!cert.extKeyUsageSet) - return -7305; + return -7505; if (cert.extKeyUsage != (KEYUSE_KEY_ENCIPHER|KEYUSE_KEY_AGREE)) - return -7306; + return -7506; /* check the CA Basic Constraints from an RSA certificate */ if (cert.isCA) - return -7307; + return -7507; #ifndef WOLFSSL_SEP /* test only if not using SEP policies */ /* check the Certificate Policies Id */ if (cert.extCertPoliciesNb != 1) - return -7308; + return -7508; if (strncmp(cert.extCertPolicies[0], "2.16.840.1.101.3.4.1.42", 23)) - return -7309; + return -7509; #endif FreeDecodedCert(&cert); @@ -11521,7 +11521,7 @@ static int certext_test(void) file = XFOPEN(certEccDerFile, "rb"); if (!file) { XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - return -7310; + return -7510; } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -11531,35 +11531,35 @@ static int certext_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) - return -7311; + return -7511; /* check the SKID from a ECC certificate - generated dynamically */ /* check the AKID from an ECC certificate */ if (XMEMCMP(akid_ecc, cert.extAuthKeyId, sizeof(cert.extAuthKeyId))) - return -7312; + return -7512; /* check the Key Usage from an ECC certificate */ if (!cert.extKeyUsageSet) - return -7313; + return -7513; if (cert.extKeyUsage != (KEYUSE_DIGITAL_SIG|KEYUSE_CONTENT_COMMIT)) - return -7314; + return -7514; /* check the CA Basic Constraints from an ECC certificate */ if (cert.isCA) - return -7315; + return -7515; #ifndef WOLFSSL_SEP /* test only if not using SEP policies */ /* check the Certificate Policies Id */ if (cert.extCertPoliciesNb != 2) - return -7316; + return -7516; if (strncmp(cert.extCertPolicies[0], "2.4.589440.587.101.2.1.9632587.1", 32)) - return -7317; + return -7517; if (strncmp(cert.extCertPolicies[1], "1.2.13025.489.1.113549", 22)) - return -7318; + return -7518; #endif FreeDecodedCert(&cert); @@ -11569,7 +11569,7 @@ static int certext_test(void) file = XFOPEN(certDerFile, "rb"); if (!file) { XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - return -7319; + return -7519; } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -11579,37 +11579,37 @@ static int certext_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) - return -7320; + return -7520; /* check the SKID from a CA certificate */ if (XMEMCMP(kid_ca, cert.extSubjKeyId, sizeof(cert.extSubjKeyId))) - return -7321; + return -7521; /* check the AKID from an CA certificate */ if (XMEMCMP(kid_ca, cert.extAuthKeyId, sizeof(cert.extAuthKeyId))) - return -7322; + return -7522; /* check the Key Usage from CA certificate */ if (!cert.extKeyUsageSet) - return -7323; + return -7523; if (cert.extKeyUsage != (KEYUSE_KEY_CERT_SIGN|KEYUSE_CRL_SIGN)) - return -7324; + return -7524; /* check the CA Basic Constraints CA certificate */ if (!cert.isCA) - return -7325; + return -7525; #ifndef WOLFSSL_SEP /* test only if not using SEP policies */ /* check the Certificate Policies Id */ if (cert.extCertPoliciesNb != 2) - return -7326; + return -7526; if (strncmp(cert.extCertPolicies[0], "2.16.840.1.101.3.4.1.42", 23)) - return -7327; + return -7527; if (strncmp(cert.extCertPolicies[1], "1.2.840.113549.1.9.16.6.5", 25)) - return -7328; + return -7528; #endif FreeDecodedCert(&cert); @@ -11632,7 +11632,7 @@ static int decodedCertCache_test(void) derSz = FOURK_BUF; der = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) - ret = -7400; + ret = -7600; if (ret == 0) { /* load cert.der */ @@ -11642,12 +11642,12 @@ static int decodedCertCache_test(void) XFCLOSE(file); } else - ret = -7401; + ret = -7601; } if (ret == 0) { if (wc_InitCert(&cert)) { - ret = -7402; + ret = -7602; } } @@ -11657,75 +11657,75 @@ static int decodedCertCache_test(void) if (ret == 0) { if(wc_SetSubjectBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7403; + ret = -7603; } if (ret == 0) { if (wc_SetSubjectRaw(&cert, der, derSz) != 0) - ret = -7404; + ret = -7604; } if (ret == 0) { if(wc_SetSubjectRaw(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7405; + ret = -7605; } if (ret == 0) { if(wc_SetIssuerBuffer(&cert, der, derSz) != 0) - ret = -7406; + ret = -7606; } if (ret == 0) { if(wc_SetIssuerBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7407; + ret = -7607; } if (ret == 0) { if(wc_SetIssuerRaw(&cert, der, derSz) != 0) - ret = -7408; + ret = -7608; } if (ret == 0) { if(wc_SetIssuerRaw(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7409; + ret = -7609; } #ifdef WOLFSSL_ALT_NAMES if (ret == 0) { if(wc_SetAltNamesBuffer(&cert, der, derSz) != 0) - ret = -7410; + ret = -7610; } if (ret == 0) { if(wc_SetAltNamesBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7411; + ret = -7611; } if (ret == 0) { if(wc_SetDatesBuffer(&cert, der, derSz) != 0) - ret = -7412; + ret = -7612; } if (ret == 0) { if(wc_SetDatesBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7413; + ret = -7613; } #endif if (ret == 0) { if(wc_SetAuthKeyIdFromCert(&cert, der, derSz) != 0) - ret = -7414; + ret = -7614; } if (ret == 0) { if(wc_SetAuthKeyIdFromCert(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -7415; + ret = -7615; } wc_SetCert_Free(&cert); if (ret == 0) { if(cert.decodedCert != NULL) - ret = -7416; + ret = -7616; } XFREE(der, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); @@ -11756,7 +11756,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -7417; + return -7620; ret = wc_RsaFlattenPublicKey(key, NULL, &eSz, n, &nSz); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -11766,7 +11766,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -7418; + return -7621; ret = wc_RsaFlattenPublicKey(key, e, NULL, n, &nSz); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -11776,7 +11776,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -7419; + return -7622; ret = wc_RsaFlattenPublicKey(key, e, &eSz, NULL, &nSz); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -11786,7 +11786,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -7420; + return -7623; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, NULL); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -11796,10 +11796,10 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -7421; + return -7624; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, &nSz); if (ret != 0) - return -7422; + return -7625; eSz = 0; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, &nSz); #ifdef HAVE_USER_RSA @@ -11813,7 +11813,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != RSA_BUFFER_E) #endif - return -7423; + return -7626; eSz = sizeof(e); nSz = 0; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, &nSz); @@ -11825,7 +11825,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != RSA_BUFFER_E) #endif - return -7424; + return -7627; return 0; } @@ -11850,59 +11850,59 @@ static int rsa_export_key_test(RsaKey* key) ret = wc_RsaExportKey(NULL, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7425; + return -7630; ret = wc_RsaExportKey(key, NULL, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7426; + return -7631; ret = wc_RsaExportKey(key, e, NULL, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7427; + return -7632; ret = wc_RsaExportKey(key, e, &eSz, NULL, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7428; + return -7633; ret = wc_RsaExportKey(key, e, &eSz, n, NULL, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7429; + return -7634; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, NULL, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7430; + return -7635; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, NULL, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7431; + return -7636; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, NULL, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7432; + return -7637; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, NULL, q, &qSz); if (ret != BAD_FUNC_ARG) - return -7433; + return -7638; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, NULL, &qSz); if (ret != BAD_FUNC_ARG) - return -7434; + return -7639; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, NULL); if (ret != BAD_FUNC_ARG) - return -7435; + return -7640; ret = wc_RsaExportKey(key, e, &zero, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != RSA_BUFFER_E) - return -7436; + return -7641; ret = wc_RsaExportKey(key, e, &eSz, n, &zero, d, &dSz, p, &pSz, q, &qSz); if (ret != RSA_BUFFER_E) - return -7437; + return -7642; #ifndef WOLFSSL_RSA_PUBLIC_ONLY ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &zero, p, &pSz, q, &qSz); if (ret != RSA_BUFFER_E) - return -7438; + return -7643; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &zero, q, &qSz); if (ret != RSA_BUFFER_E) - return -7439; + return -7644; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &zero); if (ret != RSA_BUFFER_E) - return -7440; + return -7645; #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != 0) - return -7441; + return -7646; return 0; } @@ -11936,36 +11936,36 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) /* Parameter Validation testing. */ ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_NONE, key, keyLen); if (ret != BAD_FUNC_ARG) - return -7442; + return -7650; ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA, key, 0); if (ret != BAD_FUNC_ARG) - return -7443; + return -7651; sigSz = (word32)modLen; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, NULL, inLen, out, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -7444; + return -7652; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, 0, out, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -7445; + return -7653; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, NULL, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -7446; + return -7654; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, NULL, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -7447; + return -7655; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, NULL, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -7448; + return -7656; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, 0, rng); if (ret != BAD_FUNC_ARG) - return -7449; + return -7657; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, keyLen, NULL); #ifdef HAVE_USER_RSA @@ -11991,51 +11991,51 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) #else if (ret != MISSING_RNG_E) #endif - return -7450; + return -7658; sigSz = 0; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -7451; + return -7659; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, NULL, inLen, out, (word32)modLen, key, keyLen); if (ret != BAD_FUNC_ARG) - return -7452; + return -7660; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, 0, out, (word32)modLen, key, keyLen); if (ret != BAD_FUNC_ARG) - return -7453; + return -7661; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, NULL, (word32)modLen, key, keyLen); if (ret != BAD_FUNC_ARG) - return -7454; + return -7662; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, 0, key, keyLen); if (ret != BAD_FUNC_ARG) - return -7455; + return -7663; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, NULL, keyLen); if (ret != BAD_FUNC_ARG) - return -7456; + return -7664; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, key, 0); if (ret != BAD_FUNC_ARG) - return -7457; + return -7665; #ifndef HAVE_ECC ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_ECC, key, keyLen); if (ret != SIG_TYPE_E) - return -7458; + return -7666; #endif /* Use APIs. */ ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA, key, keyLen); if (ret != modLen) - return -7459; + return -7667; ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA_W_ENC, key, keyLen); if (ret != modLen) - return -7460; + return -7668; sigSz = (word32)ret; #ifndef WOLFSSL_RSA_PUBLIC_ONLY @@ -12043,52 +12043,52 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, keyLen, rng); if (ret != 0) - return -7461; + return -7669; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, key, keyLen); if (ret != 0) - return -7462; + return -7670; sigSz = (word32)sizeof(out); ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, in, inLen, out, &sigSz, key, keyLen, rng); if (ret != 0) - return -7463; + return -7671; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, in, inLen, out, (word32)modLen, key, keyLen); if (ret != 0) - return -7464; + return -7672; /* Wrong signature type. */ ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, key, keyLen); if (ret == 0) - return -7465; + return -7673; /* check hash functions */ sigSz = (word32)sizeof(out); ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, hash, (int)sizeof(hash), out, &sigSz, key, keyLen, rng); if (ret != 0) - return -7466; + return -7674; ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, hash, (int)sizeof(hash), out, (word32)modLen, key, keyLen); if (ret != 0) - return -7467; + return -7675; sigSz = (word32)sizeof(out); ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, hashEnc, (int)sizeof(hashEnc), out, &sigSz, key, keyLen, rng); if (ret != 0) - return -7468; + return -7676; ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, hashEnc, (int)sizeof(hashEnc), out, (word32)modLen, key, keyLen); if (ret != 0) - return -7469; + return -7677; #else (void)hash; (void)hashEnc; @@ -12223,77 +12223,77 @@ static int rsa_decode_test(RsaKey* keyPub) ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7470; + return -7690; /* Parameter Validation testing. */ ret = wc_RsaPublicKeyDecodeRaw(NULL, sizeof(n), e, sizeof(e), keyPub); if (ret != BAD_FUNC_ARG) { - ret = -7471; + ret = -7691; goto done; } ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), NULL, sizeof(e), keyPub); if (ret != BAD_FUNC_ARG) { - ret = -7472; + ret = -7692; goto done; } ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), e, sizeof(e), NULL); if (ret != BAD_FUNC_ARG) { - ret = -7473; + ret = -7693; goto done; } ret = wc_RsaPublicKeyDecodeRaw(n, (word32)-1, e, sizeof(e), keyPub); -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) & !defined(WOLFSSL_SP_MATH_ALL) if (ret != 0) { #else if (ret != ASN_GETINT_E) { #endif - ret = -7474; + ret = -7694; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7475; + return -7695; ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), e, (word32)-1, keyPub); -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) & !defined(WOLFSSL_SP_MATH_ALL) if (ret != 0) { #else if (ret != ASN_GETINT_E) { #endif - ret = -7476; + ret = -7696; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7477; + return -7697; /* Use API. */ ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), e, sizeof(e), keyPub); if (ret != 0) { - ret = -7478; + ret = -7698; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7479; + return -7699; /* Parameter Validation testing. */ inSz = sizeof(good); ret = wc_RsaPublicKeyDecode(NULL, &inOutIdx, keyPub, inSz); if (ret != BAD_FUNC_ARG) { - ret = -7480; + ret = -7700; goto done; } ret = wc_RsaPublicKeyDecode(good, NULL, keyPub, inSz); if (ret != BAD_FUNC_ARG) { - ret = -7481; + ret = -7701; goto done; } ret = wc_RsaPublicKeyDecode(good, &inOutIdx, NULL, inSz); if (ret != BAD_FUNC_ARG) { - ret = -7482; + ret = -7702; goto done; } @@ -12302,14 +12302,14 @@ static int rsa_decode_test(RsaKey* keyPub) inSz = sizeof(good) - inOutIdx; ret = wc_RsaPublicKeyDecode(good, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -7483; + ret = -7703; goto done; } inOutIdx = 2; inSz = sizeof(goodAlgId) - inOutIdx; ret = wc_RsaPublicKeyDecode(goodAlgId, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -7484; + ret = -7704; goto done; } inOutIdx = 2; @@ -12321,7 +12321,7 @@ static int rsa_decode_test(RsaKey* keyPub) if (ret != ASN_RSA_KEY_E) #endif { - ret = -7485; + ret = -7705; goto done; } /* Try different bad data. */ @@ -12329,49 +12329,49 @@ static int rsa_decode_test(RsaKey* keyPub) inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badAlgIdNull, &inOutIdx, keyPub, inSz); if (ret != ASN_EXPECT_0_E) { - ret = -7486; + ret = -7706; goto done; } inSz = sizeof(badNotBitString); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNotBitString, &inOutIdx, keyPub, inSz); if (ret != ASN_BITSTR_E) { - ret = -7487; + ret = -7707; goto done; } inSz = sizeof(badBitStringLen); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badBitStringLen, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -7488; + ret = -7708; goto done; } inSz = sizeof(badNoSeq); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNoSeq, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -7489; + ret = -7709; goto done; } inSz = sizeof(badNoObj); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNoObj, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -7490; + ret = -7710; goto done; } inSz = sizeof(badIntN); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badIntN, &inOutIdx, keyPub, inSz); if (ret != ASN_RSA_KEY_E) { - ret = -7491; + ret = -7711; goto done; } inSz = sizeof(badNotIntE); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNotIntE, &inOutIdx, keyPub, inSz); if (ret != ASN_RSA_KEY_E) { - ret = -7492; + ret = -7712; goto done; } /* TODO: Shouldn't pass as the sequence length is too small. */ @@ -12379,69 +12379,69 @@ static int rsa_decode_test(RsaKey* keyPub) inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badLength, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -7493; + ret = -7713; goto done; } /* TODO: Shouldn't ignore object id's data. */ wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7494; + return -7714; inSz = sizeof(badBitStrNoZero); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badBitStrNoZero, &inOutIdx, keyPub, inSz); if (ret != ASN_EXPECT_0_E) { - ret = -7495; + ret = -7715; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7496; + return -7716; /* Valid data cases. */ inSz = sizeof(good); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(good, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -7497; + ret = -7717; goto done; } if (inOutIdx != inSz) { - ret = -7498; + ret = -7718; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7499; + return -7719; inSz = sizeof(goodAlgId); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(goodAlgId, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -7500; + ret = -7720; goto done; } if (inOutIdx != inSz) { - ret = -7501; + ret = -7721; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -7502; + return -7722; inSz = sizeof(goodAlgIdNull); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(goodAlgIdNull, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -7503; + ret = -7723; goto done; } if (inOutIdx != inSz) { - ret = -7504; + ret = -7724; goto done; } @@ -12514,7 +12514,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) /* Calculate hash of message. */ ret = wc_Hash(hash[j], in, inLen, digest, sizeof(digest)); if (ret != 0) - ERROR_OUT(-7505, exit_rsa_pss); + ERROR_OUT(-7730, exit_rsa_pss); digestSz = wc_HashGetDigestSize(hash[j]); for (i = 0; i < (int)(sizeof(mgf)/sizeof(*mgf)); i++) { @@ -12530,7 +12530,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-7506, exit_rsa_pss); + ERROR_OUT(-7731, exit_rsa_pss); outSz = ret; XMEMCPY(sig, out, outSz); @@ -12548,7 +12548,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-7507, exit_rsa_pss); + ERROR_OUT(-7732, exit_rsa_pss); plainSz = ret; TEST_SLEEP(); @@ -12561,7 +12561,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) hash[j], -1, wc_RsaEncryptSize(key)*8); #endif if (ret != 0) - ERROR_OUT(-7508, exit_rsa_pss); + ERROR_OUT(-7733, exit_rsa_pss); #ifdef RSA_PSS_TEST_WRONG_PARAMS for (k = 0; k < (int)(sizeof(mgf)/sizeof(*mgf)); k++) { @@ -12582,7 +12582,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret >= 0) - ERROR_OUT(-7509, exit_rsa_pss); + ERROR_OUT(-7734, exit_rsa_pss); } } #endif @@ -12603,7 +12603,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-7510, exit_rsa_pss); + ERROR_OUT(-7735, exit_rsa_pss); outSz = ret; TEST_SLEEP(); @@ -12618,7 +12618,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-7511, exit_rsa_pss); + ERROR_OUT(-7736, exit_rsa_pss); plainSz = ret; TEST_SLEEP(); @@ -12639,7 +12639,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != 0) - ERROR_OUT(-7512, exit_rsa_pss); + ERROR_OUT(-7737, exit_rsa_pss); XMEMCPY(sig, out, outSz); plain = NULL; @@ -12654,7 +12654,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-7513, exit_rsa_pss); + ERROR_OUT(-7738, exit_rsa_pss); plainSz = ret; TEST_SLEEP(); @@ -12667,7 +12667,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) 0, 0); #endif if (ret != 0) - ERROR_OUT(-7514, exit_rsa_pss); + ERROR_OUT(-7739, exit_rsa_pss); /* Test bad salt lengths in various APIs. */ digestSz = wc_HashGetDigestSize(hash[0]); @@ -12688,7 +12688,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-7515, exit_rsa_pss); + ERROR_OUT(-7740, exit_rsa_pss); do { #if defined(WOLFSSL_ASYNC_CRYPT) @@ -12701,7 +12701,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-7516, exit_rsa_pss); + ERROR_OUT(-7741, exit_rsa_pss); TEST_SLEEP(); do { @@ -12715,7 +12715,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-7517, exit_rsa_pss); + ERROR_OUT(-7742, exit_rsa_pss); TEST_SLEEP(); do { @@ -12729,7 +12729,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-7518, exit_rsa_pss); + ERROR_OUT(-7743, exit_rsa_pss); TEST_SLEEP(); #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER @@ -12746,7 +12746,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) len, 0); #endif if (ret != PSS_SALTLEN_E) - ERROR_OUT(-7519, exit_rsa_pss); + ERROR_OUT(-7744, exit_rsa_pss); #ifndef WOLFSSL_PSS_LONG_SALT len = digestSz + 1; #else @@ -12761,7 +12761,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) len, 0); #endif if (ret != PSS_SALTLEN_E) - ERROR_OUT(-7520, exit_rsa_pss); + ERROR_OUT(-7745, exit_rsa_pss); ret = 0; exit_rsa_pss: @@ -12820,7 +12820,7 @@ static int rsa_no_pad_test(void) || out == NULL || plain == NULL #endif ) { - ERROR_OUT(-7600, exit_rsa_nopadding); + ERROR_OUT(-7800, exit_rsa_nopadding); } #ifdef USE_CERT_BUFFERS_1024 @@ -12836,23 +12836,23 @@ static int rsa_no_pad_test(void) if (!file) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -40); - ERROR_OUT(-7601, exit_rsa_nopadding); + ERROR_OUT(-7801, exit_rsa_nopadding); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No key to use. */ - ERROR_OUT(-7602, exit_rsa_nopadding); + ERROR_OUT(-7802, exit_rsa_nopadding); #endif /* USE_CERT_BUFFERS */ ret = wc_InitRsaKey_ex(&key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7603, exit_rsa_nopadding); + ERROR_OUT(-7803, exit_rsa_nopadding); } ret = wc_RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7604, exit_rsa_nopadding); + ERROR_OUT(-7804, exit_rsa_nopadding); } /* after loading in key use tmp as the test buffer */ @@ -12863,7 +12863,7 @@ static int rsa_no_pad_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-7605, exit_rsa_nopadding); + ERROR_OUT(-7805, exit_rsa_nopadding); } #ifndef WOLFSSL_RSA_VERIFY_ONLY @@ -12881,12 +12881,12 @@ static int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret <= 0) { - ERROR_OUT(-7606, exit_rsa_nopadding); + ERROR_OUT(-7806, exit_rsa_nopadding); } /* encrypted result should not be the same as input */ if (XMEMCMP(out, tmp, inLen) == 0) { - ERROR_OUT(-7607, exit_rsa_nopadding); + ERROR_OUT(-7807, exit_rsa_nopadding); } TEST_SLEEP(); @@ -12901,11 +12901,11 @@ static int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret <= 0) { - ERROR_OUT(-7608, exit_rsa_nopadding); + ERROR_OUT(-7808, exit_rsa_nopadding); } if (XMEMCMP(plain, tmp, inLen) != 0) { - ERROR_OUT(-7609, exit_rsa_nopadding); + ERROR_OUT(-7809, exit_rsa_nopadding); } TEST_SLEEP(); #endif @@ -12913,12 +12913,12 @@ static int rsa_no_pad_test(void) #ifdef WC_RSA_BLINDING ret = wc_RsaSetRNG(NULL, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7610, exit_rsa_nopadding); + ERROR_OUT(-7810, exit_rsa_nopadding); } ret = wc_RsaSetRNG(&key, &rng); if (ret < 0) { - ERROR_OUT(-7611, exit_rsa_nopadding); + ERROR_OUT(-7811, exit_rsa_nopadding); } #endif @@ -12934,7 +12934,7 @@ static int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7612, exit_rsa_nopadding); + ERROR_OUT(-7812, exit_rsa_nopadding); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -12950,11 +12950,11 @@ static int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7613, exit_rsa_nopadding); + ERROR_OUT(-7813, exit_rsa_nopadding); } if (XMEMCMP(plain, tmp, inLen) != 0) { - ERROR_OUT(-7614, exit_rsa_nopadding); + ERROR_OUT(-7814, exit_rsa_nopadding); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -12963,25 +12963,25 @@ static int rsa_no_pad_test(void) ret = wc_RsaDirect(out, outSz, plain, &plainSz, &key, -1, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7615, exit_rsa_nopadding); + ERROR_OUT(-7815, exit_rsa_nopadding); } ret = wc_RsaDirect(out, outSz, plain, &plainSz, NULL, RSA_PUBLIC_DECRYPT, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7616, exit_rsa_nopadding); + ERROR_OUT(-7816, exit_rsa_nopadding); } ret = wc_RsaDirect(out, outSz, NULL, &plainSz, &key, RSA_PUBLIC_DECRYPT, &rng); if (ret != LENGTH_ONLY_E || plainSz != inLen) { - ERROR_OUT(-7617, exit_rsa_nopadding); + ERROR_OUT(-7817, exit_rsa_nopadding); } ret = wc_RsaDirect(out, outSz - 10, plain, &plainSz, &key, RSA_PUBLIC_DECRYPT, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7618, exit_rsa_nopadding); + ERROR_OUT(-7818, exit_rsa_nopadding); } /* if making it to this point of code without hitting an ERROR_OUT then @@ -13044,16 +13044,16 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7619, exit_rsa); + ERROR_OUT(-7820, exit_rsa); } myCert = (Cert*)XMALLOC(sizeof(Cert), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (myCert == NULL) { - ERROR_OUT(-7621, exit_rsa); + ERROR_OUT(-7821, exit_rsa); } /* self signed */ if (wc_InitCert(myCert)) { - ERROR_OUT(-7622, exit_rsa); + ERROR_OUT(-7822, exit_rsa); } XMEMCPY(&myCert->subject, &certDefaultName, sizeof(CertName)); @@ -13077,24 +13077,24 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, keypub, NULL) != 0) { - ERROR_OUT(-7623, exit_rsa); + ERROR_OUT(-7823, exit_rsa); } /* add AKID from the Public Key */ if (wc_SetAuthKeyIdFromPublicKey(myCert, keypub, NULL) != 0) { - ERROR_OUT(-7624, exit_rsa); + ERROR_OUT(-7824, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(myCert,"cRLSign,keyCertSign") != 0) { - ERROR_OUT(-7625, exit_rsa); + ERROR_OUT(-7825, exit_rsa); } #ifdef WOLFSSL_EKU_OID { const char unique[] = "2.16.840.1.111111.100.1.10.1"; if (wc_SetExtKeyUsageOID(myCert, unique, sizeof(unique), 0, HEAP_HINT) != 0) { - ERROR_OUT(-7626, exit_rsa); + ERROR_OUT(-7826, exit_rsa); } } #endif /* WOLFSSL_EKU_OID */ @@ -13110,7 +13110,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7627, exit_rsa); + ERROR_OUT(-7827, exit_rsa); } certSz = ret; @@ -13119,7 +13119,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = ParseCert(decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(decode); - ERROR_OUT(-7628, exit_rsa); + ERROR_OUT(-7828, exit_rsa); } FreeDecodedCert(decode); #endif @@ -13132,7 +13132,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) /* Setup Certificate */ if (wc_InitCert(myCert)) { - ERROR_OUT(-7629, exit_rsa); + ERROR_OUT(-7829, exit_rsa); } #ifdef WOLFSSL_ALT_NAMES @@ -13146,7 +13146,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(rsaCaCertDerFile, "rb"); if (!file3) { - ERROR_OUT(-7630, exit_rsa); + ERROR_OUT(-7830, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); XFCLOSE(file3); @@ -13156,25 +13156,25 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) !defined(USE_CERT_BUFFERS_2048) && !defined(NO_ASN) ret = wc_SetAltNames(myCert, rsaCaCertFile); if (ret != 0) { - ERROR_OUT(-7631, exit_rsa); + ERROR_OUT(-7831, exit_rsa); } #endif /* get alt names from der */ ret = wc_SetAltNamesBuffer(myCert, tmp, (int)bytes3); if (ret != 0) { - ERROR_OUT(-7632, exit_rsa); + ERROR_OUT(-7832, exit_rsa); } /* get dates from der */ ret = wc_SetDatesBuffer(myCert, tmp, (int)bytes3); if (ret != 0) { - ERROR_OUT(-7633, exit_rsa); + ERROR_OUT(-7833, exit_rsa); } #ifndef NO_ASN_TIME ret = wc_GetCertDates(myCert, &beforeTime, &afterTime); if (ret < 0) { - ERROR_OUT(-7634, exit_rsa); + ERROR_OUT(-7834, exit_rsa); } #endif #endif /* WOLFSSL_ALT_NAMES */ @@ -13189,7 +13189,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(rsaCaKeyFile, "rb"); if (!file3) { - ERROR_OUT(-7635, exit_rsa); + ERROR_OUT(-7835, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); @@ -13198,11 +13198,11 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = wc_InitRsaKey(caKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7636, exit_rsa); + ERROR_OUT(-7836, exit_rsa); } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, caKey, (word32)bytes3); if (ret != 0) { - ERROR_OUT(-7637, exit_rsa); + ERROR_OUT(-7837, exit_rsa); } #ifndef NO_SHA256 @@ -13221,7 +13221,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, key, NULL) != 0) { - ERROR_OUT(-7638, exit_rsa); + ERROR_OUT(-7838, exit_rsa); } /* add AKID from the CA certificate */ @@ -13235,12 +13235,12 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = wc_SetAuthKeyId(myCert, rsaCaCertFile); #endif if (ret != 0) { - ERROR_OUT(-7639, exit_rsa); + ERROR_OUT(-7839, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(myCert,"keyEncipherment,keyAgreement") != 0) { - ERROR_OUT(-7640, exit_rsa); + ERROR_OUT(-7840, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -13254,12 +13254,12 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = wc_SetIssuer(myCert, rsaCaCertFile); #endif if (ret < 0) { - ERROR_OUT(-7641, exit_rsa); + ERROR_OUT(-7841, exit_rsa); } certSz = wc_MakeCert(myCert, der, FOURK_BUF, key, NULL, rng); if (certSz < 0) { - ERROR_OUT(-7642, exit_rsa); + ERROR_OUT(-7842, exit_rsa); } ret = 0; @@ -13273,7 +13273,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7643, exit_rsa); + ERROR_OUT(-7843, exit_rsa); } certSz = ret; @@ -13282,7 +13282,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = ParseCert(decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(decode); - ERROR_OUT(-7644, exit_rsa); + ERROR_OUT(-7844, exit_rsa); } FreeDecodedCert(decode); #endif @@ -13360,11 +13360,11 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7645, exit_rsa); + ERROR_OUT(-7850, exit_rsa); } myCert = (Cert*)XMALLOC(sizeof(Cert), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (myCert == NULL) { - ERROR_OUT(-7647, exit_rsa); + ERROR_OUT(-7851, exit_rsa); } /* Get CA Key */ @@ -13377,7 +13377,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(rsaCaKeyFile, "rb"); if (!file3) { - ERROR_OUT(-7648, exit_rsa); + ERROR_OUT(-7852, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); @@ -13386,11 +13386,11 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_InitRsaKey(caKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7649, exit_rsa); + ERROR_OUT(-7853, exit_rsa); } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, caKey, (word32)bytes3); if (ret != 0) { - ERROR_OUT(-7650, exit_rsa); + ERROR_OUT(-7854, exit_rsa); } /* Get Cert Key */ @@ -13400,7 +13400,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(eccKeyPubFile, "rb"); if (!file3) { - ERROR_OUT(-7651, exit_rsa); + ERROR_OUT(-7855, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); @@ -13409,18 +13409,18 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_ecc_init_ex(caEccKeyPub, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7652, exit_rsa); + ERROR_OUT(-7856, exit_rsa); } idx3 = 0; ret = wc_EccPublicKeyDecode(tmp, &idx3, caEccKeyPub, (word32)bytes3); if (ret != 0) { - ERROR_OUT(-7653, exit_rsa); + ERROR_OUT(-7857, exit_rsa); } /* Setup Certificate */ if (wc_InitCert(myCert)) { - ERROR_OUT(-7654, exit_rsa); + ERROR_OUT(-7858, exit_rsa); } #ifndef NO_SHA256 @@ -13441,7 +13441,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, NULL, caEccKeyPub) != 0) { - ERROR_OUT(-7655, exit_rsa); + ERROR_OUT(-7859, exit_rsa); } /* add AKID from the CA certificate */ @@ -13455,12 +13455,12 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_SetAuthKeyId(myCert, rsaCaCertFile); #endif if (ret != 0) { - ERROR_OUT(-7656, exit_rsa); + ERROR_OUT(-7860, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(myCert, certKeyUsage) != 0) { - ERROR_OUT(-7657, exit_rsa); + ERROR_OUT(-7861, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -13474,12 +13474,12 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_SetIssuer(myCert, rsaCaCertFile); #endif if (ret < 0) { - ERROR_OUT(-7658, exit_rsa); + ERROR_OUT(-7862, exit_rsa); } certSz = wc_MakeCert(myCert, der, FOURK_BUF, NULL, caEccKeyPub, rng); if (certSz < 0) { - ERROR_OUT(-7659, exit_rsa); + ERROR_OUT(-7863, exit_rsa); } ret = 0; @@ -13493,7 +13493,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7660, exit_rsa); + ERROR_OUT(-7864, exit_rsa); } certSz = ret; @@ -13502,7 +13502,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = ParseCert(decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(decode); - ERROR_OUT(-7661, exit_rsa); + ERROR_OUT(-7865, exit_rsa); } FreeDecodedCert(decode); @@ -13575,7 +13575,7 @@ static int rsa_keygen_test(WC_RNG* rng) ret = wc_InitRsaKey_ex(genKey, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7662, exit_rsa); + ERROR_OUT(-7870, exit_rsa); } ret = wc_MakeRsaKey(genKey, keySz, WC_RSA_EXPONENT, rng); @@ -13583,7 +13583,7 @@ static int rsa_keygen_test(WC_RNG* rng) ret = wc_AsyncWait(ret, &genKey->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7663, exit_rsa); + ERROR_OUT(-7871, exit_rsa); } TEST_SLEEP(); @@ -13594,17 +13594,17 @@ static int rsa_keygen_test(WC_RNG* rng) !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) ret = wc_CheckRsaKey(genKey); if (ret != 0) { - ERROR_OUT(-7664, exit_rsa); + ERROR_OUT(-7872, exit_rsa); } #endif der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7665, exit_rsa); + ERROR_OUT(-7873, exit_rsa); } derSz = wc_RsaKeyToDer(genKey, der, FOURK_BUF); if (derSz < 0) { - ERROR_OUT(-7667, exit_rsa); + ERROR_OUT(-7874, exit_rsa); } ret = SaveDerAndPem(der, derSz, keyDerFile, keyPemFile, @@ -13616,14 +13616,14 @@ static int rsa_keygen_test(WC_RNG* rng) wc_FreeRsaKey(genKey); ret = wc_InitRsaKey(genKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7668, exit_rsa); + ERROR_OUT(-7875, exit_rsa); } idx = 0; #if !defined(WOLFSSL_CRYPTOCELL) /* The private key part of the key gen pairs from cryptocell can't be exported */ ret = wc_RsaPrivateKeyDecode(der, &idx, genKey, derSz); if (ret != 0) { - ERROR_OUT(-7669, exit_rsa); + ERROR_OUT(-7876, exit_rsa); } #endif /* WOLFSSL_CRYPTOCELL */ @@ -13771,7 +13771,7 @@ static int rsa_test(void) tmp = (byte*)XMALLOC(bytes, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) - ERROR_OUT(-7700, exit_rsa); + ERROR_OUT(-7900, exit_rsa); #ifdef USE_CERT_BUFFERS_1024 XMEMCPY(tmp, client_key_der_1024, (size_t)sizeof_client_key_der_1024); @@ -13786,24 +13786,24 @@ static int rsa_test(void) if (!file) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -40); - ERROR_OUT(-7701, exit_rsa); + ERROR_OUT(-7901, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No key to use. */ - ERROR_OUT(-7702, exit_rsa); + ERROR_OUT(-7902, exit_rsa); #endif /* USE_CERT_BUFFERS */ ret = wc_InitRsaKey_ex(key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7703, exit_rsa); + ERROR_OUT(-7903, exit_rsa); } #ifndef NO_ASN ret = wc_RsaPrivateKeyDecode(tmp, &idx, key, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7704, exit_rsa); + ERROR_OUT(-7904, exit_rsa); } #ifndef NO_SIG_WRAPPER modLen = wc_RsaEncryptSize(key); @@ -13812,11 +13812,11 @@ static int rsa_test(void) #ifdef USE_CERT_BUFFERS_2048 ret = mp_read_unsigned_bin(&key->n, &tmp[12], 256); if (ret != 0) { - ERROR_OUT(-7705, exit_rsa); + ERROR_OUT(-7905, exit_rsa); } ret = mp_set_int(&key->e, WC_RSA_EXPONENT); if (ret != 0) { - ERROR_OUT(-7706, exit_rsa); + ERROR_OUT(-7906, exit_rsa); } #ifndef NO_SIG_WRAPPER modLen = 2048; @@ -13833,7 +13833,7 @@ static int rsa_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-7707, exit_rsa); + ERROR_OUT(-7907, exit_rsa); } #endif @@ -13859,7 +13859,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7708, exit_rsa); + ERROR_OUT(-7908, exit_rsa); } TEST_SLEEP(); @@ -13868,7 +13868,7 @@ static int rsa_test(void) int tmpret = ret; ret = wc_RsaSetRNG(key, &rng); if (ret < 0) { - ERROR_OUT(-7709, exit_rsa); + ERROR_OUT(-7909, exit_rsa); } ret = tmpret; } @@ -13884,11 +13884,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7710, exit_rsa); + ERROR_OUT(-7910, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7711, exit_rsa); + ERROR_OUT(-7911, exit_rsa); } TEST_SLEEP(); @@ -13901,13 +13901,13 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7712, exit_rsa); + ERROR_OUT(-7912, exit_rsa); } if (ret != (int)inLen) { - ERROR_OUT(-7713, exit_rsa); + ERROR_OUT(-7913, exit_rsa); } if (XMEMCMP(res, in, inLen)) { - ERROR_OUT(-7714, exit_rsa); + ERROR_OUT(-7914, exit_rsa); } TEST_SLEEP(); @@ -13920,7 +13920,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7715, exit_rsa); + ERROR_OUT(-7915, exit_rsa); } TEST_SLEEP(); @@ -14003,11 +14003,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7716, exit_rsa); + ERROR_OUT(-7916, exit_rsa); } if (XMEMCMP(plain, in, (size_t)ret)) { - ERROR_OUT(-7717, exit_rsa); + ERROR_OUT(-7917, exit_rsa); } TEST_SLEEP(); #endif @@ -14031,7 +14031,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7718, exit_rsa); + ERROR_OUT(-7918, exit_rsa); } TEST_SLEEP(); @@ -14047,11 +14047,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7719, exit_rsa); + ERROR_OUT(-7919, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7720, exit_rsa); + ERROR_OUT(-7920, exit_rsa); } TEST_SLEEP(); #endif /* NO_SHA */ @@ -14070,7 +14070,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7721, exit_rsa); + ERROR_OUT(-7921, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -14087,11 +14087,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7722, exit_rsa); + ERROR_OUT(-7922, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7723, exit_rsa); + ERROR_OUT(-7923, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -14107,13 +14107,13 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7724, exit_rsa); + ERROR_OUT(-7924, exit_rsa); } if (ret != (int)inLen) { - ERROR_OUT(-7725, exit_rsa); + ERROR_OUT(-7925, exit_rsa); } if (XMEMCMP(res, in, inLen)) { - ERROR_OUT(-7726, exit_rsa); + ERROR_OUT(-7926, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -14131,7 +14131,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7727, exit_rsa); + ERROR_OUT(-7927, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -14151,7 +14151,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret > 0) { /* in this case decrypt should fail */ - ERROR_OUT(-7728, exit_rsa); + ERROR_OUT(-7928, exit_rsa); } ret = 0; TEST_SLEEP(); @@ -14170,7 +14170,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7729, exit_rsa); + ERROR_OUT(-7929, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -14187,11 +14187,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7730, exit_rsa); + ERROR_OUT(-7930, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7731, exit_rsa); + ERROR_OUT(-7931, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -14210,7 +14210,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7732, exit_rsa); + ERROR_OUT(-7932, exit_rsa); } TEST_SLEEP(); @@ -14229,7 +14229,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret > 0) { /* should fail */ - ERROR_OUT(-7733, exit_rsa); + ERROR_OUT(-7933, exit_rsa); } ret = 0; TEST_SLEEP(); @@ -14255,7 +14255,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7734, exit_rsa); + ERROR_OUT(-7934, exit_rsa); } TEST_SLEEP(); @@ -14271,11 +14271,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7735, exit_rsa); + ERROR_OUT(-7935, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7736, exit_rsa); + ERROR_OUT(-7936, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -14294,7 +14294,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7737, exit_rsa); + ERROR_OUT(-7937, exit_rsa); } TEST_SLEEP(); @@ -14310,11 +14310,11 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7738, exit_rsa); + ERROR_OUT(-7938, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7739, exit_rsa); + ERROR_OUT(-7939, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -14354,14 +14354,14 @@ static int rsa_test(void) #elif !defined(NO_FILESYSTEM) file2 = XFOPEN(clientCert, "rb"); if (!file2) { - ERROR_OUT(-7740, exit_rsa); + ERROR_OUT(-7940, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, file2); XFCLOSE(file2); #else /* No certificate to use. */ - ERROR_OUT(-7741, exit_rsa); + ERROR_OUT(-7941, exit_rsa); #endif #ifdef sizeof @@ -14374,7 +14374,7 @@ static int rsa_test(void) ret = ParseCert(cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(cert); - ERROR_OUT(-7742, exit_rsa); + ERROR_OUT(-7942, exit_rsa); } FreeDecodedCert(cert); @@ -14401,7 +14401,7 @@ static int rsa_test(void) if (!file) { err_sys("can't open ./certs/client-keyPub.der, " "Please run from wolfSSL home dir", -40); - ERROR_OUT(-7743, exit_rsa); + ERROR_OUT(-7943, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -14410,13 +14410,13 @@ static int rsa_test(void) ret = wc_InitRsaKey(keypub, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7744, exit_rsa); + ERROR_OUT(-7944, exit_rsa); } idx = 0; ret = wc_RsaPublicKeyDecode(tmp, &idx, keypub, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7745, exit_rsa); + ERROR_OUT(-7945, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -14463,26 +14463,26 @@ static int rsa_test(void) word32 rc = ntru_crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), GetEntropy, &drbg); if (rc != DRBG_OK) { - ERROR_OUT(-7746, exit_rsa); + ERROR_OUT(-7946, exit_rsa); } rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, NULL, &private_key_len, NULL); if (rc != NTRU_OK) { - ERROR_OUT(-7747, exit_rsa); + ERROR_OUT(-7947, exit_rsa); } rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, public_key, &private_key_len, private_key); if (rc != NTRU_OK) { - ERROR_OUT(-7748, exit_rsa); + ERROR_OUT(-7948, exit_rsa); } rc = ntru_crypto_drbg_uninstantiate(drbg); if (rc != NTRU_OK) { - ERROR_OUT(-7749, exit_rsa); + ERROR_OUT(-7949, exit_rsa); } #ifdef USE_CERT_BUFFERS_1024 @@ -14494,7 +14494,7 @@ static int rsa_test(void) #else caFile = XFOPEN(rsaCaKeyFile, "rb"); if (!caFile) { - ERROR_OUT(-7750, exit_rsa); + ERROR_OUT(-7950, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, caFile); @@ -14503,15 +14503,15 @@ static int rsa_test(void) ret = wc_InitRsaKey(caKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7751, exit_rsa); + ERROR_OUT(-7951, exit_rsa); } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, caKey, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7752, exit_rsa); + ERROR_OUT(-7952, exit_rsa); } if (wc_InitCert(&myCert)) { - ERROR_OUT(-7753, exit_rsa); + ERROR_OUT(-7953, exit_rsa); } XMEMCPY(&myCert.subject, &certDefaultName, sizeof(CertName)); @@ -14521,7 +14521,7 @@ static int rsa_test(void) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromNtruPublicKey(&myCert, public_key, public_key_len) != 0) { - ERROR_OUT(-7754, exit_rsa); + ERROR_OUT(-7954, exit_rsa); } /* add AKID from the CA certificate */ @@ -14535,12 +14535,12 @@ static int rsa_test(void) ret = wc_SetAuthKeyId(&myCert, rsaCaCertFile); #endif if (ret != 0) { - ERROR_OUT(-7755, exit_rsa); + ERROR_OUT(-7955, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(&myCert, certKeyUsage2) != 0) { - ERROR_OUT(-7756, exit_rsa); + ERROR_OUT(-7956, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -14554,18 +14554,18 @@ static int rsa_test(void) ret = wc_SetIssuer(&myCert, rsaCaCertFile); #endif if (ret < 0) { - ERROR_OUT(-7757, exit_rsa); + ERROR_OUT(-7957, exit_rsa); } der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7758, exit_rsa); + ERROR_OUT(-7958, exit_rsa); } certSz = wc_MakeNtruCert(&myCert, der, FOURK_BUF, public_key, public_key_len, &rng); if (certSz < 0) { - ERROR_OUT(-7760, exit_rsa); + ERROR_OUT(-7959, exit_rsa); } ret = 0; @@ -14580,7 +14580,7 @@ static int rsa_test(void) } while (ret == WC_PENDING_E); wc_FreeRsaKey(caKey); if (ret < 0) { - ERROR_OUT(-7761, exit_rsa); + ERROR_OUT(-7960, exit_rsa); } certSz = ret; @@ -14589,7 +14589,7 @@ static int rsa_test(void) ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&decode); - ERROR_OUT(-7762, exit_rsa); + ERROR_OUT(-7961, exit_rsa); } FreeDecodedCert(&decode); #endif @@ -14603,12 +14603,12 @@ static int rsa_test(void) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) ntruPrivFile = XFOPEN("./ntru-key.raw", "wb"); if (!ntruPrivFile) { - ERROR_OUT(-7763, exit_rsa); + ERROR_OUT(-7962, exit_rsa); } ret = (int)XFWRITE(private_key, 1, private_key_len, ntruPrivFile); XFCLOSE(ntruPrivFile); if (ret != private_key_len) { - ERROR_OUT(-7764, exit_rsa); + ERROR_OUT(-7963, exit_rsa); } #endif @@ -14626,11 +14626,11 @@ static int rsa_test(void) ERROR_OUT(MEMORY_E, exit_rsa); der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7765, exit_rsa); + ERROR_OUT(-7964, exit_rsa); } if (wc_InitCert(req)) { - ERROR_OUT(-7767, exit_rsa); + ERROR_OUT(-7965, exit_rsa); } req->version = 0; @@ -14647,25 +14647,25 @@ static int rsa_test(void) #ifdef WOLFSSL_CERT_EXT /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(req, keypub, NULL) != 0) { - ERROR_OUT(-7768, exit_rsa); + ERROR_OUT(-7966, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(req, certKeyUsage2) != 0) { - ERROR_OUT(-7769, exit_rsa); + ERROR_OUT(-7967, exit_rsa); } /* add Extended Key Usage */ if (wc_SetExtKeyUsage(req, "serverAuth,clientAuth,codeSigning," "emailProtection,timeStamping,OCSPSigning") != 0) { - ERROR_OUT(-7770, exit_rsa); + ERROR_OUT(-7968, exit_rsa); } #ifdef WOLFSSL_EKU_OID { static const char unique[] = "2.16.840.1.111111.100.1.10.1"; if (wc_SetExtKeyUsageOID(req, unique, sizeof(unique), 0, HEAP_HINT) != 0) { - ERROR_OUT(-7771, exit_rsa); + ERROR_OUT(-7969, exit_rsa); } } #endif /* WOLFSSL_EKU_OID */ @@ -14673,17 +14673,17 @@ static int rsa_test(void) derSz = wc_MakeCertReq(req, der, FOURK_BUF, key, NULL); if (derSz < 0) { - ERROR_OUT(-7772, exit_rsa); + ERROR_OUT(-7970, exit_rsa); } #ifdef WOLFSSL_CERT_EXT /* Try again with "any" flag set, will override all others */ if (wc_SetExtKeyUsage(req, "any") != 0) { - ERROR_OUT(-7773, exit_rsa); + ERROR_OUT(-7971, exit_rsa); } derSz = wc_MakeCertReq(req, der, FOURK_BUF, key, NULL); if (derSz < 0) { - ERROR_OUT(-7774, exit_rsa); + ERROR_OUT(-7972, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -14698,7 +14698,7 @@ static int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7775, exit_rsa); + ERROR_OUT(-7973, exit_rsa); } derSz = ret; @@ -14710,7 +14710,7 @@ static int rsa_test(void) derSz = wc_MakeCertReq_ex(req, der, FOURK_BUF, RSA_TYPE, key); if (derSz < 0) { - ERROR_OUT(-7776, exit_rsa); + ERROR_OUT(-7974, exit_rsa); } XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -14889,41 +14889,41 @@ static int dh_fips_generate_test(WC_RNG *rng) /* Parameter Validation testing. */ ret = wc_DhGenerateKeyPair(NULL, rng, priv, &privSz, pub, &pubSz); if (ret != BAD_FUNC_ARG) - ERROR_OUT(-7777, exit_gen_test); + ERROR_OUT(-7980, exit_gen_test); ret = wc_DhGenerateKeyPair(key, NULL, priv, &privSz, pub, &pubSz); if (ret != BAD_FUNC_ARG) - ERROR_OUT(-7778, exit_gen_test); + ERROR_OUT(-7981, exit_gen_test); ret = wc_DhGenerateKeyPair(key, rng, NULL, &privSz, pub, &pubSz); if (ret != BAD_FUNC_ARG) - ERROR_OUT(-7779, exit_gen_test); + ERROR_OUT(-7982, exit_gen_test); ret = wc_DhGenerateKeyPair(key, rng, priv, NULL, pub, &pubSz); if (ret != BAD_FUNC_ARG) - ERROR_OUT(-7780, exit_gen_test); + ERROR_OUT(-7983, exit_gen_test); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, NULL, &pubSz); if (ret != BAD_FUNC_ARG) - ERROR_OUT(-7781, exit_gen_test); + ERROR_OUT(-7984, exit_gen_test); ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, NULL); if (ret != BAD_FUNC_ARG) - ERROR_OUT(-7782, exit_gen_test); + ERROR_OUT(-7985, exit_gen_test); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(-7783, exit_gen_test); + ERROR_OUT(-7986, exit_gen_test); ret = wc_DhSetKey_ex(key, p, sizeof(p), g, sizeof(g), q0, sizeof(q0)); if (ret != 0) { - ERROR_OUT(-7784, exit_gen_test); + ERROR_OUT(-7987, exit_gen_test); } wc_FreeDhKey(key); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(-7785, exit_gen_test); + ERROR_OUT(-7988, exit_gen_test); ret = wc_DhSetKey_ex(key, p, sizeof(p), g, sizeof(g), q, sizeof(q)); if (ret != 0) { - ERROR_OUT(-7786, exit_gen_test); + ERROR_OUT(-7989, exit_gen_test); } /* Use API. */ @@ -14932,51 +14932,51 @@ static int dh_fips_generate_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7787, exit_gen_test); + ERROR_OUT(-7990, exit_gen_test); } ret = wc_DhCheckPubKey_ex(key, pub, pubSz, q0, sizeof(q0)); if (ret != 0) { - ERROR_OUT(-7788, exit_gen_test); + ERROR_OUT(-7991, exit_gen_test); } wc_FreeDhKey(key); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(-7789, exit_gen_test); + ERROR_OUT(-7992, exit_gen_test); ret = wc_DhSetKey(key, p, sizeof(p), g, sizeof(g)); if (ret != 0) { - ERROR_OUT(-7790, exit_gen_test); + ERROR_OUT(-7993, exit_gen_test); } ret = wc_DhCheckPubKey_ex(key, pub, pubSz, q, sizeof(q)); if (ret != 0) { - ERROR_OUT(-7791, exit_gen_test); + ERROR_OUT(-7994, exit_gen_test); } #ifndef HAVE_SELFTEST ret = wc_DhCheckKeyPair(key, pub, pubSz, priv, privSz); if (ret != 0) { - ERROR_OUT(-7792, exit_gen_test); + ERROR_OUT(-7995, exit_gen_test); } /* Taint the public key so the check fails. */ pub[0]++; ret = wc_DhCheckKeyPair(key, pub, pubSz, priv, privSz); if (ret != MP_CMP_E) { - ERROR_OUT(-7793, exit_gen_test); + ERROR_OUT(-7996, exit_gen_test); } #ifdef WOLFSSL_KEY_GEN wc_FreeDhKey(key); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(-7794, exit_gen_test); + ERROR_OUT(-7997, exit_gen_test); ret = wc_DhGenerateParams(rng, 2048, key); if (ret != 0) { - ERROR_OUT(-7795, exit_gen_test); + ERROR_OUT(-7998, exit_gen_test); } privSz = sizeof(priv); @@ -14987,7 +14987,7 @@ static int dh_fips_generate_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7796, exit_gen_test); + ERROR_OUT(-7999, exit_gen_test); } #endif /* WOLFSSL_KEY_GEN */ #endif /* HAVE_SELFTEST */ @@ -15014,7 +15014,7 @@ static int dh_generate_test(WC_RNG *rng) DhKey smallKey; byte p[2] = { 0, 5 }; byte g[2] = { 0, 2 }; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_DH_CONST /* the table for constant DH lookup will round to the lowest byte size 21 */ byte priv[21]; @@ -15029,47 +15029,47 @@ static int dh_generate_test(WC_RNG *rng) ret = wc_InitDhKey_ex(&smallKey, HEAP_HINT, devId); if (ret != 0) - return -7797; + return -8010; /* Parameter Validation testing. */ ret = wc_InitDhKey_ex(NULL, HEAP_HINT, devId); if (ret != BAD_FUNC_ARG) - return -7798; + return -8011; wc_FreeDhKey(NULL); ret = wc_DhSetKey(NULL, p, sizeof(p), g, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7799, exit_gen_test); + ERROR_OUT(-8012, exit_gen_test); } ret = wc_DhSetKey(&smallKey, NULL, sizeof(p), g, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7800, exit_gen_test); + ERROR_OUT(-8013, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, 0, g, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7801, exit_gen_test); + ERROR_OUT(-8014, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, sizeof(p), NULL, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7802, exit_gen_test); + ERROR_OUT(-8015, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, sizeof(p), g, 0); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7803, exit_gen_test); + ERROR_OUT(-8016, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, sizeof(p), g, sizeof(g)); if (ret != 0) { - ERROR_OUT(-7804, exit_gen_test); + ERROR_OUT(-8017, exit_gen_test); } -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) /* Use API. */ ret = wc_DhGenerateKeyPair(&smallKey, rng, priv, &privSz, pub, &pubSz); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &smallKey.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ret = -7805; + ret = -8018; } #else (void)rng; @@ -15133,14 +15133,14 @@ static int dh_test_check_pubvalue(void) ret = wc_DhCheckPubValue(prime, sizeof(prime), dh_pubval_fail[i].data, dh_pubval_fail[i].len); if (ret != MP_VAL) - return -7806 - (int)i; + return -8020 - (int)i; } for (i = 0; i < sizeof(dh_pubval_pass) / sizeof(*dh_pubval_pass); i++) { ret = wc_DhCheckPubValue(prime, sizeof(prime), dh_pubval_pass[i].data, dh_pubval_pass[i].len); if (ret != 0) - return -7816 - (int)i; + return -8030 - (int)i; } return 0; @@ -15190,7 +15190,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) (agree2 == NULL) || (key == NULL) || (key2 == NULL)) - ERROR_OUT(-7835, done); + ERROR_OUT(-8050, done); #endif pubSz = FFDHE_KEY_SIZE; @@ -15203,22 +15203,22 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7826, done); + ERROR_OUT(-8051, done); } ret = wc_InitDhKey_ex(key2, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7827, done); + ERROR_OUT(-8052, done); } ret = wc_DhSetKey(key, params->p, params->p_len, params->g, params->g_len); if (ret != 0) { - ERROR_OUT(-7828, done); + ERROR_OUT(-8053, done); } ret = wc_DhSetKey(key2, params->p, params->p_len, params->g, params->g_len); if (ret != 0) { - ERROR_OUT(-7829, done); + ERROR_OUT(-8054, done); } ret = wc_DhGenerateKeyPair(key, rng, priv, &privSz, pub, &pubSz); @@ -15226,7 +15226,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7830, done); + ERROR_OUT(-8055, done); } ret = wc_DhGenerateKeyPair(key2, rng, priv2, &privSz2, pub2, &pubSz2); @@ -15234,7 +15234,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7831, done); + ERROR_OUT(-8056, done); } ret = wc_DhAgree(key, agree, &agreeSz, priv, privSz, pub2, pubSz2); @@ -15242,7 +15242,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7832, done); + ERROR_OUT(-8057, done); } ret = wc_DhAgree(key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); @@ -15250,11 +15250,11 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7833, done); + ERROR_OUT(-8058, done); } if (agreeSz != agreeSz2 || XMEMCMP(agree, agree2, agreeSz)) { - ERROR_OUT(-7834, done); + ERROR_OUT(-8059, done); } done: @@ -15319,9 +15319,9 @@ static int dh_test(void) byte *agree2 = (byte *)XMALLOC(DH_TEST_BUF_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if ((tmp == NULL) || (priv == NULL) || (pub == NULL) || - (priv2 == NULL) || (pub2 == NULL) || (agree == NULL) || - (agree2 == NULL)) - ERROR_OUT(-7960, done); + (priv2 == NULL) || (pub2 == NULL) || (agree == NULL) || + (agree2 == NULL)) + ERROR_OUT(-8100, done); #else DhKey key_buf, *key = &key_buf; DhKey key2_buf, *key2 = &key2_buf; @@ -15352,14 +15352,14 @@ static int dh_test(void) { XFILE file = XFOPEN(dhParamsFile, "rb"); if (! file) - ERROR_OUT(-7900, done); + ERROR_OUT(-8101, done); bytes = (word32) XFREAD(tmp, 1, DH_TEST_TMP_SIZE, file); XFCLOSE(file); } #else /* No DH key to use. */ - ERROR_OUT(-7901, done); + ERROR_OUT(-8102, done); #endif /* USE_CERT_BUFFERS */ (void)idx; @@ -15375,40 +15375,40 @@ static int dh_test(void) /* Use API for coverage. */ ret = wc_InitDhKey(key); if (ret != 0) { - ERROR_OUT(-7902, done); + ERROR_OUT(-8103, done); } wc_FreeDhKey(key); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7903, done); + ERROR_OUT(-8104, done); } keyInit = 1; ret = wc_InitDhKey_ex(key2, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7904, done); + ERROR_OUT(-8105, done); } #ifdef NO_ASN ret = wc_DhSetKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g)); if (ret != 0) { - ERROR_OUT(-7905, done); + ERROR_OUT(-8106, done); } ret = wc_DhSetKey(key2, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g)); if (ret != 0) { - ERROR_OUT(-7906, done); + ERROR_OUT(-8107, done); } #else ret = wc_DhKeyDecode(tmp, &idx, key, bytes); if (ret != 0) { - ERROR_OUT(-7907, done); + ERROR_OUT(-8108, done); } idx = 0; ret = wc_DhKeyDecode(tmp, &idx, key2, bytes); if (ret != 0) { - ERROR_OUT(-7908, done); + ERROR_OUT(-8109, done); } #endif @@ -15418,7 +15418,7 @@ static int dh_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-7909, done); + ERROR_OUT(-8110, done); } ret = wc_DhGenerateKeyPair(key, &rng, priv, &privSz, pub, &pubSz); @@ -15426,7 +15426,7 @@ static int dh_test(void) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7910, done); + ERROR_OUT(-8111, done); } ret = wc_DhGenerateKeyPair(key2, &rng, priv2, &privSz2, pub2, &pubSz2); @@ -15434,7 +15434,7 @@ static int dh_test(void) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7911, done); + ERROR_OUT(-8112, done); } ret = wc_DhAgree(key, agree, &agreeSz, priv, privSz, pub2, pubSz2); @@ -15442,7 +15442,7 @@ static int dh_test(void) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7912, done); + ERROR_OUT(-8113, done); } ret = wc_DhAgree(key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); @@ -15450,26 +15450,26 @@ static int dh_test(void) ret = wc_AsyncWait(ret, &key2->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7913, done); + ERROR_OUT(-8114, done); } if (agreeSz != agreeSz2 || XMEMCMP(agree, agree2, agreeSz)) { - ERROR_OUT(-7914, done); + ERROR_OUT(-8115, done); } #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) if (wc_DhCheckPrivKey(NULL, NULL, 0) != BAD_FUNC_ARG) - ERROR_OUT(-7915, done); + ERROR_OUT(-8116, done); if (wc_DhCheckPrivKey(key, priv, privSz) != 0) - ERROR_OUT(-7916, done); + ERROR_OUT(-8117, done); if (wc_DhExportParamsRaw(NULL, NULL, NULL, NULL, NULL, NULL, NULL) != BAD_FUNC_ARG) - ERROR_OUT(-7917, done); + ERROR_OUT(-8118, done); { word32 pSz, qSz, gSz; if (wc_DhExportParamsRaw(key, NULL, &pSz, NULL, &qSz, NULL, &gSz) != LENGTH_ONLY_E) - ERROR_OUT(-7918, done); + ERROR_OUT(-8119, done); } #endif @@ -15480,14 +15480,14 @@ static int dh_test(void) wc_FreeDhKey(key); ret = wc_InitDhKey_ex(key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7949, done); + ERROR_OUT(-8120, done); } #if !defined(NO_ASN) && !defined(NO_FILESYSTEM) { XFILE file = XFOPEN(dhKeyFile, "rb"); if (!file) - ERROR_OUT(-7950, done); + ERROR_OUT(-8121, done); bytes = (word32)XFREAD(tmp, 1, DH_TEST_TMP_SIZE, file); XFCLOSE(file); } @@ -15495,12 +15495,12 @@ static int dh_test(void) idx = 0; ret = wc_DhKeyDecode(tmp, &idx, key, bytes); if (ret != 0) { - ERROR_OUT(-7951, done); + ERROR_OUT(-8122, done); } #else ret = wc_DhSetKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g)); if (ret != 0) { - ERROR_OUT(-7951, done); + ERROR_OUT(-8123, done); } #endif @@ -15509,38 +15509,38 @@ static int dh_test(void) pubSz = DH_TEST_BUF_SIZE; ret = wc_DhExportKeyPair(key, priv, &privSz, pub, &pubSz); if (ret != 0) { - ERROR_OUT(-7952, done); + ERROR_OUT(-8124, done); } ret = wc_DhImportKeyPair(key2, priv, privSz, pub, pubSz); if (ret != 0) { - ERROR_OUT(-7953, done); + ERROR_OUT(-8125, done); } #endif /* WOLFSSL_DH_EXTRA */ ret = dh_generate_test(&rng); if (ret != 0) - ERROR_OUT(-7954, done); + ERROR_OUT(-8126, done); ret = dh_fips_generate_test(&rng); if (ret != 0) - ERROR_OUT(-7955, done); + ERROR_OUT(-8127, done); #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) ret = dh_test_check_pubvalue(); if (ret != 0) - ERROR_OUT(-7956, done); + ERROR_OUT(-8128, done); #endif /* Specialized code for key gen when using FFDHE-2048 and FFDHE-3072. */ #ifdef HAVE_FFDHE_2048 ret = dh_test_ffdhe(&rng, wc_Dh_ffdhe2048_Get()); if (ret != 0) - ERROR_OUT(-7957, done); + ERROR_OUT(-8129, done); #endif #ifdef HAVE_FFDHE_3072 ret = dh_test_ffdhe(&rng, wc_Dh_ffdhe3072_Get()); if (ret != 0) - ERROR_OUT(-7958, done); + ERROR_OUT(-8130, done); #endif wc_FreeDhKey(key); @@ -15552,7 +15552,7 @@ static int dh_test(void) ret = wc_DhSetCheckKey(key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g), NULL, 0, 0, &rng); if (ret != 0) - ERROR_OUT(-7959, done); + ERROR_OUT(-8131, done); keyInit = 1; /* DhSetCheckKey also initializes the key, free it */ #endif @@ -15621,7 +15621,7 @@ static int dsa_test(void) #else XFILE file = XFOPEN(dsaKey, "rb"); if (!file) - return -8000; + return -8200; bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), file); XFCLOSE(file); @@ -15629,30 +15629,30 @@ static int dsa_test(void) ret = wc_InitSha_ex(&sha, HEAP_HINT, devId); if (ret != 0) - return -8001; + return -8201; wc_ShaUpdate(&sha, tmp, bytes); wc_ShaFinal(&sha, hash); wc_ShaFree(&sha); ret = wc_InitDsaKey(&key); - if (ret != 0) return -8002; + if (ret != 0) return -8202; ret = wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes); - if (ret != 0) return -8003; + if (ret != 0) return -8203; #ifndef HAVE_FIPS ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); #else ret = wc_InitRng(&rng); #endif - if (ret != 0) return -8004; + if (ret != 0) return -8204; ret = wc_DsaSign(hash, signature, &key, &rng); - if (ret != 0) return -8005; + if (ret != 0) return -8205; ret = wc_DsaVerify(hash, signature, &key, &answer); - if (ret != 0) return -8006; - if (answer != 1) return -8007; + if (ret != 0) return -8206; + if (answer != 1) return -8207; wc_FreeDsaKey(&key); @@ -15664,30 +15664,30 @@ static int dsa_test(void) DsaKey genKey; ret = wc_InitDsaKey(&genKey); - if (ret != 0) return -8008; + if (ret != 0) return -8208; ret = wc_MakeDsaParameters(&rng, 1024, &genKey); if (ret != 0) { wc_FreeDsaKey(&genKey); - return -8009; + return -8209; } ret = wc_MakeDsaKey(&rng, &genKey); if (ret != 0) { wc_FreeDsaKey(&genKey); - return -8010; + return -8210; } der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { wc_FreeDsaKey(&genKey); - return -8011; + return -8211; } derSz = wc_DsaKeyToDer(&genKey, der, FOURK_BUF); if (derSz < 0) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -8013; + return -8212; } ret = SaveDerAndPem(der, derSz, keyDerFile, keyPemFile, @@ -15702,7 +15702,7 @@ static int dsa_test(void) if (ret != 0) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); - return -8014; + return -8213; } idx = 0; @@ -15711,7 +15711,7 @@ static int dsa_test(void) XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&derIn); wc_FreeDsaKey(&genKey); - return -8015; + return -8214; } wc_FreeDsaKey(&derIn); @@ -15721,7 +15721,7 @@ static int dsa_test(void) #endif /* WOLFSSL_KEY_GEN */ if (wc_InitDsaKey_h(&key, NULL) != 0) - return -8016; + return -8215; wc_FreeRng(&rng); return 0; @@ -15733,11 +15733,11 @@ static int dsa_test(void) static int generate_random_salt(byte *buf, word32 size) { - int ret = -8017; + int ret = -8220; WC_RNG rng; if(NULL == buf || !size) - return -8018; + return -8221; if (buf && size && wc_InitRng_ex(&rng, HEAP_HINT, devId) == 0) { ret = wc_RNG_GenerateBlock(&rng, (byte *)buf, size); @@ -15881,25 +15881,25 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8200; + return -8400; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) - return -8201; + return -8401; if (outlen != 0) - return -8202; + return -8402; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) - return -8203; + return -8403; if (outlen != 16) - return -8204; + return -8404; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -8205; + return -8405; if (outlen != 16) - return -8206; + return -8406; total += outlen; if (total != 32) return 3408; @@ -15908,107 +15908,107 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8207; + return -8407; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) - return -8208; + return -8408; if (outlen != 0) - return -8209; + return -8409; total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) - return -8210; + return -8410; if (outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) - return -8211; + return -8411; if (outlen != 16) - return -8212; + return -8412; total += outlen; if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -8213; + return -8413; if (outlen != 2) - return -8214; + return -8414; total += outlen; if (total != 18) return 3427; if (XMEMCMP(plain, cbcPlain, 18)) - return -8215; + return -8415; /* test with encrypting/decrypting more than 16 bytes at once */ total = 0; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8216; + return -8416; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 17) == 0) - return -8217; + return -8417; if (outlen != 16) - return -8218; + return -8418; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[17] , 1) == 0) - return -8219; + return -8419; if (outlen != 0) - return -8220; + return -8420; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -8221; + return -8421; if (outlen != 16) - return -8222; + return -8422; total += outlen; if (total != 32) - return -8223; + return -8423; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8224; + return -8424; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 17) == 0) - return -8225; + return -8425; if (outlen != 16) - return -8226; + return -8426; total += outlen; /* final call on non block size should fail */ if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) != 0) - return -8227; + return -8427; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[17], 1) == 0) - return -8228; + return -8428; if (outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[17+1], 14) == 0) - return -8229; + return -8429; if (outlen != 0) - return -8230; + return -8430; total += outlen; if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -8231; + return -8431; if (outlen != 2) - return -8232; + return -8432; total += outlen; if (total != 18) - return -8233; + return -8433; if (XMEMCMP(plain, cbcPlain, 18)) - return -8234; + return -8434; /* test byte by byte decrypt */ for (i = 0; i < AES_BLOCK_SIZE * 3; i++) { @@ -16019,32 +16019,32 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8235; + return -8435; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)plain, AES_BLOCK_SIZE * 3) == 0) - return -8236; + return -8436; if (outlen != AES_BLOCK_SIZE * 3) - return -8237; + return -8437; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -8238; + return -8438; if (outlen != AES_BLOCK_SIZE) - return -8239; + return -8439; total += outlen; if (total != sizeof(plain)) - return -8240; + return -8440; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8241; + return -8441; for (i = 0; i < AES_BLOCK_SIZE * 4; i++) { if (EVP_CipherUpdate(&de, (byte*)plain + total, &outlen, (byte*)cipher + i, 1) == 0) - return -8242; + return -8442; if (outlen > 0) { int j; @@ -16052,21 +16052,21 @@ static int openssl_aes_test(void) total += outlen; for (j = 0; j < total; j++) { if (plain[j] != j) { - return -8243; + return -8443; } } } } if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -8244; + return -8444; total += outlen; if (total != AES_BLOCK_SIZE * 3) { - return -8245; + return -8445; } for (i = 0; i < AES_BLOCK_SIZE * 3; i++) { if (plain[i] != i) { - return -8246; + return -8446; } } } @@ -16102,40 +16102,40 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8247; + return -8447; if (EVP_CIPHER_CTX_set_padding(&en, 0) != 1) - return -8248; + return -8448; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, EVP_TEST_BUF_SZ) == 0) - return -8249; + return -8449; if (outlen != 16) - return -8250; + return -8450; total += outlen; /* should fail here */ if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) != 0) - return -8251; + return -8451; /* turn padding back on and do successful encrypt */ total = 0; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8252; + return -8452; if (EVP_CIPHER_CTX_set_padding(&en, 1) != 1) - return -8253; + return -8453; if (EVP_CipherUpdate(&en, (byte*)padded, &outlen, (byte*)cbcPlain, EVP_TEST_BUF_SZ) == 0) - return -8254; + return -8454; if (outlen != 16) - return -8255; + return -8455; total += outlen; if (EVP_CipherFinal(&en, (byte*)&padded[total], &outlen) == 0) - return -8256; + return -8456; total += outlen; if (total != 32) - return -8257; + return -8457; XMEMCPY(cipher, padded, EVP_TEST_BUF_SZ); /* test out of bounds read on buffers w/o padding during decryption */ @@ -16143,39 +16143,39 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8258; + return -8458; if (EVP_CIPHER_CTX_set_padding(&de, 0) != 1) - return -8259; + return -8459; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, EVP_TEST_BUF_SZ) == 0) - return -8260; + return -8460; if (outlen != 16) - return -8261; + return -8461; total += outlen; /* should fail since not using padding */ if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) != 0) - return -8262; + return -8462; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8263; + return -8463; if (EVP_CIPHER_CTX_set_padding(&de, 1) != 1) - return -8264; + return -8464; if (EVP_CipherUpdate(&de, (byte*)padded, &outlen, (byte*)padded, EVP_TEST_BUF_PAD) == 0) - return -8265; + return -8465; if (outlen != 16) - return -8266; + return -8466; total += outlen; if (EVP_CipherFinal(&de, (byte*)&padded[total], &outlen) == 0) - return -8267; + return -8467; if (XMEMCMP(padded, cbcPlain, EVP_TEST_BUF_SZ)) - return -8268; + return -8468; } { /* evp_cipher test: EVP_aes_128_cbc */ @@ -16201,23 +16201,23 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1) == 0) - return -8269; + return -8469; if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) - return -8270; + return -8470; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -8271; + return -8471; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) - return -8272; + return -8472; if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) - return -8273; + return -8473; if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -8274; + return -8474; } /* end evp_cipher test: EVP_aes_128_cbc*/ @@ -16253,23 +16253,23 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 1) == 0) - return -8275; + return -8475; if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) - return -8276; + return -8476; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -8277; + return -8477; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 0) == 0) - return -8278; + return -8478; if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) - return -8279; + return -8479; if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -8280; + return -8480; } /* end evp_cipher test */ #endif /* HAVE_AES_ECB && WOLFSSL_AES_256 */ @@ -16314,11 +16314,11 @@ static int openssl_aes_test(void) #ifdef HAVE_AES_DECRYPT AES_decrypt(cipher, plain, &dec); if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -8281; + return -8481; #endif /* HAVE_AES_DECRYPT */ if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -8282; + return -8482; } #endif /* WOLFSSL_AES_DIRECT && WOLFSSL_AES_256 */ @@ -16443,130 +16443,130 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8283; + return -8483; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -8284; + return -8484; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8285; + return -8485; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -8286; + return -8486; if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -8287; + return -8487; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -8288; + return -8488; p_en = wolfSSL_EVP_CIPHER_CTX_new(); if (p_en == NULL) - return -8289; + return -8489; p_de = wolfSSL_EVP_CIPHER_CTX_new(); if (p_de == NULL) - return -8290; + return -8490; if (EVP_CipherInit(p_en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8291; + return -8491; if (EVP_Cipher(p_en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -8292; + return -8492; if (EVP_CipherInit(p_de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8293; + return -8493; if (EVP_Cipher(p_de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -8294; + return -8494; wolfSSL_EVP_CIPHER_CTX_free(p_en); wolfSSL_EVP_CIPHER_CTX_free(p_de); if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -8295; + return -8495; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -8296; + return -8496; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8297; + return -8497; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -8298; + return -8498; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8299; + return -8499; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -8300; + return -8500; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -8301; + return -8501; if (XMEMCMP(cipherBuff, ctrCipher, 9)) - return -8302; + return -8502; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -8303; + return -8503; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -8304; + return -8504; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -8305; + return -8505; if (XMEMCMP(cipherBuff, oddCipher, 9)) - return -8306; + return -8506; #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -8307; + return -8507; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr192Plain, AES_BLOCK_SIZE) == 0) - return -8308; + return -8508; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -8309; + return -8509; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -8310; + return -8510; if (XMEMCMP(plainBuff, ctr192Plain, sizeof(ctr192Plain))) - return -8311; + return -8511; if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) - return -8312; + return -8512; #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -8313; + return -8513; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr256Plain, AES_BLOCK_SIZE) == 0) - return -8314; + return -8514; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -8315; + return -8515; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -8316; + return -8516; if (XMEMCMP(plainBuff, ctr256Plain, sizeof(ctr256Plain))) - return -8317; + return -8517; if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) - return -8318; + return -8518; #endif /* WOLFSSL_AES_256 */ } #endif /* HAVE_AES_COUNTER */ @@ -16615,20 +16615,20 @@ static int openssl_aes_test(void) &num, AES_ENCRYPT); if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE - 1)) - return -8319; + return -8519; if (num != 15) /* should have used 15 of the 16 bytes */ - return -8320; + return -8520; wolfSSL_AES_cfb128_encrypt(msg + AES_BLOCK_SIZE - 1, cipher + AES_BLOCK_SIZE - 1, AES_BLOCK_SIZE + 1, &enc, iv, &num, AES_ENCRYPT); if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 2)) - return -8321; + return -8521; if (num != 0) - return -8322; + return -8522; } #endif /* WOLFSSL_AES_CFB && WOLFSSL_AES_128 */ return 0; @@ -16659,7 +16659,7 @@ static int openssl_test(void) byte* p; p = (byte*)CRYPTO_malloc(10); if (p == NULL) { - return -8400; + return -8600; } XMEMSET(p, 0, 10); CRYPTO_free(p); @@ -16681,9 +16681,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE) != 0) { - return -8402; + return -8601; } #endif /* NO_MD5 */ @@ -16704,9 +16704,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, b.output, WC_SHA_DIGEST_SIZE) != 0) { - return -8402; + return -8602; } #endif /* NO_SHA */ @@ -16726,9 +16726,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, e.output, WC_SHA224_DIGEST_SIZE) != 0) { - return -8403; + return -8603; } #endif /* WOLFSSL_SHA224 */ @@ -16748,9 +16748,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, d.output, WC_SHA256_DIGEST_SIZE) != 0) { - return -8404; + return -8604; } #endif /* !NO_SHA256 */ @@ -16772,9 +16772,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, e.output, WC_SHA384_DIGEST_SIZE) != 0) { - return -8405; + return -8605; } #endif /* WOLFSSL_SHA384 */ @@ -16797,9 +16797,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, f.output, WC_SHA512_DIGEST_SIZE) != 0) { - return -8406; + return -8606; } #endif /* WOLFSSL_SHA512 */ @@ -16820,9 +16820,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, e.output, WC_SHA3_224_DIGEST_SIZE) != 0) { - return -8407; + return -8607; } #endif /* WOLFSSL_NOSHA3_224 */ @@ -16843,9 +16843,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, d.output, WC_SHA3_256_DIGEST_SIZE) != 0) { - return -8408; + return -8608; } #endif /* WOLFSSL_NOSHA3_256 */ @@ -16866,9 +16866,9 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, e.output, WC_SHA3_384_DIGEST_SIZE) != 0) { - return -8409; + return -8609; } #ifndef WOLFSSL_NOSHA3_512 @@ -16890,16 +16890,16 @@ static int openssl_test(void) ret = EVP_DigestFinal(&md_ctx, hash, 0); } EVP_MD_CTX_cleanup(&md_ctx); - if (ret != WOLFSSL_SUCCESS || + if (ret != WOLFSSL_SUCCESS || XMEMCMP(hash, f.output, WC_SHA3_512_DIGEST_SIZE) != 0) { - return -8410; + return -8610; } #endif /* WOLFSSL_NOSHA3_512 */ #endif /* WOLFSSL_SHA3 */ #ifndef WC_NO_RNG if (RAND_bytes(hash, sizeof(hash)) != WOLFSSL_SUCCESS) - return -8411; + return -8611; #endif #ifndef NO_MD5 @@ -16909,11 +16909,11 @@ static int openssl_test(void) c.inLen = XSTRLEN(c.input); c.outLen = WC_MD5_DIGEST_SIZE; - if (HMAC(EVP_md5(), "JefeJefeJefeJefe", 16, (byte*)c.input, (int)c.inLen, + if (HMAC(EVP_md5(), "JefeJefeJefeJefe", 16, (byte*)c.input, (int)c.inLen, hash, 0) == NULL || XMEMCMP(hash, c.output, WC_MD5_DIGEST_SIZE) != 0) { - return -8412; + return -8612; } #endif /* NO_MD5 */ @@ -16945,24 +16945,24 @@ static int openssl_test(void) DES_cbc_encrypt(cipher, plain, sizeof(vector), &sched, &iv, DES_DECRYPT); if (XMEMCMP(plain, vector, sizeof(vector)) != 0) - return -8413; + return -8613; if (XMEMCMP(cipher, verify, sizeof(verify)) != 0) - return -8414; + return -8614; /* test changing iv */ DES_ncbc_encrypt(vector, cipher, 8, &sched, &iv, DES_ENCRYPT); DES_ncbc_encrypt(vector + 8, cipher + 8, 16, &sched, &iv, DES_ENCRYPT); if (XMEMCMP(cipher, verify, sizeof(verify)) != 0) - return -8415; + return -8615; } /* end des test */ #endif /* NO_DES3 */ #if !defined(NO_AES) && !defined(WOLFCRYPT_ONLY) if (openssl_aes_test() != 0) { - return -8416; + return -8616; } #if defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC) @@ -17006,9 +17006,9 @@ static int openssl_test(void) } EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WOLFSSL_SUCCESS) - return -8417; + return -8617; if (cipherSz != (int)sizeof(verify) || XMEMCMP(cipher, verify, cipherSz)) - return -8418; + return -8618; /* check partial decrypt (not enough padding for full block) */ plainSz = 0; @@ -17025,10 +17025,10 @@ static int openssl_test(void) if (plainSz == 0 && ret != WOLFSSL_SUCCESS) ret = WOLFSSL_SUCCESS; else - ret = -8419; + ret = -8619; } else - ret = -8420; + ret = -8620; EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WOLFSSL_SUCCESS) return ret; @@ -17048,9 +17048,9 @@ static int openssl_test(void) } EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WOLFSSL_SUCCESS) - return -8421; + return -8621; if (plainSz != (int)sizeof(msg) || XMEMCMP(plain, msg, sizeof(msg))) - return -8422; + return -8622; cipherSz = 0; EVP_CIPHER_CTX_init(&ctx); @@ -17067,9 +17067,9 @@ static int openssl_test(void) } EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WOLFSSL_SUCCESS) - return -8423; + return -8623; if (cipherSz != (int)sizeof(verify2) || XMEMCMP(cipher, verify2, cipherSz)) - return -8424; + return -8624; } /* end evp_cipher test: EVP_aes_128_cbc*/ #endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */ @@ -17099,9 +17099,9 @@ static int openssl_test(void) ret = EVP_Cipher(&ctx, cipher, (byte*)msg, 16); EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WOLFSSL_SUCCESS) - return -8430; + return -8625; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -8431; + return -8626; EVP_CIPHER_CTX_init(&ctx); ret = EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 0); @@ -17109,9 +17109,9 @@ static int openssl_test(void) ret = EVP_Cipher(&ctx, plain, cipher, 16); EVP_CIPHER_CTX_cleanup(&ctx); if (ret != WOLFSSL_SUCCESS) - return -8436; + return -8627; if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -8437; + return -8628; } /* end evp_cipher test */ #endif /* HAVE_AES_ECB && WOLFSSL_AES_128 */ @@ -17291,128 +17291,128 @@ static int openssl_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8438; + return -8629; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -8439; + return -8630; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8440; + return -8631; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -8441; + return -8632; if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -8442; + return -8633; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -8443; + return -8634; p_en = wolfSSL_EVP_CIPHER_CTX_new(); - if(p_en == NULL)return -8444; + if(p_en == NULL)return -8635; p_de = wolfSSL_EVP_CIPHER_CTX_new(); - if(p_de == NULL)return -8445; + if(p_de == NULL)return -8636; if (EVP_CipherInit(p_en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8446; + return -8637; if (EVP_Cipher(p_en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -8447; + return -8638; if (EVP_CipherInit(p_de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8448; + return -8639; if (EVP_Cipher(p_de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -8449; + return -8640; wolfSSL_EVP_CIPHER_CTX_free(p_en); wolfSSL_EVP_CIPHER_CTX_free(p_de); if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -8450; + return -8641; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -8451; + return -8642; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8452; + return -8643; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -8453; + return -8644; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -8454; + return -8645; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -8455; + return -8646; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -8456; + return -8647; if (XMEMCMP(cipherBuff, ctrCipher, 9)) - return -8457; + return -8648; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -8458; + return -8649; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -8459; + return -8650; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -8460; + return -8651; if (XMEMCMP(cipherBuff, oddCipher, 9)) - return -8461; + return -8652; #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -8462; + return -8653; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr192Plain, AES_BLOCK_SIZE) == 0) - return -8463; + return -8654; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -8464; + return -8655; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -8465; + return -8656; if (XMEMCMP(plainBuff, ctr192Plain, sizeof(ctr192Plain))) - return -8466; + return -8657; if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) - return -8467; + return -8658; #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -8468; + return -8659; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr256Plain, AES_BLOCK_SIZE) == 0) - return -8469; + return -8660; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -8470; + return -8661; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -8471; + return -8662; if (XMEMCMP(plainBuff, ctr256Plain, sizeof(ctr256Plain))) - return -8472; + return -8663; if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) - return -8473; + return -8664; #endif /* WOLFSSL_AES_256 */ } #endif /* HAVE_AES_COUNTER */ @@ -17447,96 +17447,96 @@ static int openssl_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8474; + return -8665; /* openSSL compatibility, if(inlen == 0)return 1; */ if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 0) != 1) - return -8475; + return -8666; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -8476; + return -8667; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) - return -8477; + return -8668; if(outlen != 0) - return -8478; + return -8669; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) - return -8479; + return -8670; if(outlen != 16) - return -8480; + return -8671; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -8481; + return -8672; if(outlen != 16) - return -8482; + return -8673; total += outlen; if(total != 32) - return -8483; + return -8674; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8484; + return -8675; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) - return -8485; + return -8676; if(outlen != 0) - return -8486; + return -8677; total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) - return -8487; + return -8678; if(outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) - return -8488; + return -8679; if(outlen != 16) - return -8489; + return -8680; total += outlen; if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -8490; + return -8681; if(outlen != 2) - return -8491; + return -8682; total += outlen; if(total != 18) - return -8492; + return -8683; if (XMEMCMP(plain, cbcPlain, 18)) - return -8493; + return -8684; total = 0; EVP_CIPHER_CTX_init(&en); if (EVP_EncryptInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv) == 0) - return -8494; + return -8685; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) - return -8495; + return -8686; if(outlen != 0) - return -8496; + return -8687; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) - return -8497; + return -8688; if(outlen != 16) - return -8498; + return -8689; total += outlen; if (EVP_EncryptFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -8499; + return -8690; if(outlen != 16) - return -8500; + return -8691; total += outlen; if(total != 32) return 3438; @@ -17545,108 +17545,108 @@ static int openssl_test(void) EVP_CIPHER_CTX_init(&de); if (EVP_DecryptInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv) == 0) - return -8501; + return -8692; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) - return -8502; + return -8693; if(outlen != 0) - return -8503; + return -8694; total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) - return -8504; + return -8695; if(outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) - return -8505; + return -8696; if(outlen != 16) - return -8506; + return -8697; total += outlen; if (EVP_DecryptFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -8507; + return -8698; if(outlen != 2) - return -8508; + return -8699; total += outlen; if(total != 18) return 3447; if (XMEMCMP(plain, cbcPlain, 18)) - return -8509; + return -8700; if (EVP_CIPHER_key_length(NULL) != 0) - return -8510; + return -8701; if (EVP_CIPHER_key_length(EVP_aes_128_cbc()) != 16) - return -8511; + return -8702; if (EVP_CIPHER_CTX_mode(NULL) != 0) - return -8512; + return -8703; if (EVP_CIPHER_CTX_mode(&en) != (en.flags & WOLFSSL_EVP_CIPH_MODE)) - return -8513; + return -8704; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit_ex(&en, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -8514; + return -8705; EVP_CIPHER_CTX_init(&en); if (EVP_EncryptInit_ex(&en, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv) == 0) - return -8515; + return -8706; if (wolfSSL_EVP_EncryptFinal_ex(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -8516; + return -8707; if (wolfSSL_EVP_EncryptFinal(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -8517; + return -8708; EVP_CIPHER_CTX_init(&de); if (EVP_DecryptInit_ex(&de, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv) == 0) - return -8518; + return -8709; if (wolfSSL_EVP_DecryptFinal(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -8519; + return -8710; if (wolfSSL_EVP_DecryptFinal_ex(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -8520; + return -8711; if (EVP_CIPHER_CTX_block_size(NULL) != BAD_FUNC_ARG) - return -8521; + return -8712; EVP_CIPHER_CTX_init(&en); EVP_EncryptInit_ex(&en, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv); if (EVP_CIPHER_CTX_block_size(&en) != en.block_size) - return -8522; + return -8713; if (EVP_CIPHER_block_size(NULL) != BAD_FUNC_ARG) - return -8523; + return -8714; if (EVP_CIPHER_block_size(EVP_aes_128_cbc()) != AES_BLOCK_SIZE) - return -8524; + return -8715; if (WOLFSSL_EVP_CIPHER_mode(NULL) != 0) - return -8525; + return -8716; if (EVP_CIPHER_flags(EVP_aes_128_cbc()) != WOLFSSL_EVP_CIPH_CBC_MODE) - return -8526; + return -8717; EVP_CIPHER_CTX_clear_flags(&en, 0xFFFFFFFF); EVP_CIPHER_CTX_set_flags(&en, 42); if (en.flags != 42) - return -8527; + return -8718; if (EVP_CIPHER_CTX_set_padding(NULL, 0) != BAD_FUNC_ARG) - return -8528; + return -8719; if (EVP_CIPHER_CTX_set_padding(&en, 0) != WOLFSSL_SUCCESS) - return -8529; + return -8720; if (EVP_CIPHER_CTX_set_padding(&en, 1) != WOLFSSL_SUCCESS) - return -8530; + return -8721; } #endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */ @@ -17666,60 +17666,60 @@ static int openSSL_evpMD_test(void) ret = EVP_DigestInit(ctx, EVP_sha256()); if (ret != SSL_SUCCESS) { - ret = -8600; + ret = -8800; goto openSSL_evpMD_test_done; } ret = EVP_MD_CTX_copy(ctx2, ctx); if (ret != SSL_SUCCESS) { - ret = -8601; + ret = -8801; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha256()) != EVP_MD_CTX_type(ctx2)) { - ret = -8602; + ret = -8802; goto openSSL_evpMD_test_done; } ret = EVP_DigestInit(ctx, EVP_sha1()); if (ret != SSL_SUCCESS) { - ret = -8603; + ret = -8803; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha256()) != EVP_MD_CTX_type(ctx2)) { - ret = -8604; + ret = -8804; goto openSSL_evpMD_test_done; } ret = EVP_MD_CTX_copy_ex(ctx2, ctx); if (ret != SSL_SUCCESS) { - ret = -8605; + ret = -8805; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha256()) == EVP_MD_CTX_type(ctx2)) { - ret = -8606; + ret = -8806; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha1()) != EVP_MD_CTX_type(ctx2)) { - ret = -8607; + ret = -8807; goto openSSL_evpMD_test_done; } if (EVP_DigestInit_ex(ctx, EVP_sha1(), NULL) != SSL_SUCCESS) { - ret = -8608; + ret = -8808; goto openSSL_evpMD_test_done; } if (EVP_add_digest(NULL) != 0) { - ret = -8609; + ret = -8809; goto openSSL_evpMD_test_done; } if (wolfSSL_EVP_add_cipher(NULL) != 0) { - ret = -8610; + ret = -8810; goto openSSL_evpMD_test_done; } @@ -18022,7 +18022,7 @@ static int openssl_pkey1_test(void) if (!f) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -41); - return -8800; + return -9000; } cliKeySz = (long)XFREAD(tmp, 1, FOURK_BUF, f); @@ -18034,69 +18034,69 @@ static int openssl_pkey1_test(void) clikey = tmp; if ((prvKey = EVP_PKEY_new()) == NULL) { - return -8801; + return -9001; } EVP_PKEY_free(prvKey); prvKey = NULL; if (x509 == NULL) { - ret = -8802; + ret = -9002; goto openssl_pkey1_test_done; } pubKey = X509_get_pubkey(x509); if (pubKey == NULL) { - ret = -8803; + ret = -9003; goto openssl_pkey1_test_done; } prvKey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &clikey, cliKeySz); if (prvKey == NULL) { - ret = -8804; + ret = -9004; goto openssl_pkey1_test_done; } /* phase 2 API to create EVP_PKEY_CTX and encrypt/decrypt */ if (EVP_PKEY_bits(prvKey) != keyLenBits) { - ret = -8805; + ret = -9005; goto openssl_pkey1_test_done; } if (EVP_PKEY_size(prvKey) != keyLenBits/8) { - ret = -8806; + ret = -9006; goto openssl_pkey1_test_done; } dec = EVP_PKEY_CTX_new(prvKey, NULL); enc = EVP_PKEY_CTX_new(pubKey, NULL); if (dec == NULL || enc == NULL) { - ret = -8807; + ret = -9007; goto openssl_pkey1_test_done; } if (EVP_PKEY_decrypt_init(dec) != 1) { - ret = -8808; + ret = -9008; goto openssl_pkey1_test_done; } if (EVP_PKEY_encrypt_init(enc) != 1) { - ret = -8809; + ret = -9009; goto openssl_pkey1_test_done; } if (EVP_PKEY_CTX_set_rsa_padding(dec, RSA_PKCS1_PADDING) <= 0) { - ret = -8810; + ret = -9010; goto openssl_pkey1_test_done; } #ifndef HAVE_FIPS if (EVP_PKEY_CTX_set_rsa_padding(dec, RSA_PKCS1_OAEP_PADDING) <= 0){ - ret = -8811; + ret = -9011; goto openssl_pkey1_test_done; } if (EVP_PKEY_CTX_set_rsa_padding(enc, RSA_PKCS1_OAEP_PADDING) <= 0) { - ret = -8812; + ret = -9012; goto openssl_pkey1_test_done; } #endif @@ -18104,13 +18104,13 @@ static int openssl_pkey1_test(void) XMEMSET(cipher, 0, sizeof(cipher)); outlen = keyLenBits/8; if (EVP_PKEY_encrypt(enc, cipher, &outlen, msg, sizeof(msg)) < 0) { - ret = -8813; + ret = -9013; goto openssl_pkey1_test_done; } XMEMSET(plain, 0, sizeof(plain)); if (EVP_PKEY_decrypt(dec, plain, &outlen, cipher, outlen) != 1) { - ret = -8814; + ret = -9014; goto openssl_pkey1_test_done; } @@ -18213,7 +18213,7 @@ static int openssl_evpSig_test(void) if((prvRsa == NULL) || (pubRsa == NULL)){ XFREE(pubTmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); XFREE(prvTmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - err_sys("ERROR with RSA_new", -8900); + err_sys("ERROR with RSA_new", -9100); return ERR_BASE_EVPSIG-5; } @@ -18383,42 +18383,42 @@ static int scrypt_test(void) ret = wc_scrypt(derived, NULL, 0, NULL, 0, 4, 1, 1, sizeof(verify1)); if (ret != 0) - return -9000; + return -9200; if (XMEMCMP(derived, verify1, sizeof(verify1)) != 0) - return -9001; + return -9201; ret = wc_scrypt(derived, (byte*)"password", 8, (byte*)"NaCl", 4, 10, 8, 16, sizeof(verify2)); if (ret != 0) - return -9002; + return -9202; if (XMEMCMP(derived, verify2, sizeof(verify2)) != 0) - return -9003; + return -9203; /* Don't run these test on embedded, since they use large mallocs */ #if !defined(BENCH_EMBEDDED) && !defined(WOLFSSL_LINUXKM) && !defined(HAVE_INTEL_QA) ret = wc_scrypt(derived, (byte*)"pleaseletmein", 13, (byte*)"SodiumChloride", 14, 14, 8, 1, sizeof(verify3)); if (ret != 0) - return -9004; + return -9204; if (XMEMCMP(derived, verify3, sizeof(verify3)) != 0) - return -9005; + return -9205; #ifdef SCRYPT_TEST_ALL ret = wc_scrypt(derived, (byte*)"pleaseletmein", 13, (byte*)"SodiumChloride", 14, 20, 8, 1, sizeof(verify4)); if (ret != 0) - return -9006; + return -9206; if (XMEMCMP(derived, verify4, sizeof(verify4)) != 0) - return -9007; + return -9207; #endif #endif /* !BENCH_EMBEDDED && !defined(WOLFSSL_LINUXKM) && !HAVE_INTEL_QA */ ret = wc_scrypt_ex(derived, (byte*)"password", 8, (byte*)"NaCl", 4, 1<<10, 8, 16, sizeof(verify2)); if (ret != 0) - return -9008; + return -9208; if (XMEMCMP(derived, verify2, sizeof(verify2)) != 0) - return -9009; + return -9209; return 0; } @@ -18455,24 +18455,24 @@ static int pkcs12_test(void) iterations, kLen, WC_SHA256, id); if (ret < 0) - return -9100; + return -9300; if (XMEMCMP(derived, verify, kLen) != 0) - return -9101; + return -9301; iterations = 1000; ret = wc_PKCS12_PBKDF(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, WC_SHA256, id); if (ret < 0) - return -9102; + return -9302; ret = wc_PKCS12_PBKDF_ex(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, WC_SHA256, id, HEAP_HINT); if (ret < 0) - return -9103; + return -9303; if (XMEMCMP(derived, verify2, 24) != 0) - return -9104; + return -9304; return 0; } @@ -18498,7 +18498,7 @@ static int pbkdf2_test(void) return ret; if (XMEMCMP(derived, verify, sizeof(verify)) != 0) - return -9200; + return -9400; return 0; @@ -18526,7 +18526,7 @@ static int pbkdf1_test(void) return ret; if (XMEMCMP(derived, verify, sizeof(verify)) != 0) - return -9300; + return -9500; return 0; } @@ -18610,38 +18610,38 @@ static int hkdf_test(void) #ifndef NO_SHA ret = wc_HKDF(WC_SHA, ikm1, 22, NULL, 0, NULL, 0, okm1, L); if (ret != 0) - return -9500; + return -9700; if (XMEMCMP(okm1, res1, L) != 0) - return -9501; + return -9701; #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ ret = wc_HKDF(WC_SHA, ikm1, 11, salt1, 13, info1, 10, okm1, L); if (ret != 0) - return -9502; + return -9702; if (XMEMCMP(okm1, res2, L) != 0) - return -9503; + return -9703; #endif /* HAVE_FIPS */ #endif /* NO_SHA */ #ifndef NO_SHA256 ret = wc_HKDF(WC_SHA256, ikm1, 22, NULL, 0, NULL, 0, okm1, L); if (ret != 0) - return -9504; + return -9704; if (XMEMCMP(okm1, res3, L) != 0) - return -9505; + return -9705; #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ ret = wc_HKDF(WC_SHA256, ikm1, 22, salt1, 13, info1, 10, okm1, L); if (ret != 0) - return -9506; + return -9706; if (XMEMCMP(okm1, res4, L) != 0) - return -9507; + return -9707; #endif /* HAVE_FIPS */ #endif /* NO_SHA256 */ @@ -18757,38 +18757,38 @@ static int x963kdf_test(void) ret = wc_X963_KDF(WC_HASH_TYPE_SHA, Z, sizeof(Z), NULL, 0, kek, sizeof(verify)); if (ret != 0) - return -9600; + return -9800; if (XMEMCMP(verify, kek, sizeof(verify)) != 0) - return -9601; + return -9801; #endif #ifndef NO_SHA256 ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, Z2, sizeof(Z2), NULL, 0, kek, sizeof(verify2)); if (ret != 0) - return -9602; + return -9802; if (XMEMCMP(verify2, kek, sizeof(verify2)) != 0) - return -9603; + return -9803; #endif #ifdef WOLFSSL_SHA512 ret = wc_X963_KDF(WC_HASH_TYPE_SHA512, Z3, sizeof(Z3), NULL, 0, kek, sizeof(verify3)); if (ret != 0) - return -9604; + return -9804; if (XMEMCMP(verify3, kek, sizeof(verify3)) != 0) - return -9605; + return -9805; ret = wc_X963_KDF(WC_HASH_TYPE_SHA512, Z4, sizeof(Z4), info4, sizeof(info4), kek, sizeof(verify4)); if (ret != 0) - return -9606; + return -9806; if (XMEMCMP(verify4, kek, sizeof(verify4)) != 0) - return -9607; + return -9807; #endif return 0; @@ -18902,7 +18902,7 @@ static int ecc_test_vector_item(const eccVector* vector) if (ret != 0) goto done; if (sigSz != sigRawSz || XMEMCMP(sig, sigRaw, sigSz) != 0) { - ret = -9608; + ret = -9810; goto done; } @@ -18911,7 +18911,7 @@ static int ecc_test_vector_item(const eccVector* vector) goto done; if (rSz != vector->rSz || XMEMCMP(r, vector->r, rSz) != 0 || sSz != vector->sSz || XMEMCMP(s, vector->s, sSz) != 0) { - ret = -9613; + ret = -9811; goto done; } #endif @@ -18929,7 +18929,7 @@ static int ecc_test_vector_item(const eccVector* vector) TEST_SLEEP(); if (verify != 1) - ret = -9609; + ret = -9812; done: @@ -19249,11 +19249,11 @@ static int ecc_test_sign_vectors(WC_RNG* rng) TEST_SLEEP(); if (sigSz != sizeof(expSig)) { - ret = -9610; + ret = -9830; goto done; } if (XMEMCMP(sig, expSig, sigSz) != 0) { - ret = -9611; + ret = -9831; goto done; } @@ -19341,7 +19341,7 @@ static int ecc_test_cdh_vectors(WC_RNG* rng) /* compare results */ if (x != z || XMEMCMP(sharedA, sharedB, x)) { - ERROR_OUT(-9612, done); + ERROR_OUT(-9840, done); } done: @@ -19404,7 +19404,7 @@ static int ecc_test_make_pub(WC_RNG* rng) { XFILE file = XFOPEN(eccKeyDerFile, "rb"); if (!file) { - ERROR_OUT(-9617, done); + ERROR_OUT(-9850, done); } tmpSz = (word32)XFREAD(tmp, 1, ECC_BUFSIZE, file); @@ -19415,25 +19415,25 @@ static int ecc_test_make_pub(WC_RNG* rng) /* import private only then test with */ ret = wc_ecc_import_private_key(tmp, tmpSz, NULL, 0, NULL); if (ret == 0) { - ERROR_OUT(-9618, done); + ERROR_OUT(-9851, done); } ret = wc_ecc_import_private_key(NULL, tmpSz, NULL, 0, key); if (ret == 0) { - ERROR_OUT(-9619, done); + ERROR_OUT(-9852, done); } x = 0; ret = wc_EccPrivateKeyDecode(tmp, &x, key, tmpSz); if (ret != 0) { - ERROR_OUT(-9620, done); + ERROR_OUT(-9853, done); } #ifdef HAVE_ECC_KEY_EXPORT x = ECC_BUFSIZE; ret = wc_ecc_export_private_only(key, exportBuf, &x); if (ret != 0) { - ERROR_OUT(-9621, done); + ERROR_OUT(-9854, done); } /* make private only key */ @@ -19441,32 +19441,32 @@ static int ecc_test_make_pub(WC_RNG* rng) wc_ecc_init_ex(key, HEAP_HINT, devId); ret = wc_ecc_import_private_key(exportBuf, x, NULL, 0, key); if (ret != 0) { - ERROR_OUT(-9622, done); + ERROR_OUT(-9855, done); } x = ECC_BUFSIZE; ret = wc_ecc_export_x963_ex(key, exportBuf, &x, 0); if (ret == 0) { - ERROR_OUT(-9623, done); + ERROR_OUT(-9856, done); } #endif /* HAVE_ECC_KEY_EXPORT */ ret = wc_ecc_make_pub(NULL, NULL); if (ret == 0) { - ERROR_OUT(-9624, done); + ERROR_OUT(-9857, done); } TEST_SLEEP(); #ifndef WOLFSSL_NO_MALLOC pubPoint = wc_ecc_new_point_h(HEAP_HINT); if (pubPoint == NULL) { - ERROR_OUT(-9625, done); + ERROR_OUT(-9858, done); } ret = wc_ecc_make_pub(key, pubPoint); if (ret != 0) { - ERROR_OUT(-9626, done); + ERROR_OUT(-9859, done); } TEST_SLEEP(); @@ -19476,7 +19476,7 @@ static int ecc_test_make_pub(WC_RNG* rng) x = ECC_BUFSIZE; ret = wc_ecc_export_x963_ex(key, exportBuf, &x, 0); if (ret == 0) { - ERROR_OUT(-9627, done); + ERROR_OUT(-9860, done); } #endif /* HAVE_ECC_KEY_EXPORT */ #endif /* !WOLFSSL_NO_MALLOC */ @@ -19486,7 +19486,7 @@ static int ecc_test_make_pub(WC_RNG* rng) #if defined(WOLFSSL_CRYPTOCELL) || defined(NO_ECC256) ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, key); if (ret != 0) { - ERROR_OUT(-9628, done); + ERROR_OUT(-9861, done); } #endif @@ -19501,7 +19501,7 @@ static int ecc_test_make_pub(WC_RNG* rng) ret = wc_ecc_sign_hash(msg, (word32)XSTRLEN((const char* )msg), tmp, &tmpSz, rng, key); } while (ret == WC_PENDING_E); if (ret != 0) { - ERROR_OUT(-9629, done); + ERROR_OUT(-9862, done); } TEST_SLEEP(); @@ -19516,11 +19516,11 @@ static int ecc_test_make_pub(WC_RNG* rng) ret = wc_ecc_verify_hash(tmp, tmpSz, msg, (word32)XSTRLEN((const char* )msg), &verify, key); } while (ret == WC_PENDING_E); if (ret != 0) { - ERROR_OUT(-9630, done); + ERROR_OUT(-9863, done); } if (verify != 1) { - ERROR_OUT(-9631, done); + ERROR_OUT(-9864, done); } TEST_SLEEP(); #ifdef HAVE_ECC_KEY_EXPORT @@ -19528,7 +19528,7 @@ static int ecc_test_make_pub(WC_RNG* rng) x = ECC_BUFSIZE; ret = wc_ecc_export_x963_ex(key, exportBuf, &x, 0); if (ret != 0) { - ERROR_OUT(-9632, done); + ERROR_OUT(-9865, done); } #endif /* HAVE_ECC_KEY_EXPORT */ #endif /* HAVE_ECC_VERIFY */ @@ -19540,7 +19540,7 @@ static int ecc_test_make_pub(WC_RNG* rng) x = ECC_BUFSIZE; ret = wc_ecc_export_private_only(key, exportBuf, &x); if (ret != 0) { - ERROR_OUT(-9633, done); + ERROR_OUT(-9866, done); } /* make private only key */ @@ -19548,14 +19548,14 @@ static int ecc_test_make_pub(WC_RNG* rng) wc_ecc_init_ex(key, HEAP_HINT, devId); ret = wc_ecc_import_private_key(exportBuf, x, NULL, 0, key); if (ret != 0) { - ERROR_OUT(-9634, done); + ERROR_OUT(-9867, done); } /* check that public export fails with private only key */ x = ECC_BUFSIZE; ret = wc_ecc_export_x963_ex(key, exportBuf, &x, 0); if (ret == 0) { - ERROR_OUT(-9635, done); + ERROR_OUT(-9868, done); } /* make public key for shared secret */ @@ -19565,7 +19565,7 @@ static int ecc_test_make_pub(WC_RNG* rng) ret = wc_AsyncWait(ret, &pub->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-9636, done); + ERROR_OUT(-9869, done); } TEST_SLEEP(); @@ -19588,7 +19588,7 @@ static int ecc_test_make_pub(WC_RNG* rng) } while (ret == WC_PENDING_E); wc_ecc_free(pub); if (ret != 0) { - ERROR_OUT(-9637, done); + ERROR_OUT(-9870, done); } TEST_SLEEP(); #endif /* HAVE_ECC_DHE && HAVE_ECC_KEY_EXPORT */ @@ -19755,7 +19755,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) ERROR_OUT(derSz, done); } if (derSz == 0) { - ERROR_OUT(-9640, done); + ERROR_OUT(-9890, done); } ret = SaveDerAndPem(der, derSz, eccPubKeyDerFile, NULL, 0, -8348); @@ -19772,7 +19772,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) } if (derSz == 0) { - ERROR_OUT(-9641, done); + ERROR_OUT(-9891, done); } ret = SaveDerAndPem(der, derSz, eccPkcs8KeyDerFile, NULL, 0, -8349); @@ -19838,12 +19838,12 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, #if (defined(HAVE_ECC_DHE) || defined(HAVE_ECC_CDH)) && \ !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) if ((sharedA == NULL) || (sharedB == NULL)) - ERROR_OUT(-9652, done); + ERROR_OUT(-9900, done); #endif #ifdef HAVE_ECC_SIGN if ((sig == NULL) || (digest == NULL)) - ERROR_OUT(-9653, done); + ERROR_OUT(-9901, done); #endif #endif /* WOLFSSL_SMALL_STACK */ @@ -19855,7 +19855,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if ((userA == NULL) || (userB == NULL) || (pubKey == NULL)) - ERROR_OUT(-9654, done); + ERROR_OUT(-9902, done); #endif XMEMSET(userA, 0, sizeof *userA); @@ -19894,7 +19894,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (wc_ecc_get_curve_idx(curve_id) != -1) { curveSize = wc_ecc_get_curve_size_from_id(userA->dp->id); if (curveSize != userA->dp->size) { - ret = -9642; + ret = -9903; goto done; } } @@ -19958,10 +19958,10 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (y != x) - ERROR_OUT(-9643, done); + ERROR_OUT(-9904, done); if (XMEMCMP(sharedA, sharedB, x)) - ERROR_OUT(-9644, done); + ERROR_OUT(-9905, done); TEST_SLEEP(); #endif /* HAVE_ECC_DHE */ @@ -19995,10 +19995,10 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (y != x) - ERROR_OUT(-9645, done); + ERROR_OUT(-9906, done); if (XMEMCMP(sharedA, sharedB, x)) - ERROR_OUT(-9646, done); + ERROR_OUT(-9907, done); TEST_SLEEP(); /* remove cofactor flag */ @@ -20038,7 +20038,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (XMEMCMP(sharedA, sharedB, y)) - ERROR_OUT(-9647, done); + ERROR_OUT(-9908, done); TEST_SLEEP(); #endif /* HAVE_ECC_DHE */ @@ -20076,7 +20076,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (XMEMCMP(sharedA, sharedB, y)) - ERROR_OUT(-9648, done); + ERROR_OUT(-9909, done); TEST_SLEEP(); #endif /* HAVE_ECC_DHE */ #endif /* HAVE_COMP_KEY */ @@ -20121,7 +20121,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) goto done; if (verify != 1) - ERROR_OUT(-9649, done); + ERROR_OUT(-9910, done); TEST_SLEEP(); } #endif /* HAVE_ECC_VERIFY */ @@ -20142,7 +20142,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, userA); } while (ret == WC_PENDING_E); if (ret != 0) - ERROR_OUT(-9650, done); + ERROR_OUT(-9911, done); TEST_SLEEP(); #ifdef HAVE_ECC_VERIFY @@ -20159,7 +20159,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) goto done; if (verify != 1) - ERROR_OUT(-9651, done); + ERROR_OUT(-9912, done); TEST_SLEEP(); } #endif /* HAVE_ECC_VERIFY */ @@ -20319,25 +20319,25 @@ static int ecc_point_test(void) outLen = sizeof(out); point = wc_ecc_new_point(); if (point == NULL) - return -9700; + return -10000; point2 = wc_ecc_new_point(); if (point2 == NULL) { wc_ecc_del_point(point); - return -9701; + return -10001; } #ifdef HAVE_COMP_KEY point3 = wc_ecc_new_point(); if (point3 == NULL) { wc_ecc_del_point(point2); wc_ecc_del_point(point); - return -9702; + return -10002; } point4 = wc_ecc_new_point(); if (point4 == NULL) { wc_ecc_del_point(point3); wc_ecc_del_point(point2); wc_ecc_del_point(point); - return -9703; + return -10003; } #endif @@ -20345,154 +20345,154 @@ static int ecc_point_test(void) wc_ecc_del_point(NULL); ret = wc_ecc_import_point_der(NULL, sizeof(der), curve_idx, point); if (ret != ECC_BAD_ARG_E) { - ret = -9704; + ret = -10004; goto done; } ret = wc_ecc_import_point_der(der, sizeof(der), ECC_CURVE_INVALID, point); if (ret != ECC_BAD_ARG_E) { - ret = -9705; + ret = -10005; goto done; } ret = wc_ecc_import_point_der(der, sizeof(der), curve_idx, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -9706; + ret = -10006; goto done; } ret = wc_ecc_export_point_der(-1, point, out, &outLen); if (ret != ECC_BAD_ARG_E) { - ret = -9707; + ret = -10007; goto done; } ret = wc_ecc_export_point_der(curve_idx, NULL, out, &outLen); if (ret != ECC_BAD_ARG_E) { - ret = -9708; + ret = -10008; goto done; } ret = wc_ecc_export_point_der(curve_idx, point, NULL, &outLen); if (ret != LENGTH_ONLY_E || outLen != sizeof(out)) { - ret = -9709; + ret = -10009; goto done; } ret = wc_ecc_export_point_der(curve_idx, point, out, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -9710; + ret = -10010; goto done; } outLen = 0; ret = wc_ecc_export_point_der(curve_idx, point, out, &outLen); if (ret != BUFFER_E) { - ret = -9711; + ret = -10011; goto done; } ret = wc_ecc_copy_point(NULL, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -9712; + ret = -10012; goto done; } ret = wc_ecc_copy_point(NULL, point2); if (ret != ECC_BAD_ARG_E) { - ret = -9713; + ret = -10013; goto done; } ret = wc_ecc_copy_point(point, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -9714; + ret = -10014; goto done; } ret = wc_ecc_cmp_point(NULL, NULL); if (ret != BAD_FUNC_ARG) { - ret = -9715; + ret = -10015; goto done; } ret = wc_ecc_cmp_point(NULL, point2); if (ret != BAD_FUNC_ARG) { - ret = -9716; + ret = -10016; goto done; } ret = wc_ecc_cmp_point(point, NULL); if (ret != BAD_FUNC_ARG) { - ret = -9717; + ret = -10017; goto done; } /* Use API. */ ret = wc_ecc_import_point_der(der, sizeof(der), curve_idx, point); if (ret != 0) { - ret = -9718; + ret = -10018; goto done; } outLen = sizeof(out); ret = wc_ecc_export_point_der(curve_idx, point, out, &outLen); if (ret != 0) { - ret = -9719; + ret = -10019; goto done; } if (outLen != sizeof(der)) { - ret = -9720; + ret = -10020; goto done; } if (XMEMCMP(out, der, outLen) != 0) { - ret = -9721; + ret = -10021; goto done; } ret = wc_ecc_copy_point(point2, point); if (ret != MP_OKAY) { - ret = -9722; + ret = -10022; goto done; } ret = wc_ecc_cmp_point(point2, point); if (ret != MP_EQ) { - ret = -9723; + ret = -10023; goto done; } ret = wc_ecc_import_point_der(altDer, sizeof(altDer), curve_idx, point2); if (ret != 0) { - ret = -9724; + ret = -10024; goto done; } ret = wc_ecc_cmp_point(point2, point); if (ret != MP_GT) { - ret = -9725; + ret = -10025; goto done; } #ifdef HAVE_COMP_KEY ret = wc_ecc_import_point_der(derComp0, sizeof(derComp0)*2-1, curve_idx, point3); if (ret != 0) { - ret = -9726; + ret = -10026; goto done; } ret = wc_ecc_import_point_der_ex(derComp0, sizeof(derComp0), curve_idx, point4, 0); if (ret != 0) { - ret = -9727; + ret = -10027; goto done; } ret = wc_ecc_cmp_point(point3, point4); if (ret != MP_EQ) { - ret = -9728; + ret = -10028; goto done; } ret = wc_ecc_import_point_der(derComp1, sizeof(derComp1)*2-1, curve_idx, point3); if (ret != 0) { - ret = -9729; + ret = -10029; goto done; } ret = wc_ecc_import_point_der_ex(derComp1, sizeof(derComp1), curve_idx, point4, 0); if (ret != 0) { - ret = -9730; + ret = -10030; goto done; } ret = wc_ecc_cmp_point(point3, point4); if (ret != MP_EQ) { - ret = -9731; + ret = -10031; goto done; } #endif @@ -20529,32 +20529,32 @@ static int ecc_sig_test(WC_RNG* rng, ecc_key* key) ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_ECC, key, sizeof(*key)); if (ret != size) - return -9728; + return -10040; sigSz = (word32)ret; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, in, inLen, out, &sigSz, key, sizeof(*key), rng); if (ret != 0) - return -9729; + return -10041; TEST_SLEEP(); ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, in, inLen, out, sigSz, key, sizeof(*key)); if (ret != 0) - return -9730; + return -10042; TEST_SLEEP(); sigSz = (word32)sizeof(out); ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, hash, (int)sizeof(hash), out, &sigSz, key, sizeof(*key), rng); if (ret != 0) - return -9731; + return -10043; TEST_SLEEP(); ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, hash, (int)sizeof(hash), out, sigSz, key, sizeof(*key)); if (ret != 0) - return -9732; + return -10044; TEST_SLEEP(); return 0; @@ -20585,7 +20585,7 @@ static int ecc_exp_imp_test(ecc_key* key) #ifdef WOLFSSL_SMALL_STACK if (keyImp == NULL) - ERROR_OUT(-9743, done); + ERROR_OUT(-10050, done); #endif wc_ecc_init_ex(keyImp, HEAP_HINT, devId); @@ -20593,19 +20593,19 @@ static int ecc_exp_imp_test(ecc_key* key) privLen = sizeof(priv); ret = wc_ecc_export_private_only(key, priv, &privLen); if (ret != 0) { - ret = -9733; + ret = -10051; goto done; } pubLen = sizeof(pub); ret = wc_ecc_export_point_der(key->idx, &key->pubkey, pub, &pubLen); if (ret != 0) { - ret = -9734; + ret = -10052; goto done; } ret = wc_ecc_import_private_key(priv, privLen, pub, pubLen, keyImp); if (ret != 0) { - ret = -9735; + ret = -10053; goto done; } @@ -20614,7 +20614,7 @@ static int ecc_exp_imp_test(ecc_key* key) ret = wc_ecc_import_raw_ex(keyImp, qx, qy, d, ECC_SECP256R1); if (ret != 0) { - ret = -9736; + ret = -10054; goto done; } @@ -20623,7 +20623,7 @@ static int ecc_exp_imp_test(ecc_key* key) curve_id = wc_ecc_get_curve_id(key->idx); if (curve_id < 0) { - ret = -9737; + ret = -10055; goto done; } @@ -20631,7 +20631,7 @@ static int ecc_exp_imp_test(ecc_key* key) ret = wc_ecc_import_private_key_ex(priv, privLen, NULL, 0, keyImp, curve_id); if (ret != 0) { - ret = -9738; + ret = -10056; goto done; } @@ -20642,7 +20642,7 @@ static int ecc_exp_imp_test(ecc_key* key) pubLenX = pubLenY = 32; ret = wc_ecc_export_public_raw(key, pub, &pubLenX, &pub[32], &pubLenY); if (ret != 0) { - ret = -9739; + ret = -10057; goto done; } @@ -20650,7 +20650,7 @@ static int ecc_exp_imp_test(ecc_key* key) /* test import of public */ ret = wc_ecc_import_unsigned(keyImp, pub, &pub[32], NULL, ECC_SECP256R1); if (ret != 0) { - ret = -9740; + ret = -10058; goto done; } #endif @@ -20663,7 +20663,7 @@ static int ecc_exp_imp_test(ecc_key* key) ret = wc_ecc_export_private_raw(key, pub, &pubLenX, &pub[32], &pubLenY, priv, &privLen); if (ret != 0) { - ret = -9741; + ret = -10059; goto done; } @@ -20671,7 +20671,7 @@ static int ecc_exp_imp_test(ecc_key* key) /* test import of private and public */ ret = wc_ecc_import_unsigned(keyImp, pub, &pub[32], priv, ECC_SECP256R1); if (ret != 0) { - ret = -9742; + ret = -10060; goto done; } #endif @@ -20733,7 +20733,7 @@ static int ecc_mulmod_test(ecc_key* key1) ret = wc_ecc_mulmod(&key1->k, &key2->pubkey, &key3->pubkey, &key2->k, &key3->k, 1); if (ret != 0) { - ret = -9743; + ret = -10070; goto done; } @@ -20767,23 +20767,23 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) /* Parameter Validation testing. */ ret = wc_ecc_shared_secret_ssh(NULL, &key->pubkey, out, &outLen); if (ret != BAD_FUNC_ARG) - return -9744; + return -10080; ret = wc_ecc_shared_secret_ssh(key, NULL, out, &outLen); if (ret != BAD_FUNC_ARG) - return -9745; + return -10081; ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, NULL, &outLen); if (ret != BAD_FUNC_ARG) - return -9746; + return -10082; ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, out, NULL); if (ret != BAD_FUNC_ARG) - return -9747; + return -10083; #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ !defined(HAVE_SELFTEST) ret = wc_ecc_set_rng(key, rng); if (ret != 0) - return -9748; + return -10084; #else (void)rng; #endif @@ -20798,7 +20798,7 @@ static int ecc_ssh_test(ecc_key* key, WC_RNG* rng) ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, out, &outLen); } while (ret == WC_PENDING_E); if (ret != 0) - return -9749; + return -10085; TEST_SLEEP(); return 0; } @@ -20824,12 +20824,12 @@ static int ecc_def_curve_test(WC_RNG *rng) /* Use API */ ret = wc_ecc_set_flags(NULL, 0); if (ret != BAD_FUNC_ARG) { - ret = -9749; + ret = -10090; goto done; } ret = wc_ecc_set_flags(key, 0); if (ret != 0) { - ret = -9750; + ret = -10091; goto done; } @@ -20838,7 +20838,7 @@ static int ecc_def_curve_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ret = -9751; + ret = -10092; goto done; } TEST_SLEEP(); @@ -20939,22 +20939,22 @@ static int ecc_decode_test(void) inSz = sizeof(good); ret = wc_EccPublicKeyDecode(NULL, &inOutIdx, key, inSz); if (ret != BAD_FUNC_ARG) { - ret = -9800; + ret = -10100; goto done; } ret = wc_EccPublicKeyDecode(good, NULL, key, inSz); if (ret != BAD_FUNC_ARG) { - ret = -9801; + ret = -10101; goto done; } ret = wc_EccPublicKeyDecode(good, &inOutIdx, NULL, inSz); if (ret != BAD_FUNC_ARG) { - ret = -9802; + ret = -10102; goto done; } ret = wc_EccPublicKeyDecode(good, &inOutIdx, key, 0); if (ret != BAD_FUNC_ARG) { - ret = -9803; + ret = -10103; goto done; } @@ -20963,14 +20963,14 @@ static int ecc_decode_test(void) inSz = sizeof(good) - inOutIdx; ret = wc_EccPublicKeyDecode(good, &inOutIdx, key, inSz); if (ret != ASN_PARSE_E) { - ret = -9804; + ret = -10104; goto done; } inOutIdx = 4; inSz = sizeof(good) - inOutIdx; ret = wc_EccPublicKeyDecode(good, &inOutIdx, key, inSz); if (ret != ASN_PARSE_E) { - ret = -9805; + ret = -10105; goto done; } /* Bad data. */ @@ -20978,56 +20978,56 @@ static int ecc_decode_test(void) inOutIdx = 0; ret = wc_EccPublicKeyDecode(badNoObjId, &inOutIdx, key, inSz); if (ret != ASN_OBJECT_ID_E) { - ret = -9806; + ret = -10106; goto done; } inSz = sizeof(badOneObjId); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badOneObjId, &inOutIdx, key, inSz); if (ret != ASN_OBJECT_ID_E) { - ret = -9807; + ret = -10107; goto done; } inSz = sizeof(badObjId1Len); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badObjId1Len, &inOutIdx, key, inSz); if (ret != ASN_PARSE_E) { - ret = -9808; + ret = -10108; goto done; } inSz = sizeof(badObj2d1Len); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badObj2d1Len, &inOutIdx, key, inSz); if (ret != ASN_PARSE_E) { - ret = -9809; + ret = -10109; goto done; } inSz = sizeof(badNotBitStr); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badNotBitStr, &inOutIdx, key, inSz); if (ret != ASN_BITSTR_E) { - ret = -9810; + ret = -10110; goto done; } inSz = sizeof(badBitStrLen); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badBitStrLen, &inOutIdx, key, inSz); if (ret != ASN_PARSE_E) { - ret = -9811; + ret = -10111; goto done; } inSz = sizeof(badNoBitStrZero); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badNoBitStrZero, &inOutIdx, key, inSz); if (ret != ASN_EXPECT_0_E) { - ret = -9812; + ret = -10112; goto done; } inSz = sizeof(badPoint); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badPoint, &inOutIdx, key, inSz); if (ret != ASN_ECC_KEY_E) { - ret = -9813; + ret = -10113; goto done; } @@ -21035,7 +21035,7 @@ static int ecc_decode_test(void) inOutIdx = 0; ret = wc_EccPublicKeyDecode(good, &inOutIdx, key, inSz); if (ret != 0) { - ret = -9814; + ret = -10114; goto done; } @@ -21152,14 +21152,14 @@ static int ecc_test_custom_curves(WC_RNG* rng) ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); if (ret != 0) { - return -9815; + return -10120; } inOutIdx = 0; ret = wc_EccPublicKeyDecode(eccKeyExplicitCurve, &inOutIdx, &key, sizeof(eccKeyExplicitCurve)); if (ret != 0) - return -9816; + return -10121; wc_ecc_free(&key); @@ -21215,7 +21215,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) #ifdef WOLFSSL_SMALL_STACK der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-9818, exit); + ERROR_OUT(-10130, exit); } #endif @@ -21228,7 +21228,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) #else file = XFOPEN(eccCaKey384File, "rb"); if (!file) { - ERROR_OUT(-9819, exit); + ERROR_OUT(-10131, exit); } bytes = XFREAD(der, 1, FOURK_BUF, file); @@ -21242,7 +21242,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) #else file = XFOPEN(eccCaKeyFile, "rb"); if (!file) { - ERROR_OUT(-9820, exit); + ERROR_OUT(-10132, exit); } bytes = XFREAD(der, 1, FOURK_BUF, file); XFCLOSE(file); @@ -21255,17 +21255,17 @@ static int ecc_test_cert_gen(WC_RNG* rng) /* Get CA Key */ ret = wc_ecc_init_ex(caEccKey, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-9821, exit); + ERROR_OUT(-10133, exit); } ret = wc_EccPrivateKeyDecode(der, &idx, caEccKey, (word32)bytes); if (ret != 0) { - ERROR_OUT(-9822, exit); + ERROR_OUT(-10134, exit); } /* Make a public key */ ret = wc_ecc_init_ex(certPubKey, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-9823, exit); + ERROR_OUT(-10135, exit); } ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, certPubKey); @@ -21273,13 +21273,13 @@ static int ecc_test_cert_gen(WC_RNG* rng) ret = wc_AsyncWait(ret, &certPubKey->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-9824, exit); + ERROR_OUT(-10136, exit); } TEST_SLEEP(); /* Setup Certificate */ if (wc_InitCert(myCert)) { - ERROR_OUT(-9825, exit); + ERROR_OUT(-10137, exit); } #ifndef NO_SHA256 @@ -21299,17 +21299,17 @@ static int ecc_test_cert_gen(WC_RNG* rng) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, NULL, certPubKey) != 0) { - ERROR_OUT(-9826, exit); + ERROR_OUT(-10138, exit); } /* add AKID from the Public Key */ if (wc_SetAuthKeyIdFromPublicKey(myCert, NULL, caEccKey) != 0) { - ERROR_OUT(-9827, exit); + ERROR_OUT(-10139, exit); } /* add Key Usage */ if (wc_SetKeyUsage(myCert, certKeyUsage) != 0) { - ERROR_OUT(-9828, exit); + ERROR_OUT(-10140, exit); } #endif /* WOLFSSL_CERT_EXT */ @@ -21333,12 +21333,12 @@ static int ecc_test_cert_gen(WC_RNG* rng) #endif #endif /* ENABLE_ECC384_CERT_GEN_TEST */ if (ret < 0) { - ERROR_OUT(-9829, exit); + ERROR_OUT(-10141, exit); } certSz = wc_MakeCert(myCert, der, FOURK_BUF, NULL, certPubKey, rng); if (certSz < 0) { - ERROR_OUT(-9830, exit); + ERROR_OUT(-10142, exit); } ret = 0; @@ -21352,7 +21352,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-9831, exit); + ERROR_OUT(-10143, exit); } certSz = ret; TEST_SLEEP(); @@ -21362,7 +21362,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) ret = ParseCert(decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(decode); - ERROR_OUT(-9832, exit); + ERROR_OUT(-10144, exit); } FreeDecodedCert(decode); @@ -21412,12 +21412,12 @@ static int ecc_test_allocator(WC_RNG* rng) key = wc_ecc_key_new(HEAP_HINT); if (key == NULL) { - ERROR_OUT(-9833, exit); + ERROR_OUT(-10150, exit); } ret = wc_ecc_make_key(rng, ECC_KEYGEN_SIZE, key); if (ret != 0) { - ERROR_OUT(-9834, exit); + ERROR_OUT(-10151, exit); } exit: @@ -21433,13 +21433,13 @@ exit: defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY) /* Test Data - Random */ static const uint8_t kMsg[] = { - 0x69, 0xbc, 0x9f, 0xce, 0x68, 0x17, 0xc2, 0x10, 0xea, 0xfc, 0x10, 0x65, 0x67, 0x52, 0xed, 0x78, - 0x6e, 0xb8, 0x83, 0x9c, 0x9a, 0xb4, 0x56, 0x0d, 0xc1, 0x0d, 0x1f, 0x78, 0x6e, 0x75, 0xd7, 0xbe, - 0x92, 0x6b, 0x12, 0xf6, 0x76, 0x60, 0x8e, 0xb1, 0xf4, 0x19, 0x0c, 0x81, 0xe7, 0x54, 0x5e, 0xbc, - 0xe0, 0xae, 0xc2, 0x7d, 0x1b, 0xc4, 0x6e, 0xec, 0xb1, 0x99, 0x6c, 0xbf, 0x0e, 0x38, 0xa8, 0x01, - 0xa6, 0x9a, 0x48, 0x12, 0xe4, 0xc9, 0x3b, 0xf0, 0x63, 0x46, 0x15, 0xb4, 0x61, 0xa8, 0x1a, 0x60, - 0x71, 0x87, 0x98, 0xd7, 0x6f, 0x98, 0x7b, 0x2d, 0xb9, 0x19, 0x1b, 0x21, 0x9c, 0x70, 0x58, 0xe8, - 0x0d, 0x0f, 0xe9, 0x2d, 0x9a, 0x9a, 0xf1, 0x55, 0xa0, 0x4c, 0xd3, 0x07, 0xbd, 0x97, 0x48, 0xec, + 0x69, 0xbc, 0x9f, 0xce, 0x68, 0x17, 0xc2, 0x10, 0xea, 0xfc, 0x10, 0x65, 0x67, 0x52, 0xed, 0x78, + 0x6e, 0xb8, 0x83, 0x9c, 0x9a, 0xb4, 0x56, 0x0d, 0xc1, 0x0d, 0x1f, 0x78, 0x6e, 0x75, 0xd7, 0xbe, + 0x92, 0x6b, 0x12, 0xf6, 0x76, 0x60, 0x8e, 0xb1, 0xf4, 0x19, 0x0c, 0x81, 0xe7, 0x54, 0x5e, 0xbc, + 0xe0, 0xae, 0xc2, 0x7d, 0x1b, 0xc4, 0x6e, 0xec, 0xb1, 0x99, 0x6c, 0xbf, 0x0e, 0x38, 0xa8, 0x01, + 0xa6, 0x9a, 0x48, 0x12, 0xe4, 0xc9, 0x3b, 0xf0, 0x63, 0x46, 0x15, 0xb4, 0x61, 0xa8, 0x1a, 0x60, + 0x71, 0x87, 0x98, 0xd7, 0x6f, 0x98, 0x7b, 0x2d, 0xb9, 0x19, 0x1b, 0x21, 0x9c, 0x70, 0x58, 0xe8, + 0x0d, 0x0f, 0xe9, 0x2d, 0x9a, 0x9a, 0xf1, 0x55, 0xa0, 0x4c, 0xd3, 0x07, 0xbd, 0x97, 0x48, 0xec, 0x88, 0x0a, 0xaf, 0xb3, 0x80, 0x78, 0xa4, 0x59, 0x43, 0x57, 0xd3, 0xa7, 0x01, 0x66, 0x0e, 0xfc }; @@ -21448,18 +21448,18 @@ static const uint8_t kPrivKey[] = { #ifdef HAVE_ECC384 /* SECP384R1 */ /* d */ - 0xa4, 0xe5, 0x06, 0xe8, 0x06, 0x16, 0x3e, 0xab, + 0xa4, 0xe5, 0x06, 0xe8, 0x06, 0x16, 0x3e, 0xab, 0x89, 0xf8, 0x60, 0x43, 0xc0, 0x60, 0x25, 0xdb, - 0xba, 0x7b, 0xfe, 0x19, 0x35, 0x08, 0x55, 0x65, - 0x76, 0xe2, 0xdc, 0xe0, 0x01, 0x8b, 0x6b, 0x68, - 0xdf, 0xcf, 0x6f, 0x80, 0x12, 0xce, 0x79, 0x37, + 0xba, 0x7b, 0xfe, 0x19, 0x35, 0x08, 0x55, 0x65, + 0x76, 0xe2, 0xdc, 0xe0, 0x01, 0x8b, 0x6b, 0x68, + 0xdf, 0xcf, 0x6f, 0x80, 0x12, 0xce, 0x79, 0x37, 0xeb, 0x2b, 0x9c, 0x7b, 0xc4, 0x68, 0x1c, 0x74 #else /* SECP256R1 */ /* d */ - 0x1e, 0xe7, 0x70, 0x07, 0xd3, 0x30, 0x94, 0x39, - 0x28, 0x90, 0xdf, 0x23, 0x88, 0x2c, 0x4a, 0x34, - 0x15, 0xdb, 0x4c, 0x43, 0xcd, 0xfa, 0xe5, 0x1f, + 0x1e, 0xe7, 0x70, 0x07, 0xd3, 0x30, 0x94, 0x39, + 0x28, 0x90, 0xdf, 0x23, 0x88, 0x2c, 0x4a, 0x34, + 0x15, 0xdb, 0x4c, 0x43, 0xcd, 0xfa, 0xe5, 0x1f, 0x3d, 0x4c, 0x37, 0xfe, 0x59, 0x3b, 0x96, 0xd8 #endif }; @@ -21469,30 +21469,30 @@ static const uint8_t kPubKey[] = { #ifdef HAVE_ECC384 /* SECP384R1 */ /* Qx */ - 0xea, 0xcf, 0x93, 0x4f, 0x2c, 0x09, 0xbb, 0x39, - 0x14, 0x0f, 0x56, 0x64, 0xc3, 0x40, 0xb4, 0xdf, - 0x0e, 0x63, 0xae, 0xe5, 0x71, 0x4b, 0x00, 0xcc, - 0x04, 0x97, 0xff, 0xe1, 0xe9, 0x38, 0x96, 0xbb, - 0x5f, 0x91, 0xb2, 0x6a, 0xcc, 0xb5, 0x39, 0x5f, + 0xea, 0xcf, 0x93, 0x4f, 0x2c, 0x09, 0xbb, 0x39, + 0x14, 0x0f, 0x56, 0x64, 0xc3, 0x40, 0xb4, 0xdf, + 0x0e, 0x63, 0xae, 0xe5, 0x71, 0x4b, 0x00, 0xcc, + 0x04, 0x97, 0xff, 0xe1, 0xe9, 0x38, 0x96, 0xbb, + 0x5f, 0x91, 0xb2, 0x6a, 0xcc, 0xb5, 0x39, 0x5f, 0x8f, 0x70, 0x59, 0xf1, 0x01, 0xf6, 0x5a, 0x2b, /* Qy */ - 0x01, 0x6c, 0x68, 0x0b, 0xcf, 0x55, 0x25, 0xaf, - 0x6d, 0x98, 0x48, 0x0a, 0xa8, 0x74, 0xc9, 0xa9, - 0x17, 0xa0, 0x0c, 0xc3, 0xfb, 0xd3, 0x23, 0x68, - 0xfe, 0x04, 0x3c, 0x63, 0x50, 0x88, 0x3b, 0xb9, - 0x4f, 0x7c, 0x67, 0x34, 0xf7, 0x3b, 0xa9, 0x73, + 0x01, 0x6c, 0x68, 0x0b, 0xcf, 0x55, 0x25, 0xaf, + 0x6d, 0x98, 0x48, 0x0a, 0xa8, 0x74, 0xc9, 0xa9, + 0x17, 0xa0, 0x0c, 0xc3, 0xfb, 0xd3, 0x23, 0x68, + 0xfe, 0x04, 0x3c, 0x63, 0x50, 0x88, 0x3b, 0xb9, + 0x4f, 0x7c, 0x67, 0x34, 0xf7, 0x3b, 0xa9, 0x73, 0xe7, 0x1b, 0xc3, 0x51, 0x5e, 0x22, 0x18, 0xec #else /* SECP256R1 */ /* Qx */ - 0x96, 0x93, 0x1c, 0x53, 0x0b, 0x43, 0x6c, 0x42, - 0x0c, 0x52, 0x90, 0xe4, 0xa7, 0xec, 0x98, 0xb1, - 0xaf, 0xd4, 0x14, 0x49, 0xd8, 0xc1, 0x42, 0x82, - 0x04, 0x78, 0xd1, 0x90, 0xae, 0xa0, 0x6c, 0x07, + 0x96, 0x93, 0x1c, 0x53, 0x0b, 0x43, 0x6c, 0x42, + 0x0c, 0x52, 0x90, 0xe4, 0xa7, 0xec, 0x98, 0xb1, + 0xaf, 0xd4, 0x14, 0x49, 0xd8, 0xc1, 0x42, 0x82, + 0x04, 0x78, 0xd1, 0x90, 0xae, 0xa0, 0x6c, 0x07, /* Qy */ - 0xf2, 0x3a, 0xb5, 0x10, 0x32, 0x8d, 0xce, 0x9e, - 0x76, 0xa0, 0xd2, 0x8c, 0xf3, 0xfc, 0xa9, 0x94, - 0x43, 0x24, 0xe6, 0x82, 0x00, 0x40, 0xc6, 0xdb, + 0xf2, 0x3a, 0xb5, 0x10, 0x32, 0x8d, 0xce, 0x9e, + 0x76, 0xa0, 0xd2, 0x8c, 0xf3, 0xfc, 0xa9, 0x94, + 0x43, 0x24, 0xe6, 0x82, 0x00, 0x40, 0xc6, 0xdb, 0x1c, 0x2f, 0xcd, 0x38, 0x4b, 0x60, 0xdd, 0x61 #endif }; @@ -21527,15 +21527,15 @@ static const uint8_t kPubKey[] = { #if defined(HAVE_ECC384) && defined(WOLFSSL_SHA3) /* helper to perform hashing block by block */ -static int crypto_sha3_384(const uint8_t *buf, uint32_t len, uint8_t *hash, +static int crypto_sha3_384(const uint8_t *buf, uint32_t len, uint8_t *hash, uint32_t hashSz, uint32_t blkSz) { int ret; uint32_t i = 0, chunk; wc_Sha3 sha3; - + /* validate arguments */ - if ((buf == NULL && len > 0) || hash == NULL || + if ((buf == NULL && len > 0) || hash == NULL || hashSz < WC_SHA3_384_DIGEST_SIZE || blkSz == 0) { return BAD_FUNC_ARG; @@ -21565,15 +21565,15 @@ static int crypto_sha3_384(const uint8_t *buf, uint32_t len, uint8_t *hash, } #elif defined(HAVE_ECC384) && defined(WOLFSSL_SHA384) /* helper to perform hashing block by block */ -static int crypto_sha2_384(const uint8_t *buf, uint32_t len, uint8_t *hash, +static int crypto_sha2_384(const uint8_t *buf, uint32_t len, uint8_t *hash, uint32_t hashSz, uint32_t blkSz) { int ret; uint32_t i = 0, chunk; wc_Sha384 sha384; - + /* validate arguments */ - if ((buf == NULL && len > 0) || hash == NULL || + if ((buf == NULL && len > 0) || hash == NULL || hashSz < WC_SHA384_DIGEST_SIZE || blkSz == 0) { return BAD_FUNC_ARG; @@ -21603,15 +21603,15 @@ static int crypto_sha2_384(const uint8_t *buf, uint32_t len, uint8_t *hash, } #elif !defined(NO_SHA256) /* helper to perform hashing block by block */ -static int crypto_sha2_256(const uint8_t *buf, uint32_t len, uint8_t *hash, +static int crypto_sha2_256(const uint8_t *buf, uint32_t len, uint8_t *hash, uint32_t hashSz, uint32_t blkSz) { int ret; uint32_t i = 0, chunk; wc_Sha256 sha256; - + /* validate arguments */ - if ((buf == NULL && len > 0) || hash == NULL || + if ((buf == NULL && len > 0) || hash == NULL || hashSz < WC_SHA256_DIGEST_SIZE || blkSz == 0) { return BAD_FUNC_ARG; @@ -21654,7 +21654,7 @@ static int crypto_ecc_verify(const uint8_t *key, uint32_t keySz, ecc_nb_ctx_t nb_ctx; /* validate arguments */ - if (key == NULL || hash == NULL || sig == NULL || curveSz == 0 || + if (key == NULL || hash == NULL || sig == NULL || curveSz == 0 || hashSz == 0 || keySz < (curveSz*2) || sigSz < (curveSz*2)) { return BAD_FUNC_ARG; @@ -21687,7 +21687,7 @@ static int crypto_ecc_verify(const uint8_t *key, uint32_t keySz, /* Import public key x/y */ ret = wc_ecc_import_unsigned( - &ecc, + &ecc, (byte*)key, /* Public "x" Coordinate */ (byte*)(key + curveSz), /* Public "y" Coordinate */ NULL, /* Private "d" (optional) */ @@ -21723,7 +21723,7 @@ static int crypto_ecc_verify(const uint8_t *key, uint32_t keySz, printf("ECC non-block verify: %d times\n", count); #endif } - + /* check verify result */ if (ret == 0 && verify_res == 0) { ret = SIG_VERIFY_E; @@ -21838,9 +21838,9 @@ static int ecc_test_nonblock(WC_RNG* rng) ); if (ret == 0) { /* Sign hash using private key */ - /* Note: result of an ECC sign varies for each call even with same - private key and hash. This is because a new random public key is - used for each operation. */ + /* Note: result of an ECC sign varies for each call even with same + private key and hash. This is because a new random public key is + used for each operation. */ ret = crypto_ecc_sign( kPrivKey, sizeof(kPrivKey), /* private key */ hash, sizeof(hash), /* computed hash digest */ @@ -21884,7 +21884,7 @@ static int ecc_test(void) #endif #ifndef WC_NO_RNG if (ret != 0) - return -9900; + return -10300; #endif #if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112 @@ -22062,7 +22062,7 @@ static int ecc_encrypt_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -10000; + return -10400; #ifdef WOLFSSL_SMALL_STACK if ((userA == NULL) || @@ -22085,7 +22085,7 @@ static int ecc_encrypt_test(void) ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0){ - ret = -10001; goto done; + ret = -10401; goto done; } ret = wc_ecc_make_key(&rng, ECC_KEYGEN_SIZE, userB); @@ -22093,7 +22093,7 @@ static int ecc_encrypt_test(void) ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0){ - ret = -10002; goto done; + ret = -10402; goto done; } /* set message to incrementing 0,1,2,etc... */ @@ -22105,47 +22105,47 @@ static int ecc_encrypt_test(void) !defined(HAVE_SELFTEST) ret = wc_ecc_set_rng(userA, &rng); if (ret != 0) { - ret = -10011; goto done; + ret = -10403; goto done; } ret = wc_ecc_set_rng(userB, &rng); if (ret != 0) { - ret = -10012; goto done; + ret = -10404; goto done; } #endif /* encrypt msg to B */ ret = wc_ecc_encrypt(userA, userB, msg, sizeof(msg), out, &outSz, NULL); if (ret != 0) { - ret = -10003; goto done; + ret = -10405; goto done; } /* decrypt msg from A */ ret = wc_ecc_decrypt(userB, userA, out, outSz, plain, &plainSz, NULL); if (ret != 0) { - ret = -10004; goto done; + ret = -10406; goto done; } if (XMEMCMP(plain, msg, sizeof(msg)) != 0) { - ret = -10005; goto done; + ret = -10407; goto done; } /* let's verify message exchange works, A is client, B is server */ cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng); srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng); if (cliCtx == NULL || srvCtx == NULL) { - ret = -10006; goto done; + ret = -10408; goto done; } /* get salt to send to peer */ tmpSalt = wc_ecc_ctx_get_own_salt(cliCtx); if (tmpSalt == NULL) { - ret = -10007; goto done; + ret = -10409; goto done; } XMEMCPY(cliSalt, tmpSalt, EXCHANGE_SALT_SZ); tmpSalt = wc_ecc_ctx_get_own_salt(srvCtx); if (tmpSalt == NULL) { - ret = -10008; goto done; + ret = -10410; goto done; } XMEMCPY(srvSalt, tmpSalt, EXCHANGE_SALT_SZ); @@ -22177,7 +22177,7 @@ static int ecc_encrypt_test(void) goto done; if (XMEMCMP(plain, msg, sizeof(msg)) != 0) { - ret = -10009; goto done; + ret = -10411; goto done; } /* msg2 (response) from B to A */ @@ -22197,7 +22197,7 @@ static int ecc_encrypt_test(void) goto done; if (XMEMCMP(plain2, msg2, sizeof(msg2)) != 0) { - ret = -10010; goto done; + ret = -10412; goto done; } done: @@ -22258,17 +22258,17 @@ static int ecc_test_buffers(void) ret = wc_ecc_init_ex(cliKey, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(-10011, done); + ERROR_OUT(-10420, done); ret = wc_ecc_init_ex(servKey, HEAP_HINT, devId); if (ret != 0) - ERROR_OUT(-10012, done); + ERROR_OUT(-10421, done); bytes = (size_t)sizeof_ecc_clikey_der_256; /* place client key into ecc_key struct cliKey */ ret = wc_EccPrivateKeyDecode(ecc_clikey_der_256, &idx, cliKey, (word32)bytes); if (ret != 0) - ERROR_OUT(-10013, done); + ERROR_OUT(-10422, done); idx = 0; bytes = (size_t)sizeof_ecc_key_der_256; @@ -22277,7 +22277,7 @@ static int ecc_test_buffers(void) ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, servKey, (word32)bytes); if (ret != 0) - ERROR_OUT(-10014, done); + ERROR_OUT(-10423, done); #ifndef HAVE_FIPS ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); @@ -22285,14 +22285,14 @@ static int ecc_test_buffers(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - ERROR_OUT(-10015, done); + ERROR_OUT(-10424, done); #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ !defined(HAVE_SELFTEST) ret = wc_ecc_set_rng(cliKey, &rng); if (ret != 0) { - ERROR_OUT(-10023, done); + ERROR_OUT(-10425, done); } #endif @@ -22303,15 +22303,15 @@ static int ecc_test_buffers(void) x = sizeof(out); ret = wc_ecc_encrypt(cliKey, servKey, in, sizeof(in), out, &x, NULL); if (ret < 0) - ERROR_OUT(-10016, done); + ERROR_OUT(-10426, done); y = sizeof(plain); ret = wc_ecc_decrypt(cliKey, servKey, out, x, plain, &y, NULL); if (ret < 0) - ERROR_OUT(-10017, done); + ERROR_OUT(-10427, done); if (XMEMCMP(plain, in, inLen)) - ERROR_OUT(-10018, done); + ERROR_OUT(-10428, done); } #endif @@ -22324,7 +22324,7 @@ static int ecc_test_buffers(void) ret = wc_ecc_sign_hash(in, inLen, out, &x, &rng, cliKey); } while (ret == WC_PENDING_E); if (ret < 0) - ERROR_OUT(-10019, done); + ERROR_OUT(-10429, done); TEST_SLEEP(); XMEMSET(plain, 0, sizeof(plain)); @@ -22338,10 +22338,10 @@ static int ecc_test_buffers(void) cliKey); } while (ret == WC_PENDING_E); if (ret < 0) - ERROR_OUT(-10020, done); + ERROR_OUT(-10430, done); if (XMEMCMP(plain, in, (word32)ret)) - ERROR_OUT(-10021, done); + ERROR_OUT(-10431, done); TEST_SLEEP(); #ifdef WOLFSSL_CERT_EXT @@ -22352,7 +22352,7 @@ static int ecc_test_buffers(void) ret = wc_EccPublicKeyDecode(ecc_clikeypub_der_256, &idx, cliKey, (word32) bytes); if (ret != 0) - ERROR_OUT(-10022, done); + ERROR_OUT(-10432, done); #endif ret = 0; @@ -22510,16 +22510,16 @@ static int curve25519_overflow_test(void) for (i = 0; i < X25519_TEST_CNT; i++) { if (wc_curve25519_import_private_raw(sa[i], sizeof(sa[i]), pb[i], sizeof(pb[i]), &userA) != 0) - return -10100 - i; + return -10500 - i; /* test against known test vector */ XMEMSET(shared, 0, sizeof(shared)); y = sizeof(shared); if (wc_curve25519_shared_secret(&userA, &userA, shared, &y) != 0) - return -10110 - i; + return -10510 - i; if (XMEMCMP(ss[i], shared, y)) - return -10120 - i; + return -10520 - i; } return 0; @@ -22586,17 +22586,17 @@ static int curve25519_check_public_test(void) /* NULL pointer */ if (wc_curve25519_check_public(NULL, 0, EC25519_LITTLE_ENDIAN) != BAD_FUNC_ARG) { - return -10200; + return -10600; } if (wc_curve25519_check_public(NULL, 0, EC25519_BIG_ENDIAN) != BAD_FUNC_ARG) { - return -10201; + return -10601; } /* Length of 0 treated differently to other invalid lengths for TLS */ if (wc_curve25519_check_public(good, 0, EC25519_LITTLE_ENDIAN) != BUFFER_E) - return -10202; + return -10602; if (wc_curve25519_check_public(good, 0, EC25519_BIG_ENDIAN) != BUFFER_E) - return -10203; + return -10603; /* Length not CURVE25519_KEYSIZE */ for (i = 1; i < CURVE25519_KEYSIZE + 2; i++) { @@ -22604,11 +22604,11 @@ static int curve25519_check_public_test(void) continue; if (wc_curve25519_check_public(good, i, EC25519_LITTLE_ENDIAN) != ECC_BAD_ARG_E) { - return -10204 - i; + return -10604 - i; } if (wc_curve25519_check_public(good, i, EC25519_BIG_ENDIAN) != ECC_BAD_ARG_E) { - return -10214 - i; + return -10614 - i; } } @@ -22616,25 +22616,25 @@ static int curve25519_check_public_test(void) for (i = 0; i < (int)(sizeof(fail_le) / sizeof(*fail_le)); i++) { if (wc_curve25519_check_public(fail_le[i], CURVE25519_KEYSIZE, EC25519_LITTLE_ENDIAN) == 0) { - return -10224 - i; + return -10624 - i; } } /* Big-endian fail cases */ for (i = 0; i < (int)(sizeof(fail_be) / sizeof(*fail_be)); i++) { if (wc_curve25519_check_public(fail_be[i], CURVE25519_KEYSIZE, EC25519_BIG_ENDIAN) == 0) { - return -10234 - i; + return -10634 - i; } } /* Check a valid public value works! */ if (wc_curve25519_check_public(good, CURVE25519_KEYSIZE, EC25519_LITTLE_ENDIAN) != 0) { - return -10244; + return -10644; } if (wc_curve25519_check_public(good, CURVE25519_KEYSIZE, EC25519_BIG_ENDIAN) != 0) { - return -10245; + return -10645; } return 0; @@ -22712,7 +22712,7 @@ static int curve25519_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -10300; + return -10700; wc_curve25519_init(&userA); wc_curve25519_init(&userB); @@ -22720,38 +22720,38 @@ static int curve25519_test(void) /* make curve25519 keys */ if (wc_curve25519_make_key(&rng, 32, &userA) != 0) - return -10301; + return -10701; if (wc_curve25519_make_key(&rng, 32, &userB) != 0) - return -10302; + return -10702; #ifdef HAVE_CURVE25519_SHARED_SECRET /* find shared secret key */ x = sizeof(sharedA); if (wc_curve25519_shared_secret(&userA, &userB, sharedA, &x) != 0) - return -10303; + return -10703; y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -10304; + return -10704; /* compare shared secret keys to test they are the same */ if (y != x) - return -10305; + return -10705; if (XMEMCMP(sharedA, sharedB, x)) - return -10306; + return -10706; #endif #ifdef HAVE_CURVE25519_KEY_EXPORT /* export a public key and import it for another user */ x = sizeof(exportBuf); if (wc_curve25519_export_public(&userA, exportBuf, &x) != 0) - return -10307; + return -10707; #ifdef HAVE_CURVE25519_KEY_IMPORT if (wc_curve25519_import_public(exportBuf, x, &pubKey) != 0) - return -10308; + return -10708; #endif #endif @@ -22761,60 +22761,60 @@ static int curve25519_test(void) XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &pubKey, sharedB, &y) != 0) - return -10309; + return -10709; if (XMEMCMP(sharedA, sharedB, y)) - return -10310; + return -10710; /* import RFC test vectors and compare shared key */ if (wc_curve25519_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) != 0) - return -10311; + return -10711; if (wc_curve25519_import_private_raw(sb, sizeof(sb), pb, sizeof(pb), &userB) != 0) - return -10312; + return -10712; /* test against known test vector */ XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userA, &userB, sharedB, &y) != 0) - return -10313; + return -10713; if (XMEMCMP(ss, sharedB, y)) - return -10314; + return -10714; /* test swapping roles of keys and generating same shared key */ XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -10315; + return -10715; if (XMEMCMP(ss, sharedB, y)) - return -10316; + return -10716; /* test with 1 generated key and 1 from known test vector */ if (wc_curve25519_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) != 0) - return -10317; + return -10717; if (wc_curve25519_make_key(&rng, 32, &userB) != 0) - return -10318; + return -10718; x = sizeof(sharedA); if (wc_curve25519_shared_secret(&userA, &userB, sharedA, &x) != 0) - return -10319; + return -10719; y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -10320; + return -10720; /* compare shared secret keys to test they are the same */ if (y != x) - return -10321; + return -10721; if (XMEMCMP(sharedA, sharedB, x)) - return -10322; + return -10722; ret = curve25519_overflow_test(); if (ret != 0) @@ -22855,7 +22855,7 @@ static int ed25519_test_cert(void) tmp = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - ERROR_OUT(-10323, done); + ERROR_OUT(-10730, done); } #ifdef USE_CERT_BUFFERS_256 @@ -22864,20 +22864,20 @@ static int ed25519_test_cert(void) #elif !defined(NO_FILESYSTEM) file = XFOPEN(caEd25519Cert, "rb"); if (file == NULL) { - ERROR_OUT(-10324, done); + ERROR_OUT(-10731, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No certificate to use. */ - ERROR_OUT(-10325, done); + ERROR_OUT(-10732, done); #endif InitDecodedCert(&cert[0], tmp, (word32)bytes, 0); caCert = &cert[0]; ret = ParseCert(caCert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-10326, done); + ERROR_OUT(-10733, done); } #ifdef USE_CERT_BUFFERS_256 @@ -22886,39 +22886,39 @@ static int ed25519_test_cert(void) #elif !defined(NO_FILESYSTEM) file = XFOPEN(serverEd25519Cert, "rb"); if (file == NULL) { - ERROR_OUT(-10327, done); + ERROR_OUT(-10734, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No certificate to use. */ - ERROR_OUT(-10328, done); + ERROR_OUT(-10735, done); #endif InitDecodedCert(&cert[1], tmp, (word32)bytes, 0); serverCert = &cert[1]; ret = ParseCert(serverCert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-10329, done); + ERROR_OUT(-10736, done); } #ifdef HAVE_ED25519_VERIFY ret = wc_ed25519_init(&key); if (ret < 0) { - ERROR_OUT(-10330, done); + ERROR_OUT(-10737, done); } pubKey = &key; ret = wc_ed25519_import_public(caCert->publicKey, caCert->pubKeySize, pubKey); if (ret < 0) { - ERROR_OUT(-10331, done); + ERROR_OUT(-10738, done); } if (wc_ed25519_verify_msg(serverCert->signature, serverCert->sigLength, serverCert->source + serverCert->certBegin, serverCert->sigIndex - serverCert->certBegin, &verify, pubKey) < 0 || verify != 1) { - ERROR_OUT(-10332, done); + ERROR_OUT(-10739, done); } #endif /* HAVE_ED25519_VERIFY */ @@ -22954,7 +22954,7 @@ static int ed25519_test_make_cert(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -10333; + return -10750; wc_ed25519_init(&key); privKey = &key; @@ -22968,38 +22968,38 @@ static int ed25519_test_make_cert(void) #ifdef WOLFSSL_CERT_EXT ret = wc_SetKeyUsage(&cert, certKeyUsage); if (ret < 0) { - ERROR_OUT(-10334, done); + ERROR_OUT(-10751, done); } ret = wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED25519_TYPE, privKey); if (ret < 0) { - ERROR_OUT(-10335, done); + ERROR_OUT(-10752, done); } ret = wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED25519_TYPE, privKey); if (ret < 0) { - ERROR_OUT(-10336, done); + ERROR_OUT(-10753, done); } #endif tmp = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - ERROR_OUT(-10337, done); + ERROR_OUT(-10754, done); } cert.sigType = CTC_ED25519; ret = wc_MakeCert_ex(&cert, tmp, FOURK_BUF, ED25519_TYPE, privKey, &rng); if (ret < 0) { - ERROR_OUT(-10338, done); + ERROR_OUT(-10755, done); } ret = wc_SignCert_ex(cert.bodySz, cert.sigType, tmp, FOURK_BUF, ED25519_TYPE, privKey, &rng); if (ret < 0) { - ERROR_OUT(-10339, done); + ERROR_OUT(-10756, done); } InitDecodedCert(&decode, tmp, ret, HEAP_HINT); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); FreeDecodedCert(&decode); if (ret != 0) { - ERROR_OUT(-10340, done); + ERROR_OUT(-10757, done); } done: @@ -23072,35 +23072,35 @@ static int ed25519ctx_test(void) if (wc_ed25519_import_private_key(sKeyCtx, ED25519_KEY_SIZE, pKeyCtx, sizeof(pKeyCtx), &key) != 0) - return -10400; + return -10800; if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, contextCtx, sizeof(contextCtx)) != 0) - return -10401; + return -10801; if (XMEMCMP(out, sigCtx1, 64)) - return -10402; + return -10802; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key, contextCtx, sizeof(contextCtx)) != 0 || verify != 1) - return -10403; + return -10803; #endif if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, NULL, 0) != 0) - return -10404; + return -10804; if (XMEMCMP(out, sigCtx2, 64)) - return -10405; + return -10805; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key, NULL, 0) != 0 || verify != 1) - return -10406; + return -10806; #endif wc_ed25519_free(&key); @@ -23178,72 +23178,72 @@ static int ed25519ph_test(void) if (wc_ed25519_import_private_key(sKeyPh, ED25519_KEY_SIZE, pKeyPh, sizeof(pKeyPh), &key) != 0) { - return -10500; + return -10900; } if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL, 0) != 0) { - return -10501; + return -10901; } if (XMEMCMP(out, sigPh1, 64)) - return -10502; + return -10902; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, NULL, 0) != 0 || verify != 1) { - return -10503; + return -10903; } #endif if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, contextPh2, sizeof(contextPh2)) != 0) { - return -10504; + return -10904; } if (XMEMCMP(out, sigPh2, 64)) - return -10505; + return -10905; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, contextPh2, sizeof(contextPh2)) != 0 || verify != 1) { - return -10506; + return -10906; } #endif if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL, 0) != 0) { - return -10507; + return -10907; } if (XMEMCMP(out, sigPh1, 64)) - return -10508; + return -10908; #if defined(HAVE_ED25519_VERIFY) if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, &key, NULL, 0) != 0 || verify != 1) { - return -10509; + return -10909; } #endif if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, contextPh2, sizeof(contextPh2)) != 0) { - return -10510; + return -10910; } if (XMEMCMP(out, sigPh2, 64)) - return -10511; + return -10911; #if defined(HAVE_ED25519_VERIFY) if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, &key, contextPh2, sizeof(contextPh2)) != 0 || verify != 1) { - return -10512; + return -10912; } #endif @@ -23636,7 +23636,7 @@ static int ed25519_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -10600; + return -11000; wc_ed25519_init(&key); wc_ed25519_init(&key2); @@ -23658,56 +23658,56 @@ static int ed25519_test(void) if (wc_ed25519_import_private_key(sKeys[i], ED25519_KEY_SIZE, pKeys[i], pKeySz[i], &key) != 0) - return -10601 - i; + return -11001 - i; if (wc_ed25519_sign_msg(msgs[i], msgSz[i], out, &outlen, &key) != 0) - return -10611 - i; + return -11011 - i; if (XMEMCMP(out, sigs[i], 64)) - return -10621 - i; + return -11021 - i; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key) != 0 || verify != 1) - return -10631 - i; + return -11031 - i; /* test verify on bad msg */ out[outlen-1] = out[outlen-1] + 1; if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key) == 0 || verify == 1) - return -10641 - i; + return -11041 - i; #endif /* HAVE_ED25519_VERIFY */ /* test api for import/exporting keys */ exportPSz = sizeof(exportPKey); exportSSz = sizeof(exportSKey); if (wc_ed25519_export_public(&key, exportPKey, &exportPSz) != 0) - return -10651 - i; + return -11051 - i; if (wc_ed25519_import_public(exportPKey, exportPSz, &key2) != 0) - return -10661 - i; + return -11061 - i; if (wc_ed25519_export_private_only(&key, exportSKey, &exportSSz) != 0) - return -10671 - i; + return -11071 - i; if (wc_ed25519_import_private_key(exportSKey, exportSSz, exportPKey, exportPSz, &key2) != 0) - return -10681 - i; + return -11081 - i; /* clear "out" buffer and test sign with imported keys */ outlen = sizeof(out); XMEMSET(out, 0, sizeof(out)); if (wc_ed25519_sign_msg(msgs[i], msgSz[i], out, &outlen, &key2) != 0) - return -10691 - i; + return -11091 - i; #if defined(HAVE_ED25519_VERIFY) if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key2) != 0 || verify != 1) - return -10701 - i; + return -11101 - i; if (XMEMCMP(out, sigs[i], 64)) - return -10711 - i; + return -11111 - i; #endif /* HAVE_ED25519_VERIFY */ } @@ -23724,28 +23724,28 @@ static int ed25519_test(void) idx = 0; if (wc_Ed25519PrivateKeyDecode(privateEd25519, &idx, &key3, sizeof(privateEd25519)) != 0) - return -10721 - i; + return -11121 - i; if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != BAD_FUNC_ARG) - return -10731 - i; + return -11131 - i; idx = 0; if (wc_Ed25519PublicKeyDecode(publicEd25519, &idx, &key3, sizeof(publicEd25519)) != 0) - return -10741 - i; + return -11141 - i; if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != 0) - return -10751 - i; + return -11151 - i; if (XMEMCMP(out, sigs[0], 64)) - return -10761 - i; + return -11161 - i; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519_verify_msg(out, outlen, msgs[0], msgSz[0], &verify, &key3) != 0 || verify != 1) - return -10771 - i; + return -11171 - i; #endif /* HAVE_ED25519_VERIFY */ wc_ed25519_free(&key3); @@ -23754,13 +23754,13 @@ static int ed25519_test(void) idx = 0; if (wc_Ed25519PrivateKeyDecode(privPubEd25519, &idx, &key3, sizeof(privPubEd25519)) != 0) - return -10781 - i; + return -11181 - i; if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != 0) - return -10791 - i; + return -11191 - i; if (XMEMCMP(out, sigs[0], 64)) - return -10801 - i; + return -11201 - i; wc_ed25519_free(&key3); #endif /* NO_ASN */ @@ -23860,16 +23860,16 @@ static int curve448_check_public_test(void) /* NULL pointer */ if (wc_curve448_check_public(NULL, 0, EC448_LITTLE_ENDIAN) != BAD_FUNC_ARG) { - return -10900; + return -11300; } if (wc_curve448_check_public(NULL, 0, EC448_BIG_ENDIAN) != BAD_FUNC_ARG) { - return -10901; + return -11301; } /* Length of 0 treated differently to other invalid lengths for TLS */ if (wc_curve448_check_public(good, 0, EC448_LITTLE_ENDIAN) != BUFFER_E) - return -10902; + return -11302; if (wc_curve448_check_public(good, 0, EC448_BIG_ENDIAN) != BUFFER_E) - return -10903; + return -11303; /* Length not CURVE448_KEY_SIZE */ for (i = 1; i < CURVE448_KEY_SIZE + 2; i++) { @@ -23877,11 +23877,11 @@ static int curve448_check_public_test(void) continue; if (wc_curve448_check_public(good, i, EC448_LITTLE_ENDIAN) != ECC_BAD_ARG_E) { - return -10904 - i; + return -11304 - i; } if (wc_curve448_check_public(good, i, EC448_BIG_ENDIAN) != ECC_BAD_ARG_E) { - return -10914 - i; + return -11314 - i; } } @@ -23889,25 +23889,25 @@ static int curve448_check_public_test(void) for (i = 0; i < (int)(sizeof(fail_le) / sizeof(*fail_le)); i++) { if (wc_curve448_check_public(fail_le[i], CURVE448_KEY_SIZE, EC448_LITTLE_ENDIAN) == 0) { - return -10924 - i; + return -11324 - i; } } /* Big-endian fail cases */ for (i = 0; i < (int)(sizeof(fail_be) / sizeof(*fail_be)); i++) { if (wc_curve448_check_public(fail_be[i], CURVE448_KEY_SIZE, EC448_BIG_ENDIAN) == 0) { - return -10934 - i; + return -11334 - i; } } /* Check a valid public value works! */ if (wc_curve448_check_public(good, CURVE448_KEY_SIZE, EC448_LITTLE_ENDIAN) != 0) { - return -10944; + return -11344; } if (wc_curve448_check_public(good, CURVE448_KEY_SIZE, EC448_BIG_ENDIAN) != 0) { - return -10945; + return -11345; } return 0; @@ -24000,7 +24000,7 @@ static int curve448_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -11000; + return -11400; wc_curve448_init(&userA); wc_curve448_init(&userB); @@ -24008,38 +24008,38 @@ static int curve448_test(void) /* make curve448 keys */ if (wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &userA) != 0) - return -11001; + return -11401; if (wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &userB) != 0) - return -11002; + return -11402; #ifdef HAVE_CURVE448_SHARED_SECRET /* find shared secret key */ x = sizeof(sharedA); if (wc_curve448_shared_secret(&userA, &userB, sharedA, &x) != 0) - return -11003; + return -11403; y = sizeof(sharedB); if (wc_curve448_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -11004; + return -11404; /* compare shared secret keys to test they are the same */ if (y != x) - return -11005; + return -11405; if (XMEMCMP(sharedA, sharedB, x)) - return -11006; + return -11406; #endif #ifdef HAVE_CURVE448_KEY_EXPORT /* export a public key and import it for another user */ x = sizeof(exportBuf); if (wc_curve448_export_public(&userA, exportBuf, &x) != 0) - return -11007; + return -11407; #ifdef HAVE_CURVE448_KEY_IMPORT if (wc_curve448_import_public(exportBuf, x, &pubKey) != 0) - return -11008; + return -11408; #endif #endif @@ -24049,60 +24049,60 @@ static int curve448_test(void) XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve448_shared_secret(&userB, &pubKey, sharedB, &y) != 0) - return -11009; + return -11409; if (XMEMCMP(sharedA, sharedB, y)) - return -11010; + return -11410; /* import RFC test vectors and compare shared key */ if (wc_curve448_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) != 0) - return -11011; + return -11411; if (wc_curve448_import_private_raw(sb, sizeof(sb), pb, sizeof(pb), &userB) != 0) - return -11012; + return -11412; /* test against known test vector */ XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve448_shared_secret(&userA, &userB, sharedB, &y) != 0) - return -11013; + return -11413; if (XMEMCMP(ss, sharedB, y)) - return -11014; + return -11414; /* test swapping roles of keys and generating same shared key */ XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve448_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -11015; + return -11415; if (XMEMCMP(ss, sharedB, y)) - return -11016; + return -11416; /* test with 1 generated key and 1 from known test vector */ if (wc_curve448_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) != 0) - return -11017; + return -11417; if (wc_curve448_make_key(&rng, 56, &userB) != 0) - return -11018; + return -11418; x = sizeof(sharedA); if (wc_curve448_shared_secret(&userA, &userB, sharedA, &x) != 0) - return -11019; + return -11419; y = sizeof(sharedB); if (wc_curve448_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -11020; + return -11420; /* compare shared secret keys to test they are the same */ if (y != x) - return -11021; + return -11421; if (XMEMCMP(sharedA, sharedB, x)) - return -11022; + return -11422; ret = curve448_check_public_test(); if (ret != 0) @@ -24139,7 +24139,7 @@ static int ed448_test_cert(void) tmp = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - ERROR_OUT(-11023, done); + ERROR_OUT(-11430, done); } #ifdef USE_CERT_BUFFERS_256 @@ -24148,20 +24148,20 @@ static int ed448_test_cert(void) #elif !defined(NO_FILESYSTEM) file = XFOPEN(caEd448Cert, "rb"); if (file == NULL) { - ERROR_OUT(-11024, done); + ERROR_OUT(-11431, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No certificate to use. */ - ERROR_OUT(-11025, done); + ERROR_OUT(-11432, done); #endif InitDecodedCert(&cert[0], tmp, (word32)bytes, 0); caCert = &cert[0]; ret = ParseCert(caCert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-11026, done); + ERROR_OUT(-11433, done); } #ifdef USE_CERT_BUFFERS_256 @@ -24170,38 +24170,38 @@ static int ed448_test_cert(void) #elif !defined(NO_FILESYSTEM) file = XFOPEN(serverEd448Cert, "rb"); if (file == NULL) { - ERROR_OUT(-11027, done); + ERROR_OUT(-11434, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No certificate to use. */ - ERROR_OUT(-11028, done); + ERROR_OUT(-11435, done); #endif InitDecodedCert(&cert[1], tmp, (word32)bytes, 0); serverCert = &cert[1]; ret = ParseCert(serverCert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-11029, done); + ERROR_OUT(-11436, done); } #ifdef HAVE_ED448_VERIFY ret = wc_ed448_init(&key); if (ret < 0) { - ERROR_OUT(-11030, done); + ERROR_OUT(-11437, done); } pubKey = &key; ret = wc_ed448_import_public(caCert->publicKey, caCert->pubKeySize, pubKey); if (ret < 0) { - ERROR_OUT(-11031, done); + ERROR_OUT(-11438, done); } if (wc_ed448_verify_msg(serverCert->signature, serverCert->sigLength, serverCert->source + serverCert->certBegin, serverCert->sigIndex - serverCert->certBegin, &verify, pubKey, NULL, 0) < 0 || verify != 1) { - ERROR_OUT(-11032, done); + ERROR_OUT(-11439, done); } #endif /* HAVE_ED448_VERIFY */ @@ -24237,7 +24237,7 @@ static int ed448_test_make_cert(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -11033; + return -11450; wc_ed448_init(&key); privKey = &key; @@ -24251,38 +24251,38 @@ static int ed448_test_make_cert(void) #ifdef WOLFSSL_CERT_EXT ret = wc_SetKeyUsage(&cert, certKeyUsage); if (ret < 0) { - ERROR_OUT(-11034, done); + ERROR_OUT(-11451, done); } ret = wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED448_TYPE, privKey); if (ret < 0) { - ERROR_OUT(-11035, done); + ERROR_OUT(-11452, done); } ret = wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED448_TYPE, privKey); if (ret < 0) { - ERROR_OUT(-11036, done); + ERROR_OUT(-11453, done); } #endif tmp = (byte *)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - ERROR_OUT(-11037, done); + ERROR_OUT(-11454, done); } cert.sigType = CTC_ED448; ret = wc_MakeCert_ex(&cert, tmp, FOURK_BUF, ED448_TYPE, privKey, &rng); if (ret < 0) { - ERROR_OUT(-11038, done); + ERROR_OUT(-11455, done); } ret = wc_SignCert_ex(cert.bodySz, cert.sigType, tmp, FOURK_BUF, ED448_TYPE, privKey, &rng); if (ret < 0) { - ERROR_OUT(-11039, done); + ERROR_OUT(-11456, done); } InitDecodedCert(&decode, tmp, ret, HEAP_HINT); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); FreeDecodedCert(&decode); if (ret != 0) { - ERROR_OUT(-11040, done); + ERROR_OUT(-11457, done); } done: @@ -24358,20 +24358,20 @@ static int ed448_ctx_test(void) if (wc_ed448_import_private_key(sKeyCtx, ED448_KEY_SIZE, pKeyCtx, sizeof(pKeyCtx), &key) != 0) - return -11100; + return -11500; if (wc_ed448_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, contextCtx, sizeof(contextCtx)) != 0) - return -11101; + return -11501; if (XMEMCMP(out, sigCtx, sizeof(sigCtx))) - return -11102; + return -11502; #if defined(HAVE_ED448_VERIFY) /* test verify on good msg */ if (wc_ed448_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key, contextCtx, sizeof(contextCtx)) != 0 || verify != 1) - return -11103; + return -11503; #endif wc_ed448_free(&key); @@ -24471,70 +24471,70 @@ static int ed448ph_test(void) if (wc_ed448_import_private_key(sKeyPh, ED448_KEY_SIZE, pKeyPh, sizeof(pKeyPh), &key) != 0) { - return -11200; + return -11600; } if (wc_ed448ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL, 0) != 0) { - return -11201; + return -11601; } if (XMEMCMP(out, sigPh1, sizeof(sigPh1))) - return -11202; + return -11602; #if defined(HAVE_ED448_VERIFY) /* test verify on good msg */ if (wc_ed448ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, NULL, 0) != 0 || verify != 1) { - return -11203; + return -11603; } #endif if (wc_ed448ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, contextPh2, sizeof(contextPh2)) != 0) { - return -11204; + return -11604; } if (XMEMCMP(out, sigPh2, sizeof(sigPh2))) - return -11205; + return -11605; #if defined(HAVE_ED448_VERIFY) /* test verify on good msg */ if (wc_ed448ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, contextPh2, sizeof(contextPh2)) != 0 || verify != 1) { - return -11206; + return -11606; } #endif if (wc_ed448ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL, 0) != 0) { - return -11207; + return -11607; } if (XMEMCMP(out, sigPh1, sizeof(sigPh1))) - return -11208; + return -11608; #if defined(HAVE_ED448_VERIFY) if (wc_ed448ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, &key, NULL, 0) != 0 || verify != 1) { - return -11209; + return -11609; } #endif if (wc_ed448ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, contextPh2, sizeof(contextPh2)) != 0) { - return -11210; + return -11610; } if (XMEMCMP(out, sigPh2, sizeof(sigPh2))) - return -11211; + return -11611; #if defined(HAVE_ED448_VERIFY) if (wc_ed448ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, &key, contextPh2, sizeof(contextPh2)) != 0 || verify != 1) { - return -11212; + return -11612; } #endif @@ -25027,7 +25027,7 @@ static int ed448_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -11300; + return -11700; wc_ed448_init(&key); wc_ed448_init(&key2); @@ -25049,28 +25049,28 @@ static int ed448_test(void) if (wc_ed448_import_private_key(sKeys[i], ED448_KEY_SIZE, pKeys[i], pKeySz[i], &key) != 0) - return -11301 - i; + return -11701 - i; if (wc_ed448_sign_msg(msgs[i], msgSz[i], out, &outlen, &key, NULL, 0) != 0) { - return -11311 - i; + return -11711 - i; } if (XMEMCMP(out, sigs[i], 114)) - return -11321 - i; + return -11721 - i; #if defined(HAVE_ED448_VERIFY) /* test verify on good msg */ if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key, NULL, 0) != 0 || verify != 1) { - return -11331 - i; + return -11731 - i; } /* test verify on bad msg */ out[outlen-2] = out[outlen-2] + 1; if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key, NULL, 0) == 0 || verify == 1) { - return -11341 - i; + return -11741 - i; } #endif /* HAVE_ED448_VERIFY */ @@ -25078,33 +25078,33 @@ static int ed448_test(void) exportPSz = sizeof(exportPKey); exportSSz = sizeof(exportSKey); if (wc_ed448_export_public(&key, exportPKey, &exportPSz) != 0) - return -11351 - i; + return -11751 - i; if (wc_ed448_import_public(exportPKey, exportPSz, &key2) != 0) - return -11361 - i; + return -11761 - i; if (wc_ed448_export_private_only(&key, exportSKey, &exportSSz) != 0) - return -11371 - i; + return -11771 - i; if (wc_ed448_import_private_key(exportSKey, exportSSz, exportPKey, exportPSz, &key2) != 0) - return -11381 - i; + return -11781 - i; /* clear "out" buffer and test sign with imported keys */ outlen = sizeof(out); XMEMSET(out, 0, sizeof(out)); if (wc_ed448_sign_msg(msgs[i], msgSz[i], out, &outlen, &key2, NULL, 0) != 0) { - return -11391 - i; + return -11791 - i; } #if defined(HAVE_ED448_VERIFY) if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key2, NULL, 0) != 0 || verify != 1) - return -11401 - i; + return -11801 - i; if (XMEMCMP(out, sigs[i], SIGSZ)) - return -11411 - i; + return -11811 - i; #endif /* HAVE_ED448_VERIFY */ } @@ -25121,28 +25121,28 @@ static int ed448_test(void) idx = 0; if (wc_Ed448PrivateKeyDecode(privateEd448, &idx, &key3, sizeof(privateEd448)) != 0) - return -11421 - i; + return -11821 - i; if (wc_ed448_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3, NULL, 0) != BAD_FUNC_ARG) - return -11431 - i; + return -11831 - i; idx = 0; if (wc_Ed448PublicKeyDecode(publicEd448, &idx, &key3, sizeof(publicEd448)) != 0) - return -11441 - i; + return -11841 - i; if (wc_ed448_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3, NULL, 0) != 0) - return -11451 - i; + return -11851 - i; if (XMEMCMP(out, sigs[0], SIGSZ)) - return -11461 - i; + return -11861 - i; #if defined(HAVE_ED448_VERIFY) /* test verify on good msg */ if (wc_ed448_verify_msg(out, outlen, msgs[0], msgSz[0], &verify, &key3, NULL, 0) != 0 || verify != 1) - return -11471 - i; + return -11871 - i; #endif /* HAVE_ED448_VERIFY */ wc_ed448_free(&key3); @@ -25151,13 +25151,13 @@ static int ed448_test(void) idx = 0; if (wc_Ed448PrivateKeyDecode(privPubEd448, &idx, &key3, sizeof(privPubEd448)) != 0) - return -11481 - i; + return -11881 - i; if (wc_ed448_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3, NULL, 0) != 0) - return -11491 - i; + return -11891 - i; if (XMEMCMP(out, sigs[0], SIGSZ)) - return -11501 - i; + return -11901 - i; wc_ed448_free(&key3); #endif /* NO_ASN */ @@ -25359,34 +25359,34 @@ static int cmac_test(void) XMEMSET(tag, 0, sizeof(tag)); tagSz = AES_BLOCK_SIZE; if (wc_InitCmac(&cmac, tc->k, tc->kSz, tc->type, NULL) != 0) - return -11600; + return -12000; if (tc->partial) { if (wc_CmacUpdate(&cmac, tc->m, tc->mSz/2 - tc->partial) != 0) - return -11601; + return -12001; if (wc_CmacUpdate(&cmac, tc->m + tc->mSz/2 - tc->partial, tc->mSz/2 + tc->partial) != 0) - return -11602; + return -12002; } else { if (wc_CmacUpdate(&cmac, tc->m, tc->mSz) != 0) - return -11603; + return -12003; } if (wc_CmacFinal(&cmac, tag, &tagSz) != 0) - return -11604; + return -12004; if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0) - return -11605; + return -12005; XMEMSET(tag, 0, sizeof(tag)); tagSz = sizeof(tag); if (wc_AesCmacGenerate(tag, &tagSz, tc->m, tc->mSz, tc->k, tc->kSz) != 0) - return -11606; + return -12006; if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0) - return -11607; + return -12007; if (wc_AesCmacVerify(tc->t, tc->tSz, tc->m, tc->mSz, tc->k, tc->kSz) != 0) - return -11608; + return -12008; } return 0; @@ -25637,7 +25637,7 @@ static int compress_test(void) c = (byte *)XMALLOC(cSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); d = (byte *)XMALLOC(dSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (c == NULL || d == NULL) { - ERROR_OUT(-11700, exit); + ERROR_OUT(-12100, exit); } /* follow calloc and initialize to 0 */ @@ -25645,16 +25645,16 @@ static int compress_test(void) XMEMSET(d, 0, dSz); if ((ret = wc_Compress(c, cSz, sample_text, dSz, 0)) < 0) { - ERROR_OUT(-11701, exit); + ERROR_OUT(-12101, exit); } cSz = (word32)ret; if ((ret = wc_DeCompress(d, dSz, c, cSz)) != (int)dSz) { - ERROR_OUT(-11702, exit); + ERROR_OUT(-12102, exit); } if (XMEMCMP(d, sample_text, dSz) != 0) { - ERROR_OUT(-11703, exit); + ERROR_OUT(-12103, exit); } /* GZIP tests */ @@ -25664,17 +25664,17 @@ static int compress_test(void) ret = wc_Compress_ex(c, cSz, sample_text, dSz, 0, LIBZ_WINBITS_GZIP); if (ret < 0) { - ERROR_OUT(-11704, exit); + ERROR_OUT(-12104, exit); } cSz = (word32)ret; ret = wc_DeCompress_ex(d, dSz, c, cSz, LIBZ_WINBITS_GZIP); if (ret < 0) { - ERROR_OUT(-11705, exit); + ERROR_OUT(-12105, exit); } if (XMEMCMP(d, sample_text, dSz) != 0) { - ERROR_OUT(-11706, exit); + ERROR_OUT(-12106, exit); } /* Try with gzip generated output */ @@ -25682,12 +25682,12 @@ static int compress_test(void) ret = wc_DeCompress_ex(d, dSz, sample_text_gz, sizeof(sample_text_gz), LIBZ_WINBITS_GZIP); if (ret < 0) { - ERROR_OUT(-11707, exit); + ERROR_OUT(-12107, exit); } dSz = (word32)ret; if (XMEMCMP(d, sample_text, dSz) != 0) { - ERROR_OUT(-11708, exit); + ERROR_OUT(-12108, exit); } ret = 0; /* success */ @@ -25773,7 +25773,7 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_1024 if (*rsaClientCertBufSz < (word32)sizeof_client_cert_der_1024) - return -11709; + return -12110; XMEMCPY(rsaClientCertBuf, client_cert_der_1024, sizeof_client_cert_der_1024); @@ -25781,7 +25781,7 @@ static int pkcs7_load_certs_keys( if (rsaServerCertBuf != NULL) { if (*rsaServerCertBufSz < (word32)sizeof_server_cert_der_1024) - return -11710; + return -12111; XMEMCPY(rsaServerCertBuf, server_cert_der_1024, sizeof_server_cert_der_1024); @@ -25790,14 +25790,14 @@ static int pkcs7_load_certs_keys( if (rsaCaCertBuf != NULL) { if (*rsaCaCertBufSz < (word32)sizeof_ca_cert_der_1024) - return -11711; + return -12112; XMEMCPY(rsaCaCertBuf, ca_cert_der_1024, sizeof_ca_cert_der_1024); *rsaCaCertBufSz = sizeof_ca_cert_der_1024; } #elif defined(USE_CERT_BUFFERS_2048) if (*rsaClientCertBufSz < (word32)sizeof_client_cert_der_2048) - return -11712; + return -12113; XMEMCPY(rsaClientCertBuf, client_cert_der_2048, sizeof_client_cert_der_2048); @@ -25805,7 +25805,7 @@ static int pkcs7_load_certs_keys( if (rsaServerCertBuf != NULL) { if (*rsaServerCertBufSz < (word32)sizeof_server_cert_der_2048) - return -11713; + return -12114; XMEMCPY(rsaServerCertBuf, server_cert_der_2048, sizeof_server_cert_der_2048); @@ -25814,7 +25814,7 @@ static int pkcs7_load_certs_keys( if (rsaCaCertBuf != NULL) { if (*rsaCaCertBufSz < (word32)sizeof_ca_cert_der_2048) - return -11714; + return -12115; XMEMCPY(rsaCaCertBuf, ca_cert_der_2048, sizeof_ca_cert_der_2048); *rsaCaCertBufSz = sizeof_ca_cert_der_2048; @@ -25822,7 +25822,7 @@ static int pkcs7_load_certs_keys( #else certFile = XFOPEN(clientCert, "rb"); if (!certFile) - return -11715; + return -12116; *rsaClientCertBufSz = (word32)XFREAD(rsaClientCertBuf, 1, *rsaClientCertBufSz, certFile); @@ -25831,7 +25831,7 @@ static int pkcs7_load_certs_keys( if (rsaServerCertBuf != NULL) { certFile = XFOPEN(rsaServerCertDerFile, "rb"); if (!certFile) - return -11716; + return -12117; *rsaServerCertBufSz = (word32)XFREAD(rsaServerCertBuf, 1, *rsaServerCertBufSz, certFile); @@ -25841,7 +25841,7 @@ static int pkcs7_load_certs_keys( if (rsaCaCertBuf != NULL) { certFile = XFOPEN(rsaCaCertDerFile, "rb"); if (!certFile) - return -11717; + return -12118; *rsaCaCertBufSz = (word32)XFREAD(rsaCaCertBuf, 1, *rsaCaCertBufSz, certFile); @@ -25851,7 +25851,7 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_1024 if (*rsaClientPrivKeyBufSz < (word32)sizeof_client_key_der_1024) - return -11718; + return -12119; XMEMCPY(rsaClientPrivKeyBuf, client_key_der_1024, sizeof_client_key_der_1024); @@ -25859,7 +25859,7 @@ static int pkcs7_load_certs_keys( if (rsaServerPrivKeyBuf != NULL) { if (*rsaServerPrivKeyBufSz < (word32)sizeof_server_key_der_1024) - return -11719; + return -12120; XMEMCPY(rsaServerPrivKeyBuf, server_key_der_1024, sizeof_server_key_der_1024); @@ -25868,14 +25868,14 @@ static int pkcs7_load_certs_keys( if (rsaCaPrivKeyBuf != NULL) { if (*rsaCaPrivKeyBufSz < (word32)sizeof_ca_key_der_1024) - return -11720; + return -12121; XMEMCPY(rsaCaPrivKeyBuf, ca_key_der_1024, sizeof_ca_key_der_1024); *rsaCaPrivKeyBufSz = sizeof_ca_key_der_1024; } #elif defined(USE_CERT_BUFFERS_2048) if (*rsaClientPrivKeyBufSz < (word32)sizeof_client_key_der_2048) - return -11721; + return -12122; XMEMCPY(rsaClientPrivKeyBuf, client_key_der_2048, sizeof_client_key_der_2048); @@ -25883,7 +25883,7 @@ static int pkcs7_load_certs_keys( if (rsaServerPrivKeyBuf != NULL) { if (*rsaServerPrivKeyBufSz < (word32)sizeof_server_key_der_2048) - return -11722; + return -12123; XMEMCPY(rsaServerPrivKeyBuf, server_key_der_2048, sizeof_server_key_der_2048); @@ -25892,7 +25892,7 @@ static int pkcs7_load_certs_keys( if (rsaCaPrivKeyBuf != NULL) { if (*rsaCaPrivKeyBufSz < (word32)sizeof_ca_key_der_2048) - return -11723; + return -12124; XMEMCPY(rsaCaPrivKeyBuf, ca_key_der_2048, sizeof_ca_key_der_2048); *rsaCaPrivKeyBufSz = sizeof_ca_key_der_2048; @@ -25900,7 +25900,7 @@ static int pkcs7_load_certs_keys( #else keyFile = XFOPEN(clientKey, "rb"); if (!keyFile) - return -11724; + return -12125; *rsaClientPrivKeyBufSz = (word32)XFREAD(rsaClientPrivKeyBuf, 1, *rsaClientPrivKeyBufSz, keyFile); @@ -25909,7 +25909,7 @@ static int pkcs7_load_certs_keys( if (rsaServerPrivKeyBuf != NULL) { keyFile = XFOPEN(rsaServerKeyDerFile, "rb"); if (!keyFile) - return -11725; + return -12126; *rsaServerPrivKeyBufSz = (word32)XFREAD(rsaServerPrivKeyBuf, 1, *rsaServerPrivKeyBufSz, keyFile); @@ -25919,7 +25919,7 @@ static int pkcs7_load_certs_keys( if (rsaCaPrivKeyBuf != NULL) { keyFile = XFOPEN(rsaCaKeyFile, "rb"); if (!keyFile) - return -11726; + return -12127; *rsaCaPrivKeyBufSz = (word32)XFREAD(rsaCaPrivKeyBuf, 1, *rsaCaPrivKeyBufSz, keyFile); @@ -25934,14 +25934,14 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_256 if (*eccClientCertBufSz < (word32)sizeof_cliecc_cert_der_256) - return -11727; + return -12128; XMEMCPY(eccClientCertBuf, cliecc_cert_der_256, sizeof_cliecc_cert_der_256); *eccClientCertBufSz = sizeof_cliecc_cert_der_256; #else certFile = XFOPEN(eccClientCert, "rb"); if (!certFile) - return -11728; + return -12129; *eccClientCertBufSz = (word32)XFREAD(eccClientCertBuf, 1, *eccClientCertBufSz, certFile); @@ -25950,14 +25950,14 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_256 if (*eccClientPrivKeyBufSz < (word32)sizeof_ecc_clikey_der_256) - return -11729; + return -12130; XMEMCPY(eccClientPrivKeyBuf, ecc_clikey_der_256, sizeof_ecc_clikey_der_256); *eccClientPrivKeyBufSz = sizeof_ecc_clikey_der_256; #else keyFile = XFOPEN(eccClientKey, "rb"); if (!keyFile) - return -11730; + return -12131; *eccClientPrivKeyBufSz = (word32)XFREAD(eccClientPrivKeyBuf, 1, *eccClientPrivKeyBufSz, keyFile); @@ -26056,7 +26056,7 @@ static int myOriEncryptCb(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* oriType, /* make sure buffers are large enough */ if ((*oriValueSz < (2 + cekSz)) || (*oriTypeSz < sizeof(oriType))) - return -11731; + return -12140; /* our simple encryption algorithm will be take the bitwise complement */ oriValue[0] = 0x04; /*ASN OCTET STRING */ @@ -26091,14 +26091,14 @@ static int myOriDecryptCb(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz, /* make sure oriType matches what we expect */ if (oriTypeSz != sizeof(asnDataOid)) - return -11732; + return -12150; if (XMEMCMP(oriType, asnDataOid, sizeof(asnDataOid)) != 0) - return -11733; + return -12151; /* make sure decrypted buffer is large enough */ if (*decryptedKeySz < oriValueSz) - return -11734; + return -12152; /* decrypt encrypted CEK using simple bitwise complement, only for example */ @@ -26150,7 +26150,7 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz, /* test user context passed in */ if (usrCtx == NULL || *(int*)usrCtx != 1) { - return -11735; + return -12160; } /* if needing to find keyIdSz can call with NULL */ @@ -26159,7 +26159,7 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz, if (ret != LENGTH_ONLY_E) { printf("Unexpected error %d when getting keyIdSz\n", ret); printf("Possibly no KEY ID attribute set\n"); - return -11736; + return -12161; } else { XMEMSET(keyIdRaw, 0, sizeof(keyIdRaw)); @@ -26171,11 +26171,11 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz, if (keyIdSz < 3) { printf("keyIdSz is smaller than expected\n"); - return -11737; + return -12162; } if (keyIdSz > 2 + sizeof(int)) { printf("example case was only expecting a keyId of int size\n"); - return -11738; + return -12163; } /* keyIdRaw[0] OCTET TAG */ @@ -26407,7 +26407,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, enveloped = (byte *)XMALLOC(PKCS7_BUF_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); decoded = (byte *)XMALLOC(PKCS7_BUF_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if ((! enveloped) || (! decoded)) { - ERROR_OUT(-11761, out); + ERROR_OUT(-12170, out); } testSz = sizeof(testVectors) / sizeof(pkcs7EnvelopedVector); @@ -26419,7 +26419,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-11760, out); + ERROR_OUT(-12171, out); } #endif @@ -26432,7 +26432,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #endif ); if (pkcs7 == NULL) { - ERROR_OUT(-11739, out); + ERROR_OUT(-12172, out); } if (testVectors[i].secretKey != NULL) { @@ -26440,7 +26440,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11740, out); + ERROR_OUT(-12173, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -26459,7 +26459,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11741, out); + ERROR_OUT(-12174, out); } /* set key, for decryption */ @@ -26468,7 +26468,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11742, out); + ERROR_OUT(-12175, out); } } else if (testVectors[i].password != NULL) { @@ -26477,7 +26477,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11743, out); + ERROR_OUT(-12176, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -26496,7 +26496,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11744, out); + ERROR_OUT(-12177, out); } /* set password, for decryption */ @@ -26505,7 +26505,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11745, out); + ERROR_OUT(-12178, out); } #endif /* NO_PWDBASED */ @@ -26514,7 +26514,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11746, out); + ERROR_OUT(-12179, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -26527,7 +26527,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11747, out); + ERROR_OUT(-12180, out); } /* set decrypt callback for decryption */ @@ -26535,7 +26535,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11748, out); + ERROR_OUT(-12181, out); } } else { @@ -26543,14 +26543,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11749, out); + ERROR_OUT(-12182, out); } ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert, (word32)testVectors[i].certSz); if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11750, out); + ERROR_OUT(-12183, out); } pkcs7->keyWrapOID = testVectors[i].keyWrapOID; @@ -26570,7 +26570,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11751, out); + ERROR_OUT(-12184, out); } } else if (testVectors[i].ktriOptions & CMS_ISSUER_AND_SERIAL_NUMBER) { @@ -26579,7 +26579,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, CMS_ISSUER_AND_SERIAL_NUMBER); if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11752, out); + ERROR_OUT(-12185, out); } } } @@ -26592,7 +26592,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, PKCS7_BUF_SIZE); if (envelopedSz <= 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11753, out); + ERROR_OUT(-12186, out); } /* decode envelopedData */ @@ -26600,13 +26600,13 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, decoded, PKCS7_BUF_SIZE); if (decodedSz <= 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11754, out); + ERROR_OUT(-12187, out); } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0){ wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11755, out); + ERROR_OUT(-12188, out); } #ifndef NO_PKCS7_STREAM @@ -26617,14 +26617,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, decoded, PKCS7_BUF_SIZE); if (decodedSz <= 0 && decodedSz != WC_PKCS7_WANT_READ_E) { printf("unexpected error %d\n", decodedSz); - ERROR_OUT(-11756, out); + ERROR_OUT(-12189, out); } } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { printf("stream read compare failed\n"); wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11757, out); + ERROR_OUT(-12190, out); } } #endif @@ -26633,14 +26633,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11758, out); + ERROR_OUT(-12191, out); } ret = (int)XFWRITE(enveloped, 1, envelopedSz, pkcs7File); XFCLOSE(pkcs7File); if (ret != envelopedSz) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11759, out); + ERROR_OUT(-12192, out); } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -26689,12 +26689,12 @@ static int pkcs7enveloped_test(void) /* read client RSA cert and key in DER format */ rsaCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaCert == NULL) - return -11800; + return -12200; rsaPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaPrivKey == NULL) { XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -11801; + return -12201; } rsaCertSz = FOURK_BUF; @@ -26709,7 +26709,7 @@ static int pkcs7enveloped_test(void) XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -11802; + return -12202; } eccPrivKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -26719,7 +26719,7 @@ static int pkcs7enveloped_test(void) XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -11803; + return -12203; } eccCertSz = FOURK_BUF; @@ -26739,7 +26739,7 @@ static int pkcs7enveloped_test(void) XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -11804; + return -12204; } ret = pkcs7enveloped_run_vectors(rsaCert, (word32)rsaCertSz, @@ -27039,7 +27039,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, enveloped = (byte *)XMALLOC(PKCS7_BUF_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); decoded = (byte *)XMALLOC(PKCS7_BUF_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if ((! enveloped) || (! decoded)) { - ERROR_OUT(-11804, out); + ERROR_OUT(-12210, out); } testSz = sizeof(testVectors) / sizeof(pkcs7AuthEnvelopedVector); @@ -27053,7 +27053,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-11805, out); + ERROR_OUT(-12211, out); } senderNonce[0] = 0x04; @@ -27062,7 +27062,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ); if (ret != 0) { wc_FreeRng(&rng); - ERROR_OUT(-11806, out); + ERROR_OUT(-12212, out); } } @@ -27075,7 +27075,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #endif ); if (pkcs7 == NULL) { - ERROR_OUT(-11807, out); + ERROR_OUT(-12213, out); } if (testVectors[i].secretKey != NULL) { @@ -27083,7 +27083,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11808, out); + ERROR_OUT(-12214, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -27106,7 +27106,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11809, out); + ERROR_OUT(-12215, out); } /* set key, for decryption */ @@ -27115,7 +27115,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11810, out); + ERROR_OUT(-12216, out); } } else if (testVectors[i].password != NULL) { @@ -27124,7 +27124,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11811, out); + ERROR_OUT(-12217, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -27147,7 +27147,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11812, out); + ERROR_OUT(-12218, out); } /* set password, for decryption */ @@ -27156,7 +27156,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11813, out); + ERROR_OUT(-12219, out); } #endif /* NO_PWDBASED */ @@ -27165,7 +27165,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - ERROR_OUT(-11814, out); + ERROR_OUT(-12220, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -27182,7 +27182,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11815, out); + ERROR_OUT(-12221, out); } /* set decrypt callback for decryption */ @@ -27190,7 +27190,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11816, out); + ERROR_OUT(-12222, out); } } else { @@ -27200,7 +27200,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, (word32)testVectors[i].certSz); if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11817, out); + ERROR_OUT(-12223, out); } pkcs7->keyWrapOID = testVectors[i].keyWrapOID; @@ -27224,7 +27224,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11818, out); + ERROR_OUT(-12224, out); } } else if (testVectors[i].ktriOptions & CMS_ISSUER_AND_SERIAL_NUMBER) { @@ -27233,7 +27233,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, CMS_ISSUER_AND_SERIAL_NUMBER); if (ret != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11819, out); + ERROR_OUT(-12225, out); } } } @@ -27247,7 +27247,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, PKCS7_BUF_SIZE); if (envelopedSz <= 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11820, out); + ERROR_OUT(-12226, out); } #ifndef NO_PKCS7_STREAM { /* test reading byte by byte */ @@ -27257,14 +27257,14 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, enveloped + z, 1, decoded, PKCS7_BUF_SIZE); if (decodedSz <= 0 && decodedSz != WC_PKCS7_WANT_READ_E) { printf("unexpected error %d\n", decodedSz); - ERROR_OUT(-11821, out); + ERROR_OUT(-12227, out); } } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { printf("stream read compare failed\n"); wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11822, out); + ERROR_OUT(-12228, out); } } #endif @@ -27274,13 +27274,13 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, PKCS7_BUF_SIZE); if (decodedSz <= 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11823, out); + ERROR_OUT(-12229, out); } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0){ wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11824, out); + ERROR_OUT(-12230, out); } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -27288,14 +27288,14 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11825, out); + ERROR_OUT(-12231, out); } ret = (int)XFWRITE(enveloped, 1, envelopedSz, pkcs7File); XFCLOSE(pkcs7File); if (ret != envelopedSz) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-11826, out); + ERROR_OUT(-12232, out); } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -27348,12 +27348,12 @@ static int pkcs7authenveloped_test(void) /* read client RSA cert and key in DER format */ rsaCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaCert == NULL) - return -11900; + return -12300; rsaPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaPrivKey == NULL) { XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -11901; + return -12301; } rsaCertSz = FOURK_BUF; @@ -27368,7 +27368,7 @@ static int pkcs7authenveloped_test(void) XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -11902; + return -12302; } eccPrivKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -27378,7 +27378,7 @@ static int pkcs7authenveloped_test(void) XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -11903; + return -12303; } eccCertSz = FOURK_BUF; @@ -27398,7 +27398,7 @@ static int pkcs7authenveloped_test(void) XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -11904; + return -12304; } #ifndef WOLFSSL_LINUXKM @@ -27445,15 +27445,15 @@ static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId, /* test case sanity checks */ if (keyIdSz != 1) { - return -11905; + return -12310; } if (keyId[0] != 0x00) { - return -11906; + return -12311; } if (type != (int)PKCS7_KEKRI) { - return -11907; + return -12312; } switch (keyWrapAlgo) { @@ -27537,7 +27537,7 @@ static int envelopedData_encrypt(byte* in, word32 inSz, byte* out, pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); if (pkcs7 == NULL) - return -11908; + return -12330; pkcs7->content = in; pkcs7->contentSz = inSz; @@ -27553,7 +27553,7 @@ static int envelopedData_encrypt(byte* in, word32 inSz, byte* out, if (ret < 0) { printf("wc_PKCS7_AddRecipient_KEKRI() failed, ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -11909; + return -12331; } /* encode envelopedData, returns size */ @@ -27561,7 +27561,7 @@ static int envelopedData_encrypt(byte* in, word32 inSz, byte* out, if (ret <= 0) { printf("wc_PKCS7_EncodeEnvelopedData() failed, ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -11910; + return -12332; } @@ -27623,19 +27623,19 @@ static int generateBundle(byte* out, word32 *outSz, const byte* encryptKey, /* init PKCS7 */ pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); if (pkcs7 == NULL) - return -11911; + return -12340; ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz); if (ret != 0) { printf("ERROR: wc_PKCS7_InitWithCert() failed, ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -11912; + return -12341; } ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -11913; + return -12342; } /* encode Signed Encrypted FirmwarePkgData */ @@ -27655,7 +27655,7 @@ static int generateBundle(byte* out, word32 *outSz, const byte* encryptKey, printf("ERROR: wc_PKCS7_EncodeSignedEncryptedFPD() failed, " "ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -11914; + return -12343; } else { *outSz = ret; @@ -27783,19 +27783,19 @@ static int pkcs7callback_test(byte* cert, word32 certSz, byte* key, word32 keySz byte *derBuf = (byte *)XMALLOC(FOURK_BUF, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (! derBuf) - ERROR_OUT(-11915, out); + ERROR_OUT(-12360, out); /* Doing default generation and verify */ derSz = FOURK_BUF; ret = generateBundle(derBuf, &derSz, p7DefKey, sizeof(p7DefKey), 0, cert, certSz, key, keySz); if (ret <= 0) { - ERROR_OUT(-11916, out); + ERROR_OUT(-12361, out); } ret = verifyBundle(derBuf, derSz, 0); if (ret != 0) { - ERROR_OUT(-11917, out); + ERROR_OUT(-12362, out); } /* test choosing other key with keyID */ @@ -27803,12 +27803,12 @@ static int pkcs7callback_test(byte* cert, word32 certSz, byte* key, word32 keySz ret = generateBundle(derBuf, &derSz, p7AltKey, sizeof(p7AltKey), 1, cert, certSz, key, keySz); if (ret <= 0) { - ERROR_OUT(-11918, out); + ERROR_OUT(-12363, out); } ret = verifyBundle(derBuf, derSz, 1); if (ret != 0) { - ERROR_OUT(-11919, out); + ERROR_OUT(-12364, out); } /* test fail case with wrong keyID */ @@ -27816,12 +27816,12 @@ static int pkcs7callback_test(byte* cert, word32 certSz, byte* key, word32 keySz ret = generateBundle(derBuf, &derSz, p7DefKey, sizeof(p7DefKey), 1, cert, certSz, key, keySz); if (ret <= 0) { - ERROR_OUT(-11920, out); + ERROR_OUT(-12365, out); } ret = verifyBundle(derBuf, derSz, 1); if (ret == 0) { - ERROR_OUT(-11921, out); + ERROR_OUT(-12366, out); } ret = 0; @@ -27991,7 +27991,7 @@ static int pkcs7encrypted_test(void) for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) { - ERROR_OUT(-12000, out); + ERROR_OUT(-12400, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -28008,7 +28008,7 @@ static int pkcs7encrypted_test(void) PKCS7_BUF_SIZE); if (encryptedSz <= 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12001, out); + ERROR_OUT(-12401, out); } /* decode encryptedData */ @@ -28020,14 +28020,14 @@ static int pkcs7encrypted_test(void) decoded, PKCS7_BUF_SIZE); if (decodedSz <= 0 && decodedSz != WC_PKCS7_WANT_READ_E) { printf("unexpected error %d\n", decodedSz); - ERROR_OUT(-12002, out); + ERROR_OUT(-12402, out); } } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { printf("stream read failed\n"); wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12003, out); + ERROR_OUT(-12403, out); } } #endif @@ -28035,13 +28035,13 @@ static int pkcs7encrypted_test(void) decoded, PKCS7_BUF_SIZE); if (decodedSz <= 0){ wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12004, out); + ERROR_OUT(-12404, out); } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12005, out); + ERROR_OUT(-12405, out); } /* verify decoded unprotected attributes */ @@ -28059,14 +28059,14 @@ static int pkcs7encrypted_test(void) if (XMEMCMP(decodedAttrib->oid, expectedAttrib->oid, decodedAttrib->oidSz) != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12006, out); + ERROR_OUT(-12406, out); } /* verify value */ if (XMEMCMP(decodedAttrib->value, expectedAttrib->value, decodedAttrib->valueSz) != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12007, out); + ERROR_OUT(-12407, out); } decodedAttrib = decodedAttrib->next; @@ -28079,7 +28079,7 @@ static int pkcs7encrypted_test(void) pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12008, out); + ERROR_OUT(-12408, out); } ret = (int)XFWRITE(encrypted, encryptedSz, 1, pkcs7File); @@ -28158,7 +28158,7 @@ static int pkcs7compressed_test(void) for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) { - ERROR_OUT(-12100, out); + ERROR_OUT(-12500, out); } pkcs7->content = (byte*)testVectors[i].content; @@ -28170,7 +28170,7 @@ static int pkcs7compressed_test(void) PKCS7_BUF_SIZE); if (compressedSz <= 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12101, out); + ERROR_OUT(-12501, out); } /* decode compressedData */ @@ -28179,19 +28179,19 @@ static int pkcs7compressed_test(void) PKCS7_BUF_SIZE); if (decodedSz <= 0){ wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12102, out); + ERROR_OUT(-12502, out); } /* test decode result */ if (XMEMCMP(decoded, testVectors[i].content, testVectors[i].contentSz) != 0) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12103, out); + ERROR_OUT(-12503, out); } /* make sure content type is the same */ if (testVectors[i].contentOID != pkcs7->contentOID) { - ERROR_OUT(-12104, out); + ERROR_OUT(-12504, out); } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -28199,7 +28199,7 @@ static int pkcs7compressed_test(void) pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - ERROR_OUT(-12105, out); + ERROR_OUT(-12505, out); } ret = (int)XFWRITE(compressed, compressedSz, 1, pkcs7File); @@ -28481,14 +28481,14 @@ static int pkcs7signed_run_vectors( outSz = FOURK_BUF; out = (byte*)XMALLOC(outSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) - return -12106; + return -12510; XMEMSET(out, 0, outSz); ret = wc_PKCS7_PadData((byte*)data, sizeof(data), out, outSz, 16); if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -12107; + return -12511; } #ifndef HAVE_FIPS @@ -28498,13 +28498,13 @@ static int pkcs7signed_run_vectors( #endif if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -12108; + return -12512; } for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -12109; + return -12513; ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert, (word32)testVectors[i].certSz); @@ -28512,7 +28512,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12110; + return -12514; } /* load CA certificate, if present */ @@ -28522,7 +28522,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12111; + return -12515; } } @@ -28545,7 +28545,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12112; + return -12516; } } @@ -28556,7 +28556,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12113; + return -12517; } } @@ -28569,7 +28569,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12114; + return -12518; } } @@ -28592,7 +28592,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12115; + return -12519; } wc_ShaUpdate(&sha, pkcs7->publicKey, pkcs7->publicKeySz); wc_ShaFinal(&sha, digest); @@ -28602,7 +28602,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12116; + return -12520; } wc_Sha256Update(&sha, pkcs7->publicKey, pkcs7->publicKeySz); wc_Sha256Final(&sha, digest); @@ -28620,7 +28620,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12117; + return -12521; } } @@ -28628,7 +28628,7 @@ static int pkcs7signed_run_vectors( if (encodedSz < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12118; + return -12522; } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -28637,14 +28637,14 @@ static int pkcs7signed_run_vectors( if (!file) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12119; + return -12523; } ret = (int)XFWRITE(out, 1, encodedSz, file); XFCLOSE(file); if (ret != (int)encodedSz) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12120; + return -12524; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -28652,7 +28652,7 @@ static int pkcs7signed_run_vectors( pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -12121; + return -12525; wc_PKCS7_InitWithCert(pkcs7, NULL, 0); if (testVectors[i].detachedSignature == 1) { @@ -28665,23 +28665,23 @@ static int pkcs7signed_run_vectors( if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12122; + return -12526; } /* verify contentType extracted successfully for custom content types */ if (testVectors[i].contentTypeSz > 0) { if (pkcs7->contentTypeSz != testVectors[i].contentTypeSz) { - return -12123; + return -12527; } else if (XMEMCMP(pkcs7->contentType, testVectors[i].contentType, pkcs7->contentTypeSz) != 0) { - return -12124; + return -12528; } } if (pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12125; + return -12529; } { @@ -28700,13 +28700,13 @@ static int pkcs7signed_run_vectors( NULL, (word32*)&bufSz) != LENGTH_ONLY_E) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12126; + return -12530; } if (bufSz > (int)sizeof(buf)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12127; + return -12531; } bufSz = wc_PKCS7_GetAttributeValue(pkcs7, oidPt, oidSz, @@ -28715,7 +28715,7 @@ static int pkcs7signed_run_vectors( (testVectors[i].signedAttribs == NULL && bufSz > 0)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12128; + return -12532; } } @@ -28724,7 +28724,7 @@ static int pkcs7signed_run_vectors( if (!file) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12129; + return -12533; } ret = (int)XFWRITE(pkcs7->singleCert, 1, pkcs7->singleCertSz, file); XFCLOSE(file); @@ -28981,14 +28981,14 @@ static int pkcs7signed_run_SingleShotVectors( outSz = FOURK_BUF; out = (byte*)XMALLOC(outSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) - return -12130; + return -12540; XMEMSET(out, 0, outSz); ret = wc_PKCS7_PadData((byte*)data, sizeof(data), out, outSz, 16); if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -12131; + return -12541; } #ifndef HAVE_FIPS @@ -28998,13 +28998,13 @@ static int pkcs7signed_run_SingleShotVectors( #endif if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -12132; + return -12542; } for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -12133; + return -12543; ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert, (word32)testVectors[i].certSz); @@ -29012,7 +29012,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12134; + return -12544; } /* load CA certificate, if present */ @@ -29022,7 +29022,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12135; + return -12545; } } @@ -29033,7 +29033,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12136; + return -12546; } } @@ -29050,7 +29050,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12137; + return -12547; } #ifndef NO_PKCS7_ENCRYPTED_DATA @@ -29071,7 +29071,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz <= 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12138; + return -12548; } #endif @@ -29089,7 +29089,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz <= 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12139; + return -12549; } #ifndef NO_PKCS7_ENCRYPTED_DATA @@ -29109,7 +29109,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz <= 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12140; + return -12550; } #endif /* NO_PKCS7_ENCRYPTED_DATA */ @@ -29119,7 +29119,7 @@ static int pkcs7signed_run_SingleShotVectors( /* unsupported SignedData single-shot combination */ XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12141; + return -12551; } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -29128,14 +29128,14 @@ static int pkcs7signed_run_SingleShotVectors( if (!file) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12142; + return -12552; } ret = (int)XFWRITE(out, 1, encodedSz, file); XFCLOSE(file); if (ret != (int)encodedSz) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12143; + return -12553; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -29143,14 +29143,14 @@ static int pkcs7signed_run_SingleShotVectors( pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -12144; + return -12554; wc_PKCS7_InitWithCert(pkcs7, NULL, 0); ret = wc_PKCS7_VerifySignedData(pkcs7, out, outSz); if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12145; + return -12555; } #ifndef NO_PKCS7_STREAM { @@ -29161,7 +29161,7 @@ static int pkcs7signed_run_SingleShotVectors( XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); printf("unexpected error %d\n", ret); - return -12146; + return -12556; } } } @@ -29170,7 +29170,7 @@ static int pkcs7signed_run_SingleShotVectors( if (pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12147; + return -12557; } if (testVectors[i].encCompFlag == 0) { @@ -29180,7 +29180,7 @@ static int pkcs7signed_run_SingleShotVectors( pkcs7->contentSz)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12148; + return -12558; } } @@ -29196,7 +29196,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12149; + return -12559; } /* compare decrypted to expected */ @@ -29204,7 +29204,7 @@ static int pkcs7signed_run_SingleShotVectors( XMEMCMP(out, testVectors[i].content, ret)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12150; + return -12560; } } #endif @@ -29217,7 +29217,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12151; + return -12561; } /* compare decompressed to expected */ @@ -29225,7 +29225,7 @@ static int pkcs7signed_run_SingleShotVectors( XMEMCMP(out, testVectors[i].content, ret)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12152; + return -12562; } } #ifndef NO_PKCS7_ENCRYPTED_DATA @@ -29240,7 +29240,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encryptedTmp == NULL) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12153; + return -12563; } XMEMSET(encryptedTmp, 0, encryptedTmpSz); @@ -29257,7 +29257,7 @@ static int pkcs7signed_run_SingleShotVectors( XFREE(encryptedTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12154; + return -12564; } /* decompress inner compressedData */ @@ -29267,7 +29267,7 @@ static int pkcs7signed_run_SingleShotVectors( XFREE(encryptedTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12155; + return -12565; } XFREE(encryptedTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -29277,7 +29277,7 @@ static int pkcs7signed_run_SingleShotVectors( XMEMCMP(out, testVectors[i].content, ret)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -12156; + return -12566; } } #endif /* NO_PKCS7_ENCRYPTED_DATA */ @@ -29341,12 +29341,12 @@ static int pkcs7signed_test(void) rsaClientCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaClientCertBuf == NULL) - ret = -12200; + ret = -12600; rsaClientPrivKeyBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaClientPrivKeyBuf == NULL) { - ret = -12201; + ret = -12601; } rsaClientCertBufSz = FOURK_BUF; @@ -29356,12 +29356,12 @@ static int pkcs7signed_test(void) rsaServerCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaServerCertBuf == NULL) - ret = -12202; + ret = -12602; rsaServerPrivKeyBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaServerPrivKeyBuf == NULL) { - ret = -12203; + ret = -12603; } rsaServerCertBufSz = FOURK_BUF; @@ -29371,12 +29371,12 @@ static int pkcs7signed_test(void) rsaCaCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaCaCertBuf == NULL) - ret = -12204; + ret = -12604; rsaCaPrivKeyBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaCaPrivKeyBuf == NULL) { - ret = -12205; + ret = -12605; } rsaCaCertBufSz = FOURK_BUF; @@ -29388,13 +29388,13 @@ static int pkcs7signed_test(void) eccClientCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && eccClientCertBuf == NULL) { - ret = -12206; + ret = -12606; } eccClientPrivKeyBuf =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && eccClientPrivKeyBuf == NULL) { - ret = -12207; + ret = -12607; } eccClientCertBufSz = FOURK_BUF; @@ -29411,7 +29411,7 @@ static int pkcs7signed_test(void) eccClientCertBuf, &eccClientCertBufSz, eccClientPrivKeyBuf, &eccClientPrivKeyBufSz); if (ret < 0) { - ret = -12208; + ret = -12608; } if (ret >= 0) @@ -29460,9 +29460,8 @@ static int pkcs7signed_test(void) /* Need a static build to have access to symbols. */ /* Maximum number of bytes in a number to test. */ -#define MP_MAX_TEST_BYTE_LEN 16 +#define MP_MAX_TEST_BYTE_LEN 32 -#if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) static int randNum(mp_int* n, int len, WC_RNG* rng, void* heap) { byte d[MP_MAX_TEST_BYTE_LEN]; @@ -29481,9 +29480,2336 @@ static int randNum(mp_int* n, int len, WC_RNG* rng, void* heap) return 0; } + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(USE_FAST_MATH) +static int mp_test_div_3(mp_int* a, mp_int* r, WC_RNG* rng) +{ + int i, j; + mp_digit rem; + mp_digit rem2; + + for (i = 0; i < 10; i++) { + for (j = 1; j < 10; j++) { + if (randNum(a, j, rng, NULL) != 0) + return -12620; + if (mp_div_3(a, r, &rem) != 0) + return -12621; + if (mp_mul_d(r, 3, r) != 0) + return -12622; + if (mp_add_d(r, rem, r) != 0) + return -12623; + if (mp_cmp(r, a) != MP_EQ) + return -12624; + } + } + + if (mp_div_3(a, r, &rem) != 0) + return -12625; + if (mp_div_3(a, a, NULL) != 0) + return -12626; + if (mp_cmp(r, a) != MP_EQ) + return -12627; + +#if defined(WOLFSSL_SP_MATH_ALL) + if (mp_div_d(a, 10, r, &rem) != 0) + return -12628; + if (mp_div_d(a, 10, a, NULL) != 0) + return -12629; + if (mp_cmp(r, a) != MP_EQ) + return -12630; + + if (mp_div_d(a, 12, r, &rem) != 0) + return -12631; + if (mp_div_d(a, 12, a, NULL) != 0) + return -12632; + if (mp_cmp(r, a) != MP_EQ) + return -12633; + + if (mp_div_d(a, (mp_digit)1 << (DIGIT_BIT / 2), r, &rem) != 0) + return -12634; + if (mp_div_d(a, (mp_digit)1 << (DIGIT_BIT / 2), NULL, &rem2) != 0) + return -12635; + if (mp_div_d(a, (mp_digit)1 << (DIGIT_BIT / 2), a, NULL) != 0) + return -12636; + if (mp_cmp(r, a) != MP_EQ) + return -12637; + if (rem != rem2) + return -12638; +#else + (void)rem2; #endif -static int mp_test(void) + return 0; +} +#endif /* WOLFSSL_SP_MATH || !USE_FAST_MATH */ + +#if defined(WOLFSSL_SP_MATH_ALL) || (!defined WOLFSSL_SP_MATH && \ + (defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY))) +static int mp_test_radix_10(mp_int* a, mp_int* r, WC_RNG* rng) +{ + int ret; + int i, j; + int size; + char str[30]; + static const char* badStr1 = "A"; + static const char* badStr2 = "a"; + static const char* badStr3 = " "; + static const char* zeros = "000"; + static const char* empty = ""; + + for (i = 0; i < 10; i++) { + for (j = 2; j < 12; j++) { + if (randNum(a, j, rng, NULL) != 0) + return -12640; + if (mp_radix_size(a, MP_RADIX_DEC, &size) != MP_OKAY) + return -12641; + mp_toradix(a, str, MP_RADIX_DEC); + if ((int)XSTRLEN(str) != size - 1) + return -12642; + mp_read_radix(r, str, MP_RADIX_DEC); + if (mp_cmp(a, r) != MP_EQ) + return -12643; + } + } + + if (mp_read_radix(r, badStr1, MP_RADIX_DEC) != MP_VAL) + return -12644; + if (mp_read_radix(r, badStr2, MP_RADIX_DEC) != MP_VAL) + return -12645; + if (mp_read_radix(r, badStr3, MP_RADIX_DEC) != MP_VAL) + return -12646; + + if (mp_read_radix(r, zeros, MP_RADIX_DEC) != MP_OKAY) + return -12647; + if (!mp_iszero(r)) + return -12648; + mp_set(r, 1); + if (mp_read_radix(r, empty, MP_RADIX_DEC) != MP_OKAY) + return -12649; + if (!mp_iszero(r)) + return -12650; + + mp_zero(a); + ret = mp_radix_size(a, MP_RADIX_DEC, &size); + if (ret != 0) + return -12651; + if (size != 2) + return -12652; + ret = mp_toradix(a, str, MP_RADIX_DEC); + if (ret != 0) + return -12653; + if ((int)XSTRLEN(str) != size - 1) + return -12654; + ret = mp_read_radix(r, str, MP_RADIX_DEC); + if (ret != 0) + return -12655; + if (!mp_iszero(r)) + return -12656; + + return 0; +} +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) +static int mp_test_radix_16(mp_int* a, mp_int* r, WC_RNG* rng) +{ + int ret; + int i, j; + int size; + char str[30]; +#if defined(WOLFSSL_SP_MATH) || defined(USE_FAST_MATH) + static char longStr[2 * sizeof(a->dp) + 2]; +#endif + static const char* badStr1 = " "; + static const char* badStr2 = "}"; + static const char* empty = ""; + + for (i = 0; i < 10; i++) { + for (j = 2; j < 12; j++) { + if (randNum(a, j, rng, NULL) != 0) + return -12660; + mp_radix_size(a, MP_RADIX_HEX, &size); + mp_toradix(a, str, MP_RADIX_HEX); + if ((int)XSTRLEN(str) != size - 1) + return -12661; + mp_read_radix(r, str, MP_RADIX_HEX); + if (mp_cmp(a, r) != MP_EQ) + return -12662; + } + } + + if (mp_read_radix(r, badStr1, MP_RADIX_HEX) != MP_VAL) + return -12663; + if (mp_read_radix(r, badStr2, MP_RADIX_HEX) != MP_VAL) + return -12664; + + mp_set(r, 1); + if (mp_read_radix(r, empty, MP_RADIX_HEX) != MP_OKAY) + return -12665; + if (!mp_iszero(r)) + return -12666; + +#if defined(WOLFSSL_SP_MATH) || defined(USE_FAST_MATH) + /* Fixed MP data size - string can be too long. */ + longStr[0] = '8'; + XMEMSET(longStr+1, '0', sizeof(longStr) - 2); + longStr[sizeof(longStr)-1] = '\0'; + if (mp_read_radix(r, longStr, MP_RADIX_HEX) != MP_VAL) + return -12667; +#endif + + mp_zero(a); + ret = mp_radix_size(a, MP_RADIX_HEX, &size); + if (ret != 0) + return -12668; +#ifndef WC_DISABLE_RADIX_ZERO_PAD + if (size != 3) +#else + if (size != 2) +#endif + return -12669; + ret = mp_toradix(a, str, MP_RADIX_HEX); + if (ret != 0) + return -12670; + if ((int)XSTRLEN(str) != size - 1) + return -12671; + ret = mp_read_radix(r, str, MP_RADIX_HEX); + if (ret != 0) + return -12672; + if (!mp_iszero(r)) + return -12673; + +#ifdef WOLFSSL_SP_MATH + ret = mp_toradix(a, str, 8); + if (ret != MP_VAL) + return -12674; + ret = mp_radix_size(a, 8, &size); + if (ret != MP_VAL) + return -12675; +#endif + + return 0; +} +#endif + +static int mp_test_shift(mp_int* a, mp_int* r1, WC_RNG* rng) +{ + int i; + + if (randNum(a, 4, rng, NULL) != 0) + return -12680; + for (i = 0; i < 4; i++) { + mp_copy(r1, a); + if (mp_lshd(r1, i) != MP_OKAY) + return -12681; + mp_rshd(r1, i); + if (mp_cmp(a, r1) != MP_EQ) + return -12682; + } + for (i = 0; i < DIGIT_BIT+1; i++) { + if (mp_mul_2d(a, i, r1) != MP_OKAY) + return -12683; + mp_rshb(r1, i); + if (mp_cmp(a, r1) != MP_EQ) + return -12684; + } + + return 0; +} + +static int mp_test_add_sub_d(mp_int* a, mp_int* r1) +{ + int i, j; + + for (i = 0; i <= DIGIT_BIT * 2; i++) { + mp_zero(a); + mp_set_bit(a, i); + if (a->used != (i + DIGIT_BIT) / DIGIT_BIT) + return -12690; + for (j = 0; j < i && j < DIGIT_BIT; j++) { + mp_zero(r1); + mp_set_bit(r1, i); + if (mp_sub_d(r1, (mp_digit)1 << j, r1) != MP_OKAY) + return -12691; + if (mp_add_d(r1, (mp_digit)1 << j, r1) != MP_OKAY) + return -12692; + if (mp_cmp(a, r1) != MP_EQ) + return -12693; + } + } + + mp_zero(r1); + if (mp_add_d(r1, 1, r1) != MP_OKAY) + return -12694; + if (r1->used != 1) + return -12695; + if (mp_sub_d(r1, 1, r1) != MP_OKAY) + return -12696; + if (r1->used != 0) + return -12697; + +#ifdef WOLFSSL_SP_MATH + if (mp_set(r1, 1) != MP_OKAY) + return -12698; + if (mp_mul_2d(r1, SP_INT_MAX_BITS - 1, r1) != MP_OKAY) + return -12699; + if (mp_sub_d(r1, 1, r1) != MP_OKAY) + return -12700; + if (mp_mul_2d(r1, 1, r1) != MP_OKAY) + return -12701; + if (mp_add_d(r1, 1, r1) != MP_OKAY) + return -12702; + if (mp_add_d(r1, 1, r1) == MP_OKAY) + return -12703; +#endif + + return 0; +} + +static int mp_test_read_to_bin(mp_int* a) +{ + static const byte in[16] = { + 0x91, 0xa2, 0xb3, 0xc4, 0xd5, 0xe6, 0xf7, 0x08, + 0x93, 0xa4, 0xb4, 0xc5, 0xd6, 0xe7, 0xf8, 0x09 + }; + byte out[24]; + int i, j, k; + const byte* p; + int ret; + + for (i = 0; i < (int)sizeof(in); i++) { + p = in + sizeof(in) - i; + ret = mp_read_unsigned_bin(a, p, i); + if (ret != 0) + return -12710; + for (j = i; j < (int)sizeof(out); j++) { + XMEMSET(out, 0xff, sizeof(out)); + ret = mp_to_unsigned_bin_len(a, out, j); + if (ret != 0) + return -12711; + for (k = 0; k < j - i; k++) { + if (out[k] != 0) + return -12712; + } + for (; k < j; k++) { + if (out[k] != p[k - (j - i)]) + return -12713; + } + } + } + + ret = mp_read_unsigned_bin(a, NULL, 0); + if (ret != 0) + return -12714; + if (!mp_iszero(a)) + return -12715; + + return 0; +} + +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) +static int mp_test_set_int(mp_int* a) +{ +#if SP_ULONG_BITS == 64 + unsigned long n = 0xfedcba9876543210UL; + byte exp[8] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; + byte out[8] = { 0 }; +#elif SP_ULONG_BITS == 32 + unsigned long n = 0xfedcba98UL; + byte exp[4] = { 0xfe, 0xdc, 0xba, 0x98 }; + byte out[4] = { 0 }; +#elif SP_ULONG_BITS == 16 + unsigned long n = 0xfedc; + byte exp[2] = { 0xfe, 0xdc }; + byte out[2] = { 0 }; +#elif SP_ULONG_BITS == 8 + unsigned long n = 0xfe; + byte exp[1] = { 0xfe }; + byte out[1] = { 0 }; +#endif + int ret; + + ret = mp_set_int(a, n); + if (ret != 0) + return -12720; + + ret = mp_unsigned_bin_size(a); + if (ret != sizeof(exp)) + return -12721; + ret = mp_to_unsigned_bin(a, out); + if (ret != 0) + return -12722; + if (XMEMCMP(exp, out, sizeof(exp)) != 0) + return -12723; + + return 0; +} +#endif + +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) +static int mp_test_param(mp_int* a, mp_int* b, mp_int* r, WC_RNG* rng) +{ + byte buffer[16]; +#if defined(HAVE_ECC) || defined(WOLFSSL_SP_MATH_ALL) + char hexStr[] = "abcdef0123456789"; +#ifndef WOLFSSL_SP_INT_NEGATIVE + char negStr[] = "-1234"; +#endif +#endif +#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_KEY_GEN) || \ + defined(HAVE_COMP_KEY) + char decStr[] = "0987654321"; +#endif + int ret; +#ifdef WOLFSSL_SP_MATH_ALL + mp_digit rho; + int size; +#endif +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) + int result; +#endif +#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \ + (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN)) + mp_digit rd; +#endif + + (void)rng; + (void)r; + + ret = mp_init(NULL); + if (ret != MP_VAL) + return -12730; + +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) + ret = mp_init_multi(NULL, NULL, NULL, NULL, NULL, NULL); + if (ret != MP_OKAY) + return -12731; +#endif + + mp_free(NULL); + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || !defined(NO_DH) || defined(HAVE_ECC) + ret = mp_grow(NULL, 1); + if (ret != MP_VAL) + return -12732; +#ifdef WOLFSSL_SP_MATH + ret = mp_grow(a, SP_INT_DIGITS + 1); + if (ret != MP_MEM) + return -12733; +#endif +#endif + + mp_clear(NULL); + + ret = mp_abs(NULL, NULL); + if (ret != MP_VAL) + return -12734; + ret = mp_abs(a, NULL); + if (ret != MP_VAL) + return -12735; + ret = mp_abs(NULL, b); + if (ret != MP_VAL) + return -12736; + + ret = mp_unsigned_bin_size(NULL); + if (ret != 0) + return -12737; + + ret = mp_read_unsigned_bin(NULL, NULL, sizeof(buffer)); + if (ret != MP_VAL) + return -12738; + ret = mp_read_unsigned_bin(NULL, buffer, sizeof(buffer)); + if (ret != MP_VAL) + return -12739; + ret = mp_read_unsigned_bin(a, NULL, sizeof(buffer)); + if (ret != MP_VAL) + return -12740; + ret = mp_read_unsigned_bin(a, buffer, + (SP_INT_DIGITS - 1) * SP_WORD_SIZEOF + 1); + if (ret != MP_VAL) + return -12741; + +#if defined(HAVE_ECC) || defined(WOLFSSL_SP_MATH_ALL) + ret = mp_read_radix(NULL, NULL, 16); + if (ret != MP_VAL) + return -12742; + ret = mp_read_radix(a, NULL, 16); + if (ret != MP_VAL) + return -12743; + ret = mp_read_radix(NULL, hexStr, 16); + if (ret != MP_VAL) + return -12744; +#ifndef WOLFSSL_SP_INT_NEGATIVE + ret = mp_read_radix(a, negStr, 16); + if (ret != MP_VAL) + return -12745; +#ifdef WOLFSSL_SP_MATH_ALL + ret = mp_read_radix(a, negStr, 10); + if (ret != MP_VAL) + return -12746; +#endif /* WOLFSSL_SP_MATH_ALL */ +#endif /* WOLFSSL_SP_INT_NEGATIVE */ +#endif +#ifndef WOLFSSL_SP_MATH_ALL + /* Radix 10 only supported with ALL. */ + ret = mp_read_radix(a, decStr, 10); + if (ret != MP_VAL) + return -12747; +#endif + /* Radix 8 not supported SP_INT. */ + ret = mp_read_radix(a, "0123", 8); + if (ret != MP_VAL) + return -12748; + + ret = mp_count_bits(NULL); + if (ret != 0) + return -12749; + + ret = mp_is_bit_set(NULL, 0); + if (ret != 0) + return -12750; + + ret = mp_leading_bit(NULL); + if (ret != 0) + return -12751; + mp_zero(a); + ret = mp_leading_bit(a); + if (ret != 0) + return -12752; + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \ + !defined(NO_RSA) + ret = mp_set_bit(NULL, 1); + if (ret != MP_VAL) + return -12753; +#endif + +#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \ + !defined(WOLFSSL_RSA_VERIFY_ONLY) + ret = mp_to_unsigned_bin(NULL, NULL); + if (ret != MP_VAL) + return -12754; + ret = mp_to_unsigned_bin(a, NULL); + if (ret != MP_VAL) + return -12755; + ret = mp_to_unsigned_bin(NULL, buffer); + if (ret != MP_VAL) + return -12756; +#endif + + ret = mp_to_unsigned_bin_len(NULL, NULL, 1); + if (ret != MP_VAL) + return -12757; + ret = mp_to_unsigned_bin_len(a, NULL, 1); + if (ret != MP_VAL) + return -12758; + ret = mp_to_unsigned_bin_len(NULL, buffer, 1); + if (ret != MP_VAL) + return -12759; + +#ifdef WOLFSSL_SP_MATH_ALL + ret = mp_to_unsigned_bin_at_pos(0, NULL, NULL); + if (ret != MP_VAL) + return -12760; + ret = mp_to_unsigned_bin_at_pos(0, a, NULL); + if (ret != MP_VAL) + return -12761; + ret = mp_to_unsigned_bin_at_pos(0, NULL, buffer); + if (ret != MP_VAL) + return -12762; + ret = mp_to_unsigned_bin_at_pos(0, a, buffer); + if (ret != MP_OKAY) + return -12763; +#endif + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || (!defined(NO_DH) || defined(HAVE_ECC)) + ret = mp_copy(NULL, NULL); + if (ret != MP_VAL) + return -12764; + ret = mp_copy(a, NULL); + if (ret != MP_VAL) + return -12765; + ret = mp_copy(NULL, b); + if (ret != MP_VAL) + return -12766; +#endif + +#if defined(WOLFSSL_KEY_GEN) + ret = sp_2expt(NULL, 1); + if (ret != MP_VAL) + return -12767; +#endif + + ret = mp_set(NULL, 0); + if (ret != MP_VAL) + return -12768; + + ret = mp_cmp_d(NULL, 0); + if (ret != MP_LT) + return -12769; + + ret = mp_cmp(NULL, NULL); + if (ret != MP_EQ) + return -12770; + ret = mp_cmp(a, NULL); + if (ret != MP_GT) + return -12771; + ret = mp_cmp(NULL, b); + if (ret != MP_LT) + return -12772; + +#if !defined(NO_DH) || defined(HAVE_ECC) || !defined(WOLFSSL_RSA_VERIFY_ONLY) + mp_rshd(NULL, 1); +#endif + + mp_zero(NULL); + +#if !defined(NO_DH) || defined(HAVE_ECC) || defined(WC_RSA_BLINDING) || \ + !defined(WOLFSSL_RSA_VERIFY_ONLY) + ret = mp_lshd(NULL, 0); + if (ret != MP_VAL) + return -12773; + ret = mp_lshd(a, SP_INT_DIGITS + 1); + if (ret != MP_VAL) + return -12774; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) + ret = mp_div(NULL, NULL, a, b); + if (ret != MP_VAL) + return -12775; + ret = mp_div(a, NULL, a, b); + if (ret != MP_VAL) + return -12776; + ret = mp_div(NULL, b, a, b); + if (ret != MP_VAL) + return -12777; + ret = mp_div(a, b, NULL, NULL); + if (ret != MP_VAL) + return -12778; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + ret = mp_mod(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12779; + ret = mp_mod(a, NULL, NULL); + if (ret != MP_VAL) + return -12780; + ret = mp_mod(NULL, b, NULL); + if (ret != MP_VAL) + return -12781; + ret = mp_mod(NULL, NULL, r); + if (ret != MP_VAL) + return -12782; + ret = mp_mod(a, b, NULL); + if (ret != MP_VAL) + return -12783; + ret = mp_mod(a, NULL, r); + if (ret != MP_VAL) + return -12784; + ret = mp_mod(NULL, b, r); + if (ret != MP_VAL) + return -12785; +#endif + +#if !defined(NO_RSA) || defined(WOLFSSL_SP_MATH_ALL) + ret = mp_set_int(NULL, 0); + if (ret != MP_VAL) + return -12786; +#endif + +#if !defined(NO_RSA) || !defined(NO_DSA) || !defined(NO_DH) || \ + (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA) + ret = mp_exptmod_ex(NULL, NULL, 1, NULL, NULL); + if (ret != MP_VAL) + return 9950; + ret = mp_exptmod_ex(a, NULL, 1, NULL, NULL); + if (ret != MP_VAL) + return 9951; + ret = mp_exptmod_ex(NULL, a, 1, NULL, NULL); + if (ret != MP_VAL) + return 9952; + ret = mp_exptmod_ex(NULL, NULL, 1, a, NULL); + if (ret != MP_VAL) + return 9953; + ret = mp_exptmod_ex(NULL, NULL, 1, NULL, a); + if (ret != MP_VAL) + return 9954; + ret = mp_exptmod_ex(a, a, 1, a, NULL); + if (ret != MP_VAL) + return 9955; + ret = mp_exptmod_ex(a, a, 1, NULL, a); + if (ret != MP_VAL) + return 9956; + ret = mp_exptmod_ex(a, NULL, 1, a, a); + if (ret != MP_VAL) + return 9957; + ret = mp_exptmod_ex(NULL, a, 1, a, a); + if (ret != MP_VAL) + return 9958; + + ret = mp_exptmod_nct(NULL, NULL, NULL, NULL); + if (ret != MP_VAL) + return 9960; + ret = mp_exptmod_nct(a, NULL, NULL, NULL); + if (ret != MP_VAL) + return 9961; + ret = mp_exptmod_nct(NULL, a, NULL, NULL); + if (ret != MP_VAL) + return 9962; + ret = mp_exptmod_nct(NULL, NULL, a, NULL); + if (ret != MP_VAL) + return 9963; + ret = mp_exptmod_nct(NULL, NULL, NULL, a); + if (ret != MP_VAL) + return 9964; + ret = mp_exptmod_nct(a, a, a, NULL); + if (ret != MP_VAL) + return 9965; + ret = mp_exptmod_nct(a, a, NULL, a); + if (ret != MP_VAL) + return 9966; + ret = mp_exptmod_nct(a, NULL, a, a); + if (ret != MP_VAL) + return 9967; + ret = mp_exptmod_nct(NULL, a, a, a); + if (ret != MP_VAL) + return 9968; +#endif + +#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_DH) || !defined(NO_DSA)) && \ + !defined(WC_NO_RNG) + ret = mp_rand_prime(NULL, 32, NULL, NULL); + if (ret != MP_VAL) + return -12787; + ret = mp_rand_prime(a, 32, NULL, NULL); + if (ret != MP_VAL) + return -12788; + ret = mp_rand_prime(NULL, 32, rng, NULL); + if (ret != MP_VAL) + return -12789; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) + ret = mp_mul(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12790; + ret = mp_mul(a, NULL, NULL); + if (ret != MP_VAL) + return -12791; + ret = mp_mul(NULL, b, NULL); + if (ret != MP_VAL) + return -12792; + ret = mp_mul(NULL, NULL, r); + if (ret != MP_VAL) + return -12793; + ret = mp_mul(a, b, NULL); + if (ret != MP_VAL) + return -12794; + ret = mp_mul(a, NULL, r); + if (ret != MP_VAL) + return -12795; + ret = mp_mul(NULL, b, r); + if (ret != MP_VAL) + return -12796; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + ret = mp_sqr(NULL, NULL); + if (ret != MP_VAL) + return -12797; + ret = mp_sqr(a, NULL); + if (ret != MP_VAL) + return -12798; + ret = mp_sqr(NULL, r); + if (ret != MP_VAL) + return -12799; +#endif + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) + ret = mp_sqrmod(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12800; + ret = mp_sqrmod(a, NULL, NULL); + if (ret != MP_VAL) + return -12801; + ret = mp_sqrmod(NULL, a, NULL); + if (ret != MP_VAL) + return -12802; + ret = mp_sqrmod(NULL, NULL, a); + if (ret != MP_VAL) + return -12803; + ret = mp_sqrmod(a, b, NULL); + if (ret != MP_VAL) + return -12804; + ret = mp_sqrmod(a, NULL, b); + if (ret != MP_VAL) + return -12805; + ret = mp_sqrmod(NULL, a, b); + if (ret != MP_VAL) + return -12806; + + ret = mp_mulmod(NULL, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12807; + ret = mp_mulmod(a, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12808; + ret = mp_mulmod(NULL, a, NULL, NULL); + if (ret != MP_VAL) + return -12809; + ret = mp_mulmod(NULL, NULL, a, NULL); + if (ret != MP_VAL) + return -12810; + ret = mp_mulmod(NULL, NULL, NULL, a); + if (ret != MP_VAL) + return -12811; + ret = mp_mulmod(a, b, b, NULL); + if (ret != MP_VAL) + return -12812; + ret = mp_mulmod(a, b, NULL, a); + if (ret != MP_VAL) + return -12813; + ret = mp_mulmod(a, NULL, b, a); + if (ret != MP_VAL) + return -12814; + ret = mp_mulmod(NULL, b, b, a); + if (ret != MP_VAL) + return -12815; +#endif + +#if !defined(NO_PWDBASED) || defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || \ + !defined(NO_RSA) || !defined(NO_DSA) + ret = mp_add_d(NULL, 1, NULL); + if (ret != MP_VAL) + return -12816; + ret = mp_add_d(a, 1, NULL); + if (ret != MP_VAL) + return -12817; + ret = mp_add_d(NULL, 1, b); + if (ret != MP_VAL) + return -12818; +#endif + +#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + !defined(NO_DH) || defined(HAVE_ECC) || !defined(NO_DSA) + ret = mp_sub_d(NULL, 1, NULL); + if (ret != MP_VAL) + return -12819; + ret = mp_sub_d(a, 1, NULL); + if (ret != MP_VAL) + return -12820; + ret = mp_sub_d(NULL, 1, b); + if (ret != MP_VAL) + return -12821; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && defined(FP_ECC)) + ret = mp_div_d(NULL, 0, NULL, NULL); + if (ret != MP_VAL) + return -12822; + ret = mp_div_d(a, 0, NULL, NULL); + if (ret != MP_VAL) + return -12823; + ret = mp_div_d(NULL, 1, NULL, NULL); + if (ret != MP_VAL) + return -12824; +#endif + +#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \ + (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN)) + ret = mp_mod_d(NULL, 0, NULL); + if (ret != MP_VAL) + return -12825; + ret = mp_mod_d(a, 0, NULL); + if (ret != MP_VAL) + return -12826; + ret = mp_mod_d(NULL, 0, &rd); + if (ret != MP_VAL) + return -12827; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && defined(FP_ECC)) + ret = mp_gcd(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12828; + ret = mp_gcd(a, NULL, NULL); + if (ret != MP_VAL) + return -12829; + ret = mp_gcd(NULL, a, NULL); + if (ret != MP_VAL) + return -12830; + ret = mp_gcd(NULL, NULL, a); + if (ret != MP_VAL) + return -12831; + ret = mp_gcd(a, b, NULL); + if (ret != MP_VAL) + return -12832; + ret = mp_gcd(a, NULL, b); + if (ret != MP_VAL) + return -12833; + ret = mp_gcd(NULL, a, b); + if (ret != MP_VAL) + return -12834; +#endif + +#ifdef HAVE_ECC + ret = mp_div_2_mod_ct(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12835; + ret = mp_div_2_mod_ct(a, NULL, NULL); + if (ret != MP_VAL) + return -12836; + ret = mp_div_2_mod_ct(NULL, b, NULL); + if (ret != MP_VAL) + return -12837; + ret = mp_div_2_mod_ct(NULL, NULL, a); + if (ret != MP_VAL) + return -12838; + ret = mp_div_2_mod_ct(a, b, NULL); + if (ret != MP_VAL) + return -12839; + ret = mp_div_2_mod_ct(a, b, NULL); + if (ret != MP_VAL) + return -12840; + ret = mp_div_2_mod_ct(NULL, b, a); + if (ret != MP_VAL) + return -12841; + + ret = mp_div_2(NULL, NULL); + if (ret != MP_VAL) + return -12842; + ret = mp_div_2(a, NULL); + if (ret != MP_VAL) + return -12843; + ret = mp_div_2(NULL, a); + if (ret != MP_VAL) + return -12844; +#endif + +#if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + defined(HAVE_ECC) || !defined(NO_DSA) || defined(OPENSSL_EXTRA) + ret = mp_invmod(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12845; + ret = mp_invmod(a, NULL, NULL); + if (ret != MP_VAL) + return -12846; + ret = mp_invmod(NULL, b, NULL); + if (ret != MP_VAL) + return -12847; + ret = mp_invmod(NULL, NULL, a); + if (ret != MP_VAL) + return -12848; + ret = mp_invmod(a, b, NULL); + if (ret != MP_VAL) + return -12849; + ret = mp_invmod(a, NULL, a); + if (ret != MP_VAL) + return -12850; + ret = mp_invmod(NULL, b, a); + if (ret != MP_VAL) + return -12851; +#endif + +#ifdef HAVE_ECC + ret = mp_invmod_mont_ct(NULL, NULL, NULL, 1); + if (ret != MP_VAL) + return -12852; + ret = mp_invmod_mont_ct(a, NULL, NULL, 1); + if (ret != MP_VAL) + return -12853; + ret = mp_invmod_mont_ct(NULL, b, NULL, 1); + if (ret != MP_VAL) + return -12854; + ret = mp_invmod_mont_ct(NULL, NULL, a, 1); + if (ret != MP_VAL) + return -12855; + ret = mp_invmod_mont_ct(a, b, NULL, 1); + if (ret != MP_VAL) + return -12856; + ret = mp_invmod_mont_ct(a, NULL, a, 1); + if (ret != MP_VAL) + return -12857; + ret = mp_invmod_mont_ct(NULL, b, a, 1); + if (ret != MP_VAL) + return -12858; +#endif + +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) + ret = mp_lcm(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12859; + ret = mp_lcm(a, NULL, NULL); + if (ret != MP_VAL) + return -12860; + ret = mp_lcm(NULL, b, NULL); + if (ret != MP_VAL) + return -12861; + ret = mp_lcm(NULL, NULL, a); + if (ret != MP_VAL) + return -12862; + ret = mp_lcm(a, b, NULL); + if (ret != MP_VAL) + return -12863; + ret = mp_lcm(a, NULL, a); + if (ret != MP_VAL) + return -12864; + ret = mp_lcm(NULL, b, a); + if (ret != MP_VAL) + return -12865; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) + ret = mp_exptmod_ex(NULL, NULL, 1, NULL, NULL); + if (ret != MP_VAL) + return -12866; + ret = mp_exptmod_ex(a, NULL, 1, NULL, NULL); + if (ret != MP_VAL) + return -12867; + ret = mp_exptmod_ex(NULL, b, 1, NULL, NULL); + if (ret != MP_VAL) + return -12868; + ret = mp_exptmod_ex(NULL, NULL, 1, b, NULL); + if (ret != MP_VAL) + return -12869; + ret = mp_exptmod_ex(NULL, NULL, 1, NULL, a); + if (ret != MP_VAL) + return -12870; + ret = mp_exptmod_ex(a, b, 1, b, NULL); + if (ret != MP_VAL) + return -12871; + ret = mp_exptmod_ex(a, b, 1, NULL, a); + if (ret != MP_VAL) + return -12872; + ret = mp_exptmod_ex(a, NULL, 1, b, a); + if (ret != MP_VAL) + return -12873; + ret = mp_exptmod_ex(NULL, b, 1, b, a); + if (ret != MP_VAL) + return -12874; + + ret = mp_exptmod(NULL, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12875; + ret = mp_exptmod(a, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12876; + ret = mp_exptmod(NULL, b, NULL, NULL); + if (ret != MP_VAL) + return -12877; + ret = mp_exptmod(NULL, NULL, b, NULL); + if (ret != MP_VAL) + return -12878; + ret = mp_exptmod(NULL, NULL, NULL, a); + if (ret != MP_VAL) + return -12879; + ret = mp_exptmod(a, b, b, NULL); + if (ret != MP_VAL) + return -12880; + ret = mp_exptmod(a, b, NULL, a); + if (ret != MP_VAL) + return -12881; + ret = mp_exptmod(a, NULL, b, a); + if (ret != MP_VAL) + return -12882; + ret = mp_exptmod(NULL, b, b, a); + if (ret != MP_VAL) + return -12883; + + ret = mp_exptmod_nct(NULL, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12884; + ret = mp_exptmod_nct(a, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12885; + ret = mp_exptmod_nct(NULL, b, NULL, NULL); + if (ret != MP_VAL) + return -12886; + ret = mp_exptmod_nct(NULL, NULL, b, NULL); + if (ret != MP_VAL) + return -12887; + ret = mp_exptmod_nct(NULL, NULL, NULL, a); + if (ret != MP_VAL) + return -12888; + ret = mp_exptmod_nct(a, b, b, NULL); + if (ret != MP_VAL) + return -12889; + ret = mp_exptmod_nct(a, b, NULL, a); + if (ret != MP_VAL) + return -12890; + ret = mp_exptmod_nct(a, NULL, b, a); + if (ret != MP_VAL) + return -12891; + ret = mp_exptmod_nct(NULL, b, b, a); + if (ret != MP_VAL) + return -12892; +#endif + +#if defined(HAVE_ECC) && defined(HAVE_COMP_KEY) + ret = mp_cnt_lsb(NULL); + if (ret != 0) + return -12893; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) + ret = mp_prime_is_prime(NULL, 1, NULL); + if (ret != MP_VAL) + return -12894; + ret = mp_prime_is_prime(a, 1, NULL); + if (ret != MP_VAL) + return -12895; + ret = mp_prime_is_prime(NULL, 1, &result); + if (ret != MP_VAL) + return -12896; + ret = mp_prime_is_prime(a, 0, &result); + if (ret != MP_VAL) + return -12897; + ret = mp_prime_is_prime(a, 1024, &result); + if (ret != MP_VAL) + return -12898; + + ret = mp_prime_is_prime_ex(NULL, 1, NULL, NULL); + if (ret != MP_VAL) + return -12899; + ret = mp_prime_is_prime_ex(a, 1, NULL, NULL); + if (ret != MP_VAL) + return -12900; + ret = mp_prime_is_prime_ex(NULL, 1, &result, NULL); + if (ret != MP_VAL) + return -12901; + ret = mp_prime_is_prime_ex(NULL, 1, NULL, rng); + if (ret != MP_VAL) + return -12902; + ret = mp_prime_is_prime_ex(a, 1, &result, NULL); + if (ret != MP_VAL) + return -12903; + ret = mp_prime_is_prime_ex(a, 1, NULL, rng); + if (ret != MP_VAL) + return -12904; + ret = mp_prime_is_prime_ex(NULL, 1, &result, rng); + if (ret != MP_VAL) + return -12905; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || !defined(NO_DSA) + ret = mp_exch(NULL, NULL); + if (ret != MP_VAL) + return -12906; + ret = mp_exch(a, NULL); + if (ret != MP_VAL) + return -12907; + ret = mp_exch(NULL, b); + if (ret != MP_VAL) + return -12908; +#endif + +#if (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)) || \ + defined(WOLFSSL_SP_MATH_ALL) + ret = mp_mul_d(NULL, 1, NULL); + if (ret != MP_VAL) + return -12909; + ret = mp_mul_d(a, 1, NULL); + if (ret != MP_VAL) + return -12910; + ret = mp_mul_d(NULL, 1, b); + if (ret != MP_VAL) + return -12911; +#endif + +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) + ret = mp_add(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12912; + ret = mp_add(a, NULL, NULL); + if (ret != MP_VAL) + return -12913; + ret = mp_add(NULL, b, NULL); + if (ret != MP_VAL) + return -12914; + ret = mp_add(NULL, NULL, r); + if (ret != MP_VAL) + return -12915; + ret = mp_add(a, b, NULL); + if (ret != MP_VAL) + return -12916; + ret = mp_add(a, NULL, r); + if (ret != MP_VAL) + return -12917; + ret = mp_add(NULL, b, r); + if (ret != MP_VAL) + return -12918; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + ret = mp_sub(NULL, NULL, NULL); + if (ret != MP_VAL) + return -12919; + ret = mp_sub(a, NULL, NULL); + if (ret != MP_VAL) + return -12920; + ret = mp_sub(NULL, b, NULL); + if (ret != MP_VAL) + return -12921; + ret = mp_sub(NULL, NULL, r); + if (ret != MP_VAL) + return -12922; + ret = mp_sub(a, b, NULL); + if (ret != MP_VAL) + return -12923; + ret = mp_sub(a, NULL, r); + if (ret != MP_VAL) + return -12924; + ret = mp_sub(NULL, b, r); + if (ret != MP_VAL) + return -12925; +#endif + + +#if defined(WOLFSSL_SP_MATH_ALL) || (!defined(WOLFSSL_SP_MATH) && \ + defined(WOLFSSL_CUSTOM_CURVES)) + ret = mp_addmod(NULL, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12926; + ret = mp_addmod(a, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12927; + ret = mp_addmod(NULL, b, NULL, NULL); + if (ret != MP_VAL) + return -12928; + ret = mp_addmod(NULL, NULL, b, NULL); + if (ret != MP_VAL) + return -12929; + ret = mp_addmod(NULL, NULL, NULL, a); + if (ret != MP_VAL) + return -12930; + ret = mp_addmod(a, b, b, NULL); + if (ret != MP_VAL) + return -12931; + ret = mp_addmod(a, b, NULL, a); + if (ret != MP_VAL) + return -12932; + ret = mp_addmod(a, NULL, b, a); + if (ret != MP_VAL) + return -12933; + ret = mp_addmod(NULL, b, b, a); + if (ret != MP_VAL) + return -12934; +#endif + +#ifdef WOLFSSL_SP_MATH_ALL + ret = mp_submod(NULL, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12935; + ret = mp_submod(a, NULL, NULL, NULL); + if (ret != MP_VAL) + return -12936; + ret = mp_submod(NULL, b, NULL, NULL); + if (ret != MP_VAL) + return -12937; + ret = mp_submod(NULL, NULL, b, NULL); + if (ret != MP_VAL) + return -12938; + ret = mp_submod(NULL, NULL, NULL, a); + if (ret != MP_VAL) + return -12939; + ret = mp_submod(a, b, b, NULL); + if (ret != MP_VAL) + return -12940; + ret = mp_submod(a, b, NULL, a); + if (ret != MP_VAL) + return -12941; + ret = mp_submod(a, NULL, b, a); + if (ret != MP_VAL) + return -12942; + ret = mp_submod(NULL, b, b, a); + if (ret != MP_VAL) + return -12943; +#endif + +#ifdef WOLFSSL_SP_MATH_ALL + ret = mp_div_2d(NULL, 1, a, b); + if (ret != MP_VAL) + return -12944; + + ret = mp_mod_2d(NULL, 1, NULL); + if (ret != MP_VAL) + return -12945; + ret = mp_mod_2d(a, 1, NULL); + if (ret != MP_VAL) + return -12946; + ret = mp_mod_2d(NULL, 1, b); + if (ret != MP_VAL) + return -12947; + + ret = mp_mul_2d(NULL, 1, NULL); + if (ret != MP_VAL) + return -12948; + ret = mp_mul_2d(a, 1, NULL); + if (ret != MP_VAL) + return -12949; + ret = mp_mul_2d(NULL, 1, b); + if (ret != MP_VAL) + return -12950; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + ret = mp_montgomery_reduce(NULL, NULL, 1); + if (ret != MP_VAL) + return -12951; + ret = mp_montgomery_reduce(a, NULL, 1); + if (ret != MP_VAL) + return -12952; + ret = mp_montgomery_reduce(NULL, b, 1); + if (ret != MP_VAL) + return -12953; + mp_zero(b); + ret = mp_montgomery_reduce(a, b, 1); + if (ret != MP_VAL) + return -12954; +#endif + +#ifdef WOLFSSL_SP_MATH_ALL + ret = mp_montgomery_setup(NULL, NULL); + if (ret != MP_VAL) + return -12955; + ret = mp_montgomery_setup(a, NULL); + if (ret != MP_VAL) + return -12956; + ret = mp_montgomery_setup(NULL, &rho); + if (ret != MP_VAL) + return -12957; + + ret = mp_montgomery_calc_normalization(NULL, NULL); + if (ret != MP_VAL) + return -12958; + ret = mp_montgomery_calc_normalization(a, NULL); + if (ret != MP_VAL) + return -12959; + ret = mp_montgomery_calc_normalization(NULL, b); + if (ret != MP_VAL) + return -12960; +#endif + + ret = mp_unsigned_bin_size(NULL); + if (ret != 0) + return -12961; + +#if defined(WC_MP_TO_RADIX) || defined(WOLFSSL_SP_MATH_ALL) + ret = mp_tohex(NULL, NULL); + if (ret != MP_VAL) + return -12962; + ret = mp_tohex(a, NULL); + if (ret != MP_VAL) + return -12963; + ret = mp_tohex(NULL, hexStr); + if (ret != MP_VAL) + return -12964; +#endif + +#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) + ret = mp_todecimal(NULL, NULL); + if (ret != MP_VAL) + return -12965; + ret = mp_todecimal(a, NULL); + if (ret != MP_VAL) + return -12966; + ret = mp_todecimal(NULL, decStr); + if (ret != MP_VAL) + return -12967; +#endif + +#ifdef WOLFSSL_SP_MATH_ALL + ret = mp_toradix(NULL, NULL, MP_RADIX_HEX); + if (ret != MP_VAL) + return -12968; + ret = mp_toradix(a, NULL, MP_RADIX_HEX); + if (ret != MP_VAL) + return -12969; + ret = mp_toradix(NULL, hexStr, MP_RADIX_HEX); + if (ret != MP_VAL) + return -12970; + ret = mp_toradix(a, hexStr, 3); + if (ret != MP_VAL) + return -12971; + + ret = mp_radix_size(NULL, MP_RADIX_HEX, NULL); + if (ret != MP_VAL) + return -12972; + ret = mp_radix_size(a, MP_RADIX_HEX, NULL); + if (ret != MP_VAL) + return -12973; + ret = mp_radix_size(NULL, MP_RADIX_HEX, &size); + if (ret != MP_VAL) + return -12974; + ret = mp_radix_size(a, 3, &size); + if (ret != MP_VAL) + return -12975; +#endif + + return 0; +} +#endif + +#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) +static int mp_test_set_is_bit(mp_int* a) +{ + int i, j; + + mp_zero(a); + for (i = 0; i <= DIGIT_BIT * 2; i++) { + if (mp_is_bit_set(a, i)) + return -12980; + for (j = 0; j < i; j++) { + if (!mp_is_bit_set(a, j)) + return -12981; + } + if (mp_set_bit(a, i) != 0) + return -12982; + if (!mp_is_bit_set(a, i)) + return -12983; + } + + mp_zero(a); + for (i = 0; i <= DIGIT_BIT * 2; i++) { + if (mp_is_bit_set(a, i)) + return -12984; + } + + for (i = 0; i <= DIGIT_BIT * 2; i++) { + mp_zero(a); + if (mp_set_bit(a, i) != 0) + return -12985; + for (j = 0; j < i; j++) { + if (mp_is_bit_set(a, j)) + return -12986; + } + if (!mp_is_bit_set(a, i)) + return -12987; + } + +#ifdef WOLFSSL_KEY_GEN + for (i = 0; i < DIGIT_BIT * 2; i++) { + mp_set(a, 1); + if (mp_2expt(a, i) != 0) + return -12988; + for (j = 0; j < i; j++) { + if (mp_is_bit_set(a, j)) + return -12989; + } + if (!mp_is_bit_set(a, i)) + return -12990; + } +#endif + +#ifdef WOLFSSL_SP_MATH + mp_zero(a); + for (j = 1; j <= 3; j++) { + i = SP_INT_MAX_BITS - j; + if (mp_is_bit_set(a, i)) + return -12991; + if (mp_set_bit(a, i) != 0) + return -12992; + if (!mp_is_bit_set(a, i)) + return -12993; + #ifdef WOLFSSL_KEY_GEN + if (mp_2expt(a, i) != 0) + return -12994; + if (!mp_is_bit_set(a, i)) + return -12995; + #endif + } + + mp_zero(a); + for (j = 0; j <= 3; j++) { + i = SP_INT_MAX_BITS + j; + if (mp_is_bit_set(a, i)) + return -12996; + if (mp_set_bit(a, i) != MP_VAL) + return -12997; + #ifdef WOLFSSL_KEY_GEN + if (mp_2expt(a, i) != MP_VAL) + return -12998; + #endif + } +#endif + + return 0; +} +#endif /* !WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */ + +static int mp_test_cmp(mp_int* a, mp_int* b) +{ + int ret; + + mp_zero(a); + mp_zero(b); + + ret = mp_cmp_d(a, 0); + if (ret != MP_EQ) + return -13000; + ret = mp_cmp_d(a, 1); + if (ret != MP_LT) + return -13001; + + ret = mp_cmp(a, b); + if (ret != MP_EQ) + return -13002; + + mp_set(a, 1); + ret = mp_cmp_d(a, 0); + if (ret != MP_GT) + return -13003; + ret = mp_cmp_d(a, 1); + if (ret != MP_EQ) + return -13004; + ret = mp_cmp_d(a, 2); + if (ret != MP_LT) + return -13005; + + ret = mp_cmp(a, b); + if (ret != MP_GT) + return -13006; + + mp_read_radix(b, "1234567890123456789", MP_RADIX_HEX); + ret = mp_cmp_d(b, -1); + if (ret != MP_GT) + return -13007; + + ret = mp_cmp(a, b); + if (ret != MP_LT) + return -13008; + ret = mp_cmp(b, a); + if (ret != MP_GT) + return -13009; + ret = mp_cmp(b, b); + if (ret != MP_EQ) + return -13010; + + return 0; +} + +#if !defined(NO_DH) || defined(HAVE_ECC) || !defined(WOLFSSL_RSA_VERIFY_ONLY) +static int mp_test_shbd(mp_int* a, mp_int* b, WC_RNG* rng) +{ + int ret; + int i, j, k; + + for (i = 0; i < 10; i++) { + for (j = 1; j < (DIGIT_BIT + 7) / 8 * 3; j++) { + ret = randNum(a, j, rng, NULL); + if (ret != MP_OKAY) + return -13020; + mp_copy(a, b); + for (k = 0; k <= DIGIT_BIT * 2; k++) { + ret = mp_mul_2d(a, k, a); + if (ret != MP_OKAY) + return -13021; + mp_rshb(a, k); + if (mp_cmp(a, b) != MP_EQ) + return -13022; + } + } + } + + for (i = 0; i < 10; i++) { + for (j = 1; j < (DIGIT_BIT + 7) / 8 * 3; j++) { + ret = randNum(a, j, rng, NULL); + if (ret != MP_OKAY) + return -13023; + mp_copy(a, b); + for (k = 0; k < 10; k++) { + ret = mp_lshd(a, k); + if (ret != MP_OKAY) + return -13024; + mp_rshd(a, k); + if (mp_cmp(a, b) != MP_EQ) + return -13025; + } + } + } + + mp_zero(a); + mp_rshd(a, 1); + if (!mp_iszero(a)) + return -13026; + + mp_set(a, 1); + mp_rshd(a, 1); + if (!mp_iszero(a)) + return -13027; + + mp_set(a, 1); + mp_rshd(a, 2); + if (!mp_iszero(a)) + return -13028; + + return 0; +} +#endif + +static int mp_test_div(mp_int* a, mp_int* d, mp_int* r, mp_int* rem, + WC_RNG* rng) +{ + int ret; + int i, j, k; + + mp_zero(a); + mp_zero(d); + + ret = mp_div(a, d, r, rem); + if (ret != MP_VAL) + return -13030; + + mp_set(d, 1); + ret = mp_div(a, d, r, rem); + if (ret != MP_OKAY) + return -13031; + if (!mp_iszero(r)) + return -13032; + if (!mp_iszero(rem)) + return -13033; + + mp_set(a, 1); + ret = mp_div(a, d, r, rem); + if (ret != MP_OKAY) + return -13034; + if (!mp_isone(r)) + return -13035; + if (!mp_iszero(rem)) + return -13036; + + for (i = 0; i < 100; i++) { + for (j = 1; j < (DIGIT_BIT + 7) / 8 * 2; j++) { + ret = randNum(d, j, rng, NULL); + if (ret != MP_OKAY) + return -13037; + for (k = 1; k < (DIGIT_BIT + 7) / 8 * 2 + 1; k++) { + ret = randNum(a, k, rng, NULL); + if (ret != MP_OKAY) + return -13038; + + ret = mp_div(a, d, NULL, rem); + if (ret != MP_OKAY) + return -13039; + ret = mp_div(a, d, r, NULL); + if (ret != MP_OKAY) + return -13040; + ret = mp_div(a, d, r, rem); + if (ret != MP_OKAY) + return -13041; + + mp_mul(r, d, r); + mp_add(r, rem, r); + + if (mp_cmp(r, a) != MP_EQ) + return -13042; + } + } + } + + ret = randNum(d, (DIGIT_BIT + 7) / 8 * 2, rng, NULL); + if (ret != MP_OKAY) + return -13043; + mp_add(d, d, a); + + mp_set(rem, 1); + mp_div(a, d, NULL, rem); + if (ret != MP_OKAY) + return -13044; + if (!mp_iszero(rem)) + return -13045; + + mp_set(r, 1); + mp_div(a, d, r, NULL); + if (ret != MP_OKAY) + return -13046; + if (mp_cmp_d(r, 2) != MP_EQ) + return -13047; + + mp_set(r, 1); + mp_set(rem, 1); + mp_div(a, d, r, rem); + if (ret != MP_OKAY) + return -13048; + if (mp_cmp_d(r, 2) != MP_EQ) + return -13049; + if (!mp_iszero(rem)) + return -13050; + + mp_set(a, 0xfe); + mp_lshd(a, 3); + mp_add_d(a, 0xff, a); + mp_set(d, 0xfe); + mp_lshd(d, 2); + ret = mp_div(a, d, r, rem); + if (ret != MP_OKAY) + return -13051; + mp_mul(r, d, d); + mp_add(rem, d, d); + if (mp_cmp(a, d) != MP_EQ) + return -13052; + + /* Force (hi | lo) / d to be (d | 0) / d which will would not fit in + * a digit. So mp_div must detect and handle. + * For example: 0x800000 / 0x8001, DIGIT_BIT = 8 + */ + mp_set(a, 1); + mp_mul_2d(a, DIGIT_BIT * 3 - 1, a); + mp_set(d, 1); + mp_mul_2d(d, DIGIT_BIT * 2 - 1, d); + mp_add_d(d, 1, d); + ret = mp_div(a, d, r, rem); + if (ret != MP_OKAY) + return -13053; + + return 0; +} + +#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_DH) || !defined(NO_DSA)) && \ + !defined(WC_NO_RNG) +static int mp_test_prime(mp_int* a, WC_RNG* rng) +{ + int ret; + int res; + + ret = mp_rand_prime(a, 1, rng, NULL); +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) + if (ret != 0) +#else + if (ret != MP_VAL) +#endif + return -13060; + ret = mp_rand_prime(a, -5, rng, NULL); + if (ret != 0) + return -13061; + ret = mp_prime_is_prime(a, 1, &res); + if (ret != MP_OKAY) + return -13062; + if (res != MP_YES) + return -13063; + + ret = mp_prime_is_prime(a, 0, &res); + if (ret != MP_VAL) + return -13064; + ret = mp_prime_is_prime(a, -1, &res); + if (ret != MP_VAL) + return -13065; + ret = mp_prime_is_prime(a, 257, &res); + if (ret != MP_VAL) + return -13066; + + mp_set(a, 1); + ret = mp_prime_is_prime(a, 1, &res); + if (ret != MP_OKAY) + return -13067; + if (res != MP_NO) + return -13068; + ret = mp_prime_is_prime_ex(a, 1, &res, rng); + if (ret != MP_OKAY) + return -13069; + if (res != MP_NO) + return -13070; + + mp_set(a, 2); + ret = mp_prime_is_prime(a, 1, &res); + if (ret != MP_OKAY) + return -13071; + if (res != MP_YES) + return -13072; + ret = mp_prime_is_prime_ex(a, 1, &res, rng); + if (ret != MP_OKAY) + return -13073; + if (res != MP_YES) + return -13074; + + mp_set(a, 0xfb); + ret = mp_prime_is_prime(a, 1, &res); + if (ret != MP_OKAY) + return -13075; + if (res != MP_YES) + return -13076; + ret = mp_prime_is_prime_ex(a, 1, &res, rng); + if (ret != MP_OKAY) + return -13077; + if (res != MP_YES) + return -13078; + + mp_set(a, 0x6); + ret = mp_prime_is_prime(a, 1, &res); + if (ret != MP_OKAY) + return -13079; + if (res != MP_NO) + return -13080; + ret = mp_prime_is_prime_ex(a, 1, &res, rng); + if (ret != MP_OKAY) + return -13081; + if (res != MP_NO) + return -13082; + + mp_set_int(a, 0x655 * 0x65b); + ret = mp_prime_is_prime(a, 10, &res); + if (ret != MP_OKAY) + return -13083; + if (res != MP_NO) + return -13084; + ret = mp_prime_is_prime_ex(a, 10, &res, rng); + if (ret != MP_OKAY) + return -13085; + if (res != MP_NO) + return -13086; + + return 0; +} +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || (defined(WOLFSSL_SP_MATH) && \ + defined(WOLFSSL_HAVE_SP_DH) || (defined(HAVE_ECC) && defined(FP_ECC))) +static int mp_test_lcm_gcd(mp_int* a, mp_int* b, mp_int* r, mp_int* exp, + WC_RNG* rng) +{ + int ret; +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) + int i; + static const int kat[][3] = { + { 1, 1, 1 }, { 2, 1, 2 }, { 1, 2, 2 }, { 2, 4, 4 }, { 4, 2, 4 }, + { 12, 56, 168 }, { 56, 12, 168 } + }; +#endif + + (void)exp; + +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) + mp_set(a, 0); + mp_set(b, 1); + ret = mp_lcm(a, a, r); + if (ret != MP_VAL) + return -13090; + ret = mp_lcm(a, b, r); + if (ret != MP_VAL) + return -13091; + ret = mp_lcm(b, a, r); + if (ret != MP_VAL) + return -13092; + + for (i = 0; i < (int)(sizeof(kat) / sizeof(*kat)); i++) { + mp_set(a, kat[i][0]); + mp_set(b, kat[i][1]); + ret = mp_lcm(a, b, r); + if (ret != MP_OKAY) + return -13093; + mp_set(exp, kat[i][2]); + if (mp_cmp(r, exp) != MP_EQ) + return -13094; + } +#endif + + (void)rng; +#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_DH) || !defined(NO_DSA)) && \ + !defined(WC_NO_RNG) + if (mp_rand_prime(a, 20, rng, NULL) != MP_OKAY) + return -13095; + if (mp_rand_prime(b, 20, rng, NULL) != MP_OKAY) + return -13096; + if (mp_mul(a, b, exp) != MP_OKAY) + return -13097; + ret = mp_lcm(a, b, r); + if (ret != MP_OKAY) + return -13098; + if (mp_cmp(r, exp) != MP_EQ) + return -13099; + ret = mp_lcm(b, a, r); + if (ret != MP_OKAY) + return -13100; + if (mp_cmp(r, exp) != MP_EQ) + return -13101; +#endif + + mp_set(a, 11); + mp_zero(b); + ret = mp_gcd(a, b, r); + if (ret != MP_OKAY) + return -13102; + if (mp_cmp_d(r, 11) != MP_EQ) + return -13103; + ret = mp_gcd(b, a, r); + if (ret != MP_OKAY) + return -13104; + if (mp_cmp_d(r, 11) != MP_EQ) + return -13105; + ret = mp_gcd(b, b, r); + if (ret != MP_VAL) + return -13106; + + return 0; +} +#endif + +#if (!defined(WOLFSSL_SP_MATH) && !defined(USE_FAST_MATH)) || \ + defined(WOLFSSL_SP_MATH_ALL) +static int mp_test_mod_2d(mp_int* a, mp_int* r, mp_int* t, WC_RNG* rng) +{ + int ret; + int i; + int j; + + mp_set(a, 10); + ret = mp_mod_2d(a, 0, r); + if (ret != MP_OKAY) + return -13110; + if (!mp_iszero(r)) + return -13111; + + ret = mp_mod_2d(a, 1, r); + if (ret != MP_OKAY) + return -13112; + if (!mp_iszero(r)) + return -13113; + + ret = mp_mod_2d(a, 2, r); + if (ret != MP_OKAY) + return -13114; + if (mp_cmp_d(r, 2)) + return -13115; + + for (i = 2; i < 20; i++) { + ret = randNum(a, i, rng, NULL); + if (ret != 0) + return -13116; + for (j = 1; j <= mp_count_bits(a); j++) { + /* Get top part */ + ret = mp_div_2d(a, j, t, NULL); + if (ret != 0) + return -13117; + ret = mp_mul_2d(t, j, t); + if (ret != 0) + return -13118; + + /* Get bottom part */ + ret = mp_mod_2d(a, j, r); + if (ret != 0) + return -13119; + + /* Reassemble */ + ret = mp_add(t, r, r); + if (ret != 0) + return -13120; + if (mp_cmp(a, r) != MP_EQ) + return -13121; + } + } + + return 0; +} +#endif + +#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \ + (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN)) +static int mp_test_mod_d(mp_int* a) +{ + int ret; + mp_digit r; + + if (mp_set(a, 1) != MP_OKAY) + return -13130; + ret = mp_mod_d(a, 0, &r); + if (ret != MP_VAL) + return -13131; + + mp_zero(a); + ret = mp_mod_d(a, 1, &r); + if (ret != MP_OKAY) + return -13132; + ret = mp_mod_d(a, 3, &r); + if (ret != MP_OKAY) + return -13133; + ret = mp_mod_d(a, 5, &r); + if (ret != MP_OKAY) + return -13134; + + return 0; +} +#endif + +static int mp_test_mul_sqr(mp_int* a, mp_int* b, mp_int* r1, mp_int* r2, + WC_RNG* rng) +{ + int ret; + int i; + + for (i = 1; i < 16; i++) { + ret = randNum(a, i, rng, NULL); + if (ret != 0) + return -13140; + + ret = mp_mul(a, a, r1); + if (ret != 0) + return -13141; + ret = mp_sqr(a, r2); + if (ret != 0) + return -13142; + + if (mp_cmp(r1, r2) != MP_EQ) + return -13143; + } + + ret = mp_set(b, 0); + if (ret != MP_OKAY) + return -13144; + ret = mp_mul(a, b, r1); + if (ret != MP_OKAY) + return -13145; + if (!mp_iszero(r1)) + return -13146; + ret = mp_sqr(b, r1); + if (ret != MP_OKAY) + return -13147; + if (!mp_iszero(r1)) + return -13148; + +#ifdef WOLFSSL_SP_MATH + ret = mp_set(a, 1); + if (ret != MP_OKAY) + return -13149; + i = (SP_INT_DIGITS + 1) / 2; + ret = mp_mul_2d(a, i * SP_WORD_SIZE - 1, a); + if (ret != MP_OKAY) + return -13150; + ret = mp_set(b, 1); + if (ret != MP_OKAY) + return -13151; + ret = mp_mul_2d(b, (SP_INT_DIGITS - 1 - i) * SP_WORD_SIZE - 1, b); + if (ret != MP_OKAY) + return -13152; + + ret = mp_mul(a, b, r1); + if (ret != MP_OKAY) + return -13153; + ret = mp_mul(a, a, r1); + if (ret == MP_OKAY) + return -13154; + ret = mp_sqr(a, r1); + if (ret == MP_OKAY) + return -13155; + ret = mp_sqr(b, r1); + if (ret != MP_OKAY) + return -13156; + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + (defined(HAVE_ECC) && defined(FP_ECC)) + ret = mp_mulmod(a, b, b, r1); + if (ret != MP_OKAY) + return -13157; + ret = mp_mulmod(a, a, b, r1); + if (ret == MP_OKAY) + return -13158; +#if defined(HAVE_ECC) && (defined(ECC_SHAMIR) || defined(FP_ECC)) + ret = mp_sqrmod(a, b, r1); + if (ret == MP_OKAY) + return -13159; + ret = mp_sqrmod(b, a, r1); + if (ret != MP_OKAY) + return -13160; +#endif /* HAVE_ECC && (ECC_SHAMIR || FP_ECC) */ +#endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || (HAVE_ECC && FP_ECC) */ +#endif /* WOLFSSL_SP_MATH */ + + return 0; +} + +#if !defined(NO_RSA) || defined(HAVE_ECC) || !defined(NO_DSA) || \ + defined(OPENSSL_EXTRA) +static int mp_test_invmod(mp_int* a, mp_int* m, mp_int* r) +{ + int ret; + + mp_set(a, 0); + mp_set(m, 1); + ret = mp_invmod(a, m, r); + if (ret != MP_VAL) + return -13170; + ret = mp_invmod(m, a, r); + if (ret != MP_VAL) + return -13171; + mp_set(a, 2); + mp_set(m, 4); + ret = mp_invmod(a, m, r); + if (ret != MP_VAL) + return -13172; + mp_set(a, 1); + mp_set(m, 4); + ret = mp_invmod(a, m, r); + if (ret != MP_OKAY) + return -13173; + if (!mp_isone(r)) + return -13174; + + mp_set(a, 3); + mp_set(m, 4); + ret = mp_invmod(a, m, r); + if (ret != MP_OKAY) + return -13175; + + mp_set(a, 3); + mp_set(m, 5); + ret = mp_invmod(a, m, r); + if (ret != MP_OKAY) + return -13176; + +#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_INT_NEGATIVE) + mp_read_radix(a, "-3", 16); + ret = mp_invmod(a, m, r); + if (ret != MP_OKAY) + return -13177; +#endif + +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) +#ifdef HAVE_ECC + mp_set(a, 0); + mp_set(m, 3); + ret = mp_invmod_mont_ct(a, m, r, 1); + if (ret != MP_VAL) + return -13178; + mp_set(a, 1); + mp_set(m, 0); + ret = mp_invmod_mont_ct(a, m, r, 1); + if (ret != MP_VAL) + return -13179; + mp_set(a, 1); + mp_set(m, 1); + ret = mp_invmod_mont_ct(a, m, r, 1); + if (ret != MP_VAL) + return -13180; + mp_set(a, 1); + mp_set(m, 2); + ret = mp_invmod_mont_ct(a, m, r, 1); + if (ret != MP_VAL) + return -13181; + + mp_set(a, 1); + mp_set(m, 3); + ret = mp_invmod_mont_ct(a, m, r, 1); + if (ret != MP_OKAY) + return -13182; +#endif +#endif + + return 0; +} +#endif /* !NO_RSA || HAVE_ECC || !NO_DSA || OPENSSL_EXTRA */ + +#if !defined(NO_RSA) || !defined(NO_DSA) || !defined(NO_DH) || \ + (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA) +static int mp_test_exptmod(mp_int* b, mp_int* e, mp_int* m, mp_int* r) +{ + int ret; + + mp_set(b, 0x2); + mp_set(e, 0x3); + mp_set(m, 0x0); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_VAL) + return -13190; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_VAL) + return -13191; + + + mp_set(b, 0x2); + mp_set(e, 0x3); + mp_set(m, 0x1); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13192; + if (!mp_iszero(r)) + return -13193; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13194; + if (!mp_iszero(r)) + return -13195; + + mp_set(b, 0x2); + mp_set(e, 0x0); + mp_set(m, 0x7); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13196; + if (!mp_isone(r)) + return -13197; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13198; + if (!mp_isone(r)) + return -13199; + + mp_set(b, 0x0); + mp_set(e, 0x3); + mp_set(m, 0x7); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13200; + if (!mp_iszero(r)) + return -13201; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13202; + if (!mp_iszero(r)) + return -13203; + + mp_set(b, 0x10); + mp_set(e, 0x3); + mp_set(m, 0x7); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13204; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13205; + + mp_set(b, 0x7); + mp_set(e, 0x3); + mp_set(m, 0x7); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13206; + if (!mp_iszero(r)) + return -13207; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13208; + if (!mp_iszero(r)) + return -13209; + + mp_set(b, 0x01); + mp_mul_2d(b, DIGIT_BIT, b); + mp_add_d(b, 1, b); + mp_set(e, 0x3); + mp_copy(b, m); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13210; + if (!mp_iszero(r)) + return -13211; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13212; + if (!mp_iszero(r)) + return -13213; + + mp_set(b, 0x2); + mp_set(e, 0x3); + mp_set(m, 0x7); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_OKAY) + return -13214; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_OKAY) + return -13215; + +#ifdef WOLFSSL_SP_MATH + mp_set(b, 0x2); + mp_set(e, 0x3); + mp_set(m, 0x01); + mp_mul_2d(m, SP_WORD_SIZE * SP_INT_DIGITS / 2, m); + mp_add_d(m, 0x01, m); + ret = mp_exptmod_ex(b, e, 1, m, r); + if (ret != MP_VAL) + return -13216; + ret = mp_exptmod_nct(b, e, m, r); + if (ret != MP_VAL) + return -13217; +#endif + + return 0; +} +#endif /* !NO_RSA || !NO_DSA || !NO_DH || (HAVE_ECC && HAVE_COMP_KEY) || + * OPENSSL_EXTRA */ + +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) +static int mp_test_mont(mp_int* a, mp_int* m, mp_int* n, mp_int* r, WC_RNG* rng) +{ + int ret; + mp_digit mp; + static int exp[] = { 7, 8, 16, 27, 32, 64, + 127, 128, 255, 256, + 383, 384, 2033, 2048 + }; + static mp_digit sub[] = { 0x01, 0x05, 0x0f, 0x27, 0x05, 0x3b, + 0x01, 0x9f, 0x13, 0xbd, + 0x1f, 0x13d, 0x45, 0x615 + }; + int i; + int j; + + for (i = 0; i < (int)(sizeof(exp) / sizeof(*exp)); i++) { + if (exp[i] >= DIGIT_BIT) + continue; + + mp_zero(m); + ret = mp_set_bit(m, exp[i]); + if (ret != MP_OKAY) + return -13220; + ret = mp_sub_d(m, sub[i], m); + if (ret != MP_OKAY) + return -13221; + + ret = mp_montgomery_setup(m, &mp); + if (ret != MP_OKAY) + return -13222; + ret = mp_montgomery_calc_normalization(n, m); + if (ret != MP_OKAY) + return -13223; + + for (j = 0; j < 10; j++) { + ret = randNum(a, (exp[i] + DIGIT_BIT - 1) / DIGIT_BIT, rng, NULL); + if (ret != 0) + return -13224; + + ret = mp_mod(a, m, a); + if (ret != 0) + return -13225; + + /* r = a * a */ + ret = mp_sqrmod(a, m, r); + if (ret != MP_OKAY) + return -13226; + + /* Convert to Montgomery form = a*n */ + ret = mp_mulmod(a, n, m, a); + if (ret != MP_OKAY) + return -13227; + + /* a*a mod m == ((a*n) * (a*n)) / n / n */ + ret = mp_sqr(a, a); + if (ret != MP_OKAY) + return -13228; + ret = mp_montgomery_reduce(a, m, mp); + if (ret != MP_OKAY) + return -13229; + ret = mp_montgomery_reduce(a, m, mp); + if (ret != MP_OKAY) + return -13230; + + if (mp_cmp(a, r) != MP_EQ) + return -13231; + } + } + + return 0; +} +#endif + +int mp_test(void) { WC_RNG rng; int ret; @@ -29495,9 +31821,15 @@ static int mp_test(void) ret = mp_init_multi(&a, &b, &r1, &r2, NULL, NULL); if (ret != 0) - return -12300; + return -13300; +#ifdef WOLSSL_SP_MATH_ALL mp_init_copy(&p, &a); +#else + ret = mp_init(&p); + if (ret != 0) + return -13301; +#endif #ifndef HAVE_FIPS ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); @@ -29510,62 +31842,80 @@ static int mp_test(void) #if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) mp_set_int(&a, 0); if (a.used != 0 || a.dp[0] != 0) - return -12301; + return -13302; for (j = 1; j <= MP_MAX_TEST_BYTE_LEN; j++) { for (i = 0; i < 4 * j; i++) { /* New values to use. */ ret = randNum(&p, j, &rng, NULL); if (ret != 0) - return -12302; + return -13303; ret = randNum(&a, j, &rng, NULL); if (ret != 0) - return -12303; + return -13304; ret = randNum(&b, j, &rng, NULL); if (ret != 0) - return -12304; + return -13305; ret = wc_RNG_GenerateBlock(&rng, (byte*)&d, sizeof(d)); if (ret != 0) - return -12305; + return -13306; d &= MP_MASK; + #if !defined(WOLFSSL_SP_MATH) || (defined(HAVE_ECC) && \ + (defined(ECC_SHAMIR) || defined(FP_ECC))) /* Ensure sqrmod produce same result as mulmod. */ ret = mp_sqrmod(&a, &p, &r1); if (ret != 0) - return -12306; + return -13307; ret = mp_mulmod(&a, &a, &p, &r2); if (ret != 0) - return -12307; + return -13308; if (mp_cmp(&r1, &r2) != 0) - return -12308; + return -13309; + #endif + #if defined(WOLFSSL_SP_MATH) || (defined(WOLFSSL_SP_MATH_ALL) && \ + !defined(WOLFSSL_SP_INT_NEGATIVE)) + ret = mp_addmod(&a, &b, &p, &r1); + if (ret != 0) + return -13310; + ret = mp_submod(&r1, &b, &p, &r2); + if (ret != 0) + return -13311; + ret = mp_mod(&a, &p, &r1); + if (ret != 0) + return -13312; + if (mp_cmp(&r1, &r2) != MP_EQ) + return -13313; + #else /* Ensure add with mod produce same result as sub with mod. */ ret = mp_addmod(&a, &b, &p, &r1); if (ret != 0) - return -12309; + return -13314; b.sign ^= 1; ret = mp_submod(&a, &b, &p, &r2); if (ret != 0) - return -12310; + return -13315; if (mp_cmp(&r1, &r2) != 0) - return -12311; + return -13316; + #endif /* Ensure add digit produce same result as sub digit. */ ret = mp_add_d(&a, d, &r1); if (ret != 0) - return -12312; + return -13317; ret = mp_sub_d(&r1, d, &r2); if (ret != 0) - return -12313; + return -13318; if (mp_cmp(&a, &r2) != 0) - return -12314; + return -13319; /* Invert - if p is even it will use the slow impl. * - if p and a are even it will fail. */ ret = mp_invmod(&a, &p, &r1); if (ret != 0 && ret != MP_VAL) - return -12315; + return -13320; ret = 0; /* Shift up and down number all bits in a digit. */ @@ -29573,31 +31923,123 @@ static int mp_test(void) mp_mul_2d(&a, k, &r1); mp_div_2d(&r1, k, &r2, &p); if (mp_cmp(&a, &r2) != 0) - return -12316; + return -13321; if (!mp_iszero(&p)) - return -12317; + return -13322; mp_rshb(&r1, k); if (mp_cmp(&a, &r1) != 0) - return -12318; + return -13323; } } } +#if DIGIT_BIT >= 32 /* Check that setting a 32-bit digit works. */ - d &= 0xffffffff; + d &= 0xffffffffU; mp_set_int(&a, d); if (a.used != 1 || a.dp[0] != d) - return -12319; + return -13324; +#endif /* Check setting a bit and testing a bit works. */ for (i = 0; i < MP_MAX_TEST_BYTE_LEN * 8; i++) { mp_zero(&a); mp_set_bit(&a, i); if (!mp_is_bit_set(&a, i)) - return -12320; + return -13325; } #endif +#if defined(HAVE_ECC) && defined(HAVE_COMP_KEY) + mp_zero(&a); + i = mp_cnt_lsb(&a); + if (i != 0) + return -13326; + mp_set(&a, 1); + i = mp_cnt_lsb(&a); + if (i != 0) + return -13327; +#endif + +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) + if ((ret = mp_test_param(&a, &b, &r1, &rng)) != 0) + return ret; +#endif + +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(USE_FAST_MATH) + if ((ret = mp_test_div_3(&a, &r1, &rng)) != 0) + return ret; +#endif +#if defined(WOLFSSL_SP_MATH_ALL) || (!defined WOLFSSL_SP_MATH && \ + (defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY))) + if ((ret = mp_test_radix_10(&a, &r1, &rng)) != 0) + return ret; +#endif +#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) + if ((ret = mp_test_radix_16(&a, &r1, &rng)) != 0) + return ret; +#endif + + if ((ret = mp_test_shift(&a, &r1, &rng)) != 0) + return ret; + if ((ret = mp_test_add_sub_d(&a, &r1)) != 0) + return ret; + if ((ret = mp_test_read_to_bin(&a)) != 0) + return ret; +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) + if ((ret = mp_test_set_int(&a)) != 0) + return ret; +#endif + if ((ret = mp_test_cmp(&a, &r1)) != 0) + return ret; +#if !defined(NO_DH) || defined(HAVE_ECC) || !defined(WOLFSSL_RSA_VERIFY_ONLY) + if ((ret = mp_test_shbd(&a, &b, &rng)) != 0) + return ret; +#endif +#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) + if ((ret = mp_test_set_is_bit(&a)) != 0) + return ret; +#endif + if ((ret = mp_test_div(&a, &b, &r1, &r2, &rng)) != 0) + return ret; +#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_DH) || !defined(NO_DSA)) && \ + !defined(WC_NO_RNG) + if ((ret = mp_test_prime(&a, &rng)) != 0) + return ret; +#endif +#if defined(WOLFSSL_SP_MATH_ALL) || (defined(WOLFSSL_SP_MATH) && \ + defined(WOLFSSL_HAVE_SP_DH) || (defined(HAVE_ECC) && defined(FP_ECC))) + if ((ret = mp_test_lcm_gcd(&a, &b, &r1, &r2, &rng)) != 0) + return ret; +#endif +#if (!defined(WOLFSSL_SP_MATH) && !defined(USE_FAST_MATH)) || \ + defined(WOLFSSL_SP_MATH_ALL) + if ((ret = mp_test_mod_2d(&a, &r1, &p, &rng)) != 0) + return ret; +#endif +#if (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \ + (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN)) + if ((ret = mp_test_mod_d(&a)) != 0) + return ret; +#endif + if ((ret = mp_test_mul_sqr(&a, &b, &r1, &r2, &rng)) != 0) + return ret; +#if !defined(NO_RSA) || defined(HAVE_ECC) || !defined(NO_DSA) || \ + defined(OPENSSL_EXTRA) + if ((ret = mp_test_invmod(&a, &b, &r1)) != 0) + return ret; +#endif +#if !defined(NO_RSA) || !defined(NO_DSA) || !defined(NO_DH) || \ + (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA) + if ((ret = mp_test_exptmod(&a, &b, &r1, &r2)) != 0) + return ret; +#endif +#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \ + defined(HAVE_ECC) || (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) + if ((ret = mp_test_mont(&a, &b, &r1, &r2, &rng)) != 0) + return ret; +#endif + done: mp_clear(&p); mp_clear(&r2); @@ -29763,65 +32205,65 @@ static int prime_test(void) if (ret == 0) ret = mp_mul(n, p3, n); if (ret != 0) - ERROR_OUT(-12400, out); + ERROR_OUT(-13400, out); /* Check the old prime test using the number that false positives. * This test result should indicate as not prime. */ ret = mp_prime_is_prime(n, 40, &isPrime); if (ret != 0) - ERROR_OUT(-12401, out); + ERROR_OUT(-13401, out); if (isPrime) - ERROR_OUT(-12402, out); + ERROR_OUT(-13402, out); /* This test result should fail. It should indicate the value as prime. */ ret = mp_prime_is_prime(n, 8, &isPrime); if (ret != 0) - ERROR_OUT(-12403, out); + ERROR_OUT(-13403, out); if (!isPrime) - ERROR_OUT(-12404, out); + ERROR_OUT(-13404, out); /* This test result should indicate the value as not prime. */ ret = mp_prime_is_prime_ex(n, 8, &isPrime, &rng); if (ret != 0) - ERROR_OUT(-12405, out); + ERROR_OUT(-13405, out); if (isPrime) - ERROR_OUT(-12406, out); + ERROR_OUT(-13406, out); ret = mp_read_unsigned_bin(n, controlPrime, sizeof(controlPrime)); if (ret != 0) - ERROR_OUT(-12407, out); + ERROR_OUT(-13407, out); /* This test result should indicate the value as prime. */ ret = mp_prime_is_prime_ex(n, 8, &isPrime, &rng); if (ret != 0) - ERROR_OUT(-12408, out); + ERROR_OUT(-13408, out); if (!isPrime) - ERROR_OUT(-12409, out); + ERROR_OUT(-13409, out); /* This test result should indicate the value as prime. */ isPrime = -1; ret = mp_prime_is_prime(n, 8, &isPrime); if (ret != 0) - ERROR_OUT(-12410, out); + ERROR_OUT(-13410, out); if (!isPrime) - ERROR_OUT(-12411, out); + ERROR_OUT(-13411, out); ret = mp_read_unsigned_bin(n, testOne, sizeof(testOne)); if (ret != 0) - ERROR_OUT(-12412, out); + ERROR_OUT(-13412, out); /* This test result should indicate the value as not prime. */ ret = mp_prime_is_prime_ex(n, 8, &isPrime, &rng); if (ret != 0) - ERROR_OUT(-12413, out); + ERROR_OUT(-13413, out); if (isPrime) - ERROR_OUT(-12414, out); + ERROR_OUT(-13414, out); ret = mp_prime_is_prime(n, 8, &isPrime); if (ret != 0) - ERROR_OUT(-12415, out); + ERROR_OUT(-13415, out); if (isPrime) - ERROR_OUT(-12416, out); + ERROR_OUT(-13416, out); ret = 0; @@ -29921,57 +32363,57 @@ static int berder_test(void) for (i = 0; i < (int)(sizeof(testData) / sizeof(*testData)); i++) { ret = wc_BerToDer(testData[i].in, testData[i].inSz, NULL, &len); if (ret != LENGTH_ONLY_E) - return -12500 - i; + return -13500 - i; if (len != testData[i].outSz) - return -12510 - i; + return -13510 - i; len = testData[i].outSz; ret = wc_BerToDer(testData[i].in, testData[i].inSz, out, &len); if (ret != 0) - return -12520 - i; + return -13520 - i; if (XMEMCMP(out, testData[i].out, len) != 0) - return -12530 - i; + return -13530 - i; for (l = 1; l < testData[i].inSz; l++) { ret = wc_BerToDer(testData[i].in, l, NULL, &len); if (ret != ASN_PARSE_E) - return -12540; + return -13540; len = testData[i].outSz; ret = wc_BerToDer(testData[i].in, l, out, &len); if (ret != ASN_PARSE_E) - return -12541; + return -13541; } for (l = 0; l < testData[i].outSz-1; l++) { ret = wc_BerToDer(testData[i].in, testData[i].inSz, out, &l); if (ret != BUFFER_E) - return -12542; + return -13542; } } ret = wc_BerToDer(NULL, 4, NULL, NULL); if (ret != BAD_FUNC_ARG) - return -12543; + return -13543; ret = wc_BerToDer(out, 4, NULL, NULL); if (ret != BAD_FUNC_ARG) - return -12544; + return -13544; ret = wc_BerToDer(NULL, 4, NULL, &len); if (ret != BAD_FUNC_ARG) - return -12545; + return -13545; ret = wc_BerToDer(NULL, 4, out, NULL); if (ret != BAD_FUNC_ARG) - return -12546; + return -13546; ret = wc_BerToDer(out, 4, out, NULL); if (ret != BAD_FUNC_ARG) - return -12547; + return -13547; ret = wc_BerToDer(NULL, 4, out, &len); if (ret != BAD_FUNC_ARG) - return -12548; + return -13548; for (l = 1; l < sizeof(good4_out); l++) { len = l; ret = wc_BerToDer(good4_in, sizeof(good4_in), out, &len); if (ret != BUFFER_E) - return -12549; + return -13549; } return 0; @@ -30000,10 +32442,10 @@ static int logging_test(void) b[i] = i; if (wolfSSL_Debugging_ON() != 0) - return -12600; + return -13600; if (wolfSSL_SetLoggingCb(my_Logging_cb) != 0) - return -12601; + return -13601; WOLFSSL_MSG(msg); WOLFSSL_BUFFER(a, sizeof(a)); @@ -30028,7 +32470,7 @@ static int logging_test(void) /* check the logs were disabled */ if (i != log_cnt) - return -12602; + return -13602; /* restore callback and leave logging enabled */ wolfSSL_SetLoggingCb(NULL); @@ -30040,10 +32482,10 @@ static int logging_test(void) #else if (wolfSSL_Debugging_ON() != NOT_COMPILED_IN) - return -12603; + return -13603; wolfSSL_Debugging_OFF(); if (wolfSSL_SetLoggingCb(NULL) != NOT_COMPILED_IN) - return -12604; + return -13604; #endif /* DEBUG_WOLFSSL */ return 0; } @@ -30057,7 +32499,7 @@ static int mutex_test(void) #if !defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_USER_MUTEX) wolfSSL_Mutex *mm = wc_InitAndAllocMutex(); if (mm == NULL) - return -12700; + return -13700; wc_FreeMutex(mm); XFREE(mm, NULL, DYNAMIC_TYPE_MUTEX); #endif @@ -30065,25 +32507,25 @@ static int mutex_test(void) /* Can optionally enable advanced pthread tests using "ENABLE_PTHREAD_LOCKFREE_TESTS" */ #ifdef WOLFSSL_PTHREADS if (wc_InitMutex(&m) != 0) - return -12701; + return -13701; if (wc_LockMutex(&m) != 0) - return -12702; + return -13702; #if !defined(WOLFSSL_SOLARIS) && defined(ENABLE_PTHREAD_LOCKFREE_TESTS) /* trying to free a locked mutex is not portable behavior with pthread */ /* Attempting to destroy a locked mutex results in undefined behavior */ if (wc_FreeMutex(&m) != BAD_MUTEX_E) - return -12703; + return -13703; #endif if (wc_UnLockMutex(&m) != 0) - return -12704; + return -13704; if (wc_FreeMutex(&m) != 0) - return -12705; + return -13705; #if !defined(WOLFSSL_SOLARIS) && defined(ENABLE_PTHREAD_LOCKFREE_TESTS) /* Trying to use a pthread after free'ing is not portable behavior */ if (wc_LockMutex(&m) != BAD_MUTEX_E) - return -12706; + return -13706; if (wc_UnLockMutex(&m) != BAD_MUTEX_E) - return -12707; + return -13707; #endif #endif @@ -30144,13 +32586,13 @@ static int memcb_test(void) /* Save existing memory callbacks */ if (wolfSSL_GetAllocators(&mc, &fc, &rc) != 0) - return -12800; + return -13800; #if !defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_LINUXKM) /* test realloc */ b = (byte*)XREALLOC(b, 1024, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (b == NULL) { - ERROR_OUT(-12801, exit_memcb); + ERROR_OUT(-13801, exit_memcb); } XFREE(b, NULL, DYNAMIC_TYPE_TMP_BUFFER); b = NULL; @@ -30159,7 +32601,7 @@ static int memcb_test(void) if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)(void*)&my_Malloc_cb, (wolfSSL_Free_cb)(void*)&my_Free_cb, (wolfSSL_Realloc_cb)(void*)&my_Realloc_cb) != 0) { - ERROR_OUT(-12802, exit_memcb); + ERROR_OUT(-13802, exit_memcb); } b = (byte*)XMALLOC(1024, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -30171,7 +32613,7 @@ static int memcb_test(void) #else if (malloc_cnt != 0 || free_cnt != 0 || realloc_cnt != 0) #endif - ret = -12803; + ret = -13803; #endif /* !WOLFSSL_NO_MALLOC */ #if !defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_LINUXKM) @@ -30217,45 +32659,45 @@ static int blob_test(void) outSz = sizeof(blob); ret = wc_caamCreateBlob((byte*)iv, sizeof(iv), blob, &outSz); if (ret != 0) { - ERROR_OUT(-12900, exit_blob); + ERROR_OUT(-13900, exit_blob); } blob[outSz - 2] += 1; ret = wc_caamOpenBlob(blob, outSz, out, &outSz); if (ret == 0) { /* should fail with altered blob */ - ERROR_OUT(-12901, exit_blob); + ERROR_OUT(-13901, exit_blob); } XMEMSET(blob, 0, sizeof(blob)); outSz = sizeof(blob); ret = wc_caamCreateBlob((byte*)iv, sizeof(iv), blob, &outSz); if (ret != 0) { - ERROR_OUT(-12902, exit_blob); + ERROR_OUT(-13902, exit_blob); } ret = wc_caamOpenBlob(blob, outSz, out, &outSz); if (ret != 0) { - ERROR_OUT(-12903, exit_blob); + ERROR_OUT(-13903, exit_blob); } if (XMEMCMP(out, iv, sizeof(iv))) { - ERROR_OUT(-12904, exit_blob); + ERROR_OUT(-13904, exit_blob); } XMEMSET(blob, 0, sizeof(blob)); outSz = sizeof(blob); ret = wc_caamCreateBlob((byte*)text, sizeof(text), blob, &outSz); if (ret != 0) { - ERROR_OUT(-12905, exit_blob); + ERROR_OUT(-13905, exit_blob); } ret = wc_caamOpenBlob(blob, outSz, out, &outSz); if (ret != 0) { - ERROR_OUT(-12906, exit_blob); + ERROR_OUT(-13906, exit_blob); } if (XMEMCMP(out, text, sizeof(text))) { - ERROR_OUT(-12907, exit_blob); + ERROR_OUT(-13907, exit_blob); } exit_blob: diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 312954d7c..f8adc57be 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -40,7 +40,7 @@ typedef struct WOLFSSL_BIGNUM { int neg; /* openssh deference */ void *internal; /* our big num */ -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) sp_int fp; #elif defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT) fp_int fp; diff --git a/wolfssl/wolfcrypt/cpuid.h b/wolfssl/wolfcrypt/cpuid.h index 64baedf5f..6e009c4ac 100644 --- a/wolfssl/wolfcrypt/cpuid.h +++ b/wolfssl/wolfcrypt/cpuid.h @@ -60,6 +60,7 @@ WOLFSSL_API void cpuid_select_flags(word32 flags); WOLFSSL_API void cpuid_set_flag(word32 flag); WOLFSSL_API void cpuid_clear_flag(word32 flag); + #endif #ifdef __cplusplus diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 454979f7d..451d871dd 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -33,7 +33,7 @@ may not be faster on all */ #include /* will set MP_xxBIT if not default */ -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #include #elif defined(USE_FAST_MATH) #include @@ -161,7 +161,7 @@ extern "C" { #define MP_OKAY 0 /* ok result */ #define MP_MEM -2 /* out of mem */ #define MP_VAL -3 /* invalid input */ -#define MP_NOT_INF -4 /* point not at infinity */ +#define MP_NOT_INF -4 /* point not at infinity */ #define MP_RANGE MP_NOT_INF #define MP_YES 1 /* yes response */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 6c405794b..a4614f01b 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2137,8 +2137,8 @@ extern void uITRON4_free(void *p) ; #ifndef USE_WOLF_STRTOK #define USE_WOLF_STRTOK #endif - #ifndef WOLFSSL_SP_MOD_WORD_RP - #define WOLFSSL_SP_MOD_WORD_RP + #ifndef WOLFSSL_SP_DIV_WORD_HALF + #define WOLFSSL_SP_DIV_WORD_HALF #endif #ifndef WOLFSSL_OLD_PRIME_CHECK #define WOLFSSL_OLD_PRIME_CHECK @@ -2316,7 +2316,8 @@ extern void uITRON4_free(void *p) ; #if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(WOLFSSL_SHA384) && \ !defined(WOLFSSL_SHA512) && defined(WC_NO_RNG) && \ - defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_RSA_PUBLIC_ONLY) + (defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \ + defined(WOLFSSL_RSA_PUBLIC_ONLY) #undef WOLFSSL_NO_FORCE_ZERO #define WOLFSSL_NO_FORCE_ZERO #endif diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 01c9ed5d0..6cd1cd529 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -28,10 +28,116 @@ This library provides single precision (SP) integer math functions. #define WOLF_CRYPT_SP_INT_H #ifndef WOLFSSL_LINUXKM -#include #include #endif +/* Find smallest type for smallest bits. */ +#if UCHAR_MAX == 255 + #define SP_UCHAR_BITS 8 + + typedef unsigned char sp_uint8; + typedef char sp_int8; +#elif UCHAR_MAX == 127 + #define SP_UCHAR_BITS 7 + + typedef unsigned char sp_uint7; + typedef char sp_int7; +#else + #error "Size of unsigned short not detected" +#endif + +#if USHRT_MAX == 65535 + #define SP_USHORT_BITS 16 + + typedef unsigned short sp_uint16; + typedef short sp_int16; +#elif USHRT_MAX == 255 + #define SP_USHORT_BITS 8 + + #if USHRT_MAX > UCHAR_MAX + typedef unsigned short sp_uint8; + typedef short sp_int8; + #endif +#else + #error "Size of unsigned short not detected" +#endif + +#if UINT_MAX == 4294967295UL + #define SP_UINT_BITS 32 + + typedef unsigned int sp_uint32; + typedef int sp_int32; +#elif UINT_MAX == 65535 + #define SP_UINT_BITS 16 + + #if UINT_MAX > USHRT_MAX + typedef unsigned int sp_uint16; + typedef int sp_int16; + #endif +#elif UINT_MAX == 255 + #define SP_UINT_BITS 8 + + #if UINT_MAX > USHRT_MAX + typedef unsigned int sp_uint8; + typedef int sp_int8; + #endif +#else + #error "Size of unsigned int not detected" +#endif + +#if ULONG_MAX == 18446744073709551615UL + #define SP_ULONG_BITS 64 + + typedef unsigned long sp_uint64; + typedef long sp_int64; +#elif ULONG_MAX == 4294967295UL + #define SP_ULONG_BITS 32 + + #if ULONG_MAX > UINT_MAX + typedef unsigned long sp_uint32; + typedef long sp_int32; + #endif +#elif ULONG_MAX == 65535 + #define SP_ULONG_BITS 16 + + #if ULONG_MAX > UINT_MAX + typedef unsigned long sp_uint16; + typedef long sp_int16; + #endif +#else + #error "Size of unsigned long not detected" +#endif + +#if ULLONG_MAX == 18446744073709551615UL + #define SP_ULLONG_BITS 64 + + #if SP_ULLONG_BITS > SP_ULONG_BITS + typedef unsigned long long sp_uint64; + typedef long long sp_int64; + #endif +#elif ULLONG_MAX == 4294967295UL + #define SP_ULLONG_BITS 32 + + #if SP_ULLONG_BITS > SP_ULONG_BITS + typedef unsigned long long sp_uint32; + typedef long long sp_int32; + #endif +#elif ULLONG_MAX == 65535 + #define SP_ULLONG_BITS 16 + + #if SP_ULLONG_BITS > SP_ULONG_BITS + typedef unsigned long long sp_uint16; + typedef long long sp_int16; + #endif +#else + #error "Size of unsigned long long not detected" +#endif + + +#ifdef WOLFSSL_SP_DIV_32 +#define WOLFSSL_SP_DIV_WORD_HALF +#endif + /* Make sure WOLFSSL_SP_ASM build option defined when requested */ #if !defined(WOLFSSL_SP_ASM) && ( \ defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_ARM32_ASM) || \ @@ -41,19 +147,47 @@ This library provides single precision (SP) integer math functions. #endif -#ifdef WOLFSSL_SP_X86_64_ASM - #define SP_WORD_SIZE 64 - - #define HAVE_INTEL_AVX1 - #define HAVE_INTEL_AVX2 -#elif defined(WOLFSSL_SP_ARM64_ASM) - #define SP_WORD_SIZE 64 -#elif defined(WOLFSSL_SP_ARM32_ASM) +/* Detemine the number of bits to use in each word. */ +#ifdef SP_WORD_SIZE +#elif defined(WOLFSSL_DSP_BUILD) #define SP_WORD_SIZE 32 -#elif defined(WOLFSSL_SP_ARM_THUMB_ASM) +#elif defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_X86_64) + #if SP_ULONG_BITS == 64 + #define SP_WORD_SIZE 64 + #define HAVE_INTEL_AVX1 + #define HAVE_INTEL_AVX2 + #elif SP_ULONG_BITS == 32 + #define SP_WORD_SIZE 32 + #undef WOLFSSL_SP_ASM + #elif SP_ULONG_BITS == 16 + #define SP_WORD_SIZE 16 + #undef WOLFSSL_SP_ASM + #endif +#elif defined(WOLFSSL_SP_ARM64_ASM) || defined(WOLFSSL_SP_ARM64) + #define SP_WORD_SIZE 64 +#elif defined(WOLFSSL_SP_ARM32_ASM) || defined(WOLFSSL_SP_ARM32) #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_ARM_THUMB_ASM) || defined(WOLFSSL_SP_ARM_THUMB) + #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_PPC) + #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_PPC64) + #define SP_WORD_SIZE 64 +#elif defined(WOLFSSL_SP_MIPS) + #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_MIPS64) + #define SP_WORD_SIZE 64 +#elif defined(WOLFSSL_SP_RISCV32) + #define SP_WORD_SIZE 32 +#elif defined(WOLFSSL_SP_RISCV64) + #define SP_WORD_SIZE 64 +#elif defined(WOLFSSL_SP_S390X) + #define SP_WORD_SIZE 64 #endif +/* If no predefined or assembly required size then use maximum available + * with compiler. + */ #ifndef SP_WORD_SIZE #if defined(NO_64BIT) || !defined(HAVE___UINT128_T) #define SP_WORD_SIZE 32 @@ -62,63 +196,103 @@ This library provides single precision (SP) integer math functions. #endif #endif -#ifdef WOLFSSL_DSP_BUILD - typedef int32 sp_digit; - typedef uint32 sp_int_digit; - typedef uint64 sp_int_word; - typedef int64 sp_int_sword; - #undef SP_WORD_SIZE - #define SP_WORD_SIZE 32 -#elif !defined(WOLFSSL_SP_ASM) - #if SP_WORD_SIZE == 32 - typedef int32_t sp_digit; - typedef uint32_t sp_int_digit; - typedef uint64_t sp_int_word; - typedef int64_t sp_int_sword; - #elif SP_WORD_SIZE == 64 - typedef int64_t sp_digit; - typedef uint64_t sp_int_digit; +/* Number of bytes in each word. */ +#define SP_WORD_SIZEOF (SP_WORD_SIZE / 8) + +/* Define the types used. */ +#ifdef HAVE___UINT128_T #ifdef __SIZEOF_INT128__ - typedef __uint128_t uint128_t; - typedef __int128_t int128_t; + typedef __uint128_t sp_uint128; + typedef __int128_t sp_int128; + typedef __uint128_t uint128_t; + typedef __int128_t int128_t; #else - typedef unsigned long uint128_t __attribute__ ((mode(TI))); - typedef long int128_t __attribute__ ((mode(TI))); + typedef unsigned long sp_uint128 __attribute__ ((mode(TI))); + typedef long sp_int128 __attribute__ ((mode(TI))); + typedef unsigned long uint128_t __attribute__ ((mode(TI))); + typedef long int128_t __attribute__ ((mode(TI))); #endif - typedef uint128_t sp_int_word; - typedef int128_t sp_int_sword; - #endif -#else - #if SP_WORD_SIZE == 32 - typedef uint32_t sp_digit; - typedef uint32_t sp_int_digit; - typedef uint64_t sp_int_word; - typedef int64_t sp_int_sword; - #elif SP_WORD_SIZE == 64 - typedef uint64_t sp_digit; - typedef uint64_t sp_int_digit; - #ifdef __SIZEOF_INT128__ - typedef __uint128_t uint128_t; - typedef __int128_t int128_t; - #else - typedef unsigned long uint128_t __attribute__ ((mode(TI))); - typedef long int128_t __attribute__ ((mode(TI))); - #endif - typedef uint128_t sp_int_word; - typedef int128_t sp_int_sword; - #endif #endif -#if SP_WORD_SIZE == 32 - #define SP_MASK ((sp_int_digit)0xffffffffU) +#if SP_WORD_SIZE == 8 + typedef sp_uint8 sp_int_digit; + typedef sp_int8 sp_sint_digit; + typedef sp_uint16 sp_int_word; + typedef sp_int16 sp_int_sword; + + #define SP_MASK 0xffU +#elif SP_WORD_SIZE == 16 + typedef sp_uint16 sp_int_digit; + typedef sp_int16 sp_sint_digit; + typedef sp_uint32 sp_int_word; + typedef sp_int32 sp_int_sword; + + #define SP_MASK 0xffffU +#elif SP_WORD_SIZE == 32 + typedef sp_uint32 sp_int_digit; + typedef sp_int32 sp_sint_digit; + typedef sp_uint64 sp_int_word; + typedef sp_int64 sp_int_sword; + + #define SP_MASK 0xffffffffU #elif SP_WORD_SIZE == 64 - #define SP_MASK ((sp_int_digit)0xffffffffffffffffUL) + typedef sp_uint64 sp_int_digit; + typedef sp_int64 sp_sint_digit; + typedef sp_uint128 sp_int_word; + typedef sp_int128 sp_int_sword; + + #define SP_MASK 0xffffffffffffffffUL #else #error Word size not defined #endif +/* Define an SP digit. */ +#ifndef WOLFSSL_SP_ASM + /* SP C code uses n/m bits and therefore needs a signed type. */ + #if SP_WORD_SIZE == 8 + typedef sp_int8 sp_digit; + #elif SP_WORD_SIZE == 16 + typedef sp_int16 sp_digit; + #elif SP_WORD_SIZE == 32 + typedef sp_int32 sp_digit; + #elif SP_WORD_SIZE == 64 + typedef sp_int64 sp_digit; + #endif +#else + /* SP ASM code uses full size and needs an unsigned type. */ + #if SP_WORD_SIZE == 8 + typedef sp_uint8 sp_digit; + #elif SP_WORD_SIZE == 16 + typedef sp_uint16 sp_digit; + #elif SP_WORD_SIZE == 32 + typedef sp_uint32 sp_digit; + #elif SP_WORD_SIZE == 64 + typedef sp_uint64 sp_digit; + #endif +#endif + +/** Number of bits in a half a word. */ +#define SP_HALF_SIZE (SP_WORD_SIZE / 2) +/** Maximum value that can be held in a half a word. */ +#define SP_HALF_MAX (((sp_digit)1 << SP_HALF_SIZE) - 1) +/** Maximum value that can be held in a word. */ +#define SP_DIGIT_MAX SP_MASK +/* Number of bits to shift to divide by word size. */ +#if SP_WORD_SIZE == 8 + #define SP_WORD_SHIFT 3 +#elif SP_WORD_SIZE == 16 + #define SP_WORD_SHIFT 4 +#elif SP_WORD_SIZE == 32 + #define SP_WORD_SHIFT 5 +#elif SP_WORD_SIZE == 64 + #define SP_WORD_SHIFT 6 +#endif +/* Mask of word size. */ +#define SP_WORD_MASK (SP_WORD_SIZE - 1) + #if defined(WOLFSSL_HAVE_SP_ECC) && defined(WOLFSSL_SP_NONBLOCK) +/* Non-blocking ECC operation context. */ typedef struct sp_ecc_ctx { #ifdef WOLFSSL_SP_384 byte data[48*80]; /* stack data */ @@ -128,184 +302,589 @@ typedef struct sp_ecc_ctx { } sp_ecc_ctx_t; #endif -#ifdef WOLFSSL_SP_MATH +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #include -#if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) - #if !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512) - #define SP_INT_DIGITS ((512 + SP_WORD_SIZE) / SP_WORD_SIZE) - #elif defined(WOLFSSL_SP_384) - #define SP_INT_DIGITS ((384 + SP_WORD_SIZE) / SP_WORD_SIZE) +#ifdef SP_INT_BITS + /* Calculate number of digits to have in an sp_int based maximum size of + * numbers in bits that will be used. + * Double the size to hold multiplication result. + */ + #define SP_INT_DIGITS \ + (((SP_INT_BITS + (SP_WORD_SIZE - 1)) * 2 + SP_WORD_SIZE) / SP_WORD_SIZE) +#endif + +#ifndef SP_INT_DIGITS + /* Calculate number of digits to have in an sp_int based on features + * compiled in. + */ + #if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) && \ + !defined(WOLFSSL_HAVE_SP_ECC) + #if !defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA) + #define SP_INT_DIGITS ((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) + #elif defined(HAVE_ECC) + #define SP_INT_DIGITS \ + ((2 * ( 521 + SP_WORD_SIZE) + SP_WORD_SIZE) / SP_WORD_SIZE) + #elif !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512) + #define SP_INT_DIGITS (( 512 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS (( 256 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif + #elif !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) + #if !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512) + #define SP_INT_DIGITS (( 512 + SP_WORD_SIZE) / SP_WORD_SIZE) + #elif defined(WOLFSSL_SP_384) + #define SP_INT_DIGITS (( 768 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS (( 512 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif + #elif defined(WOLFSSL_SP_4096) + #if defined(WOLFSSL_HAVE_SP_DH) + #define SP_INT_DIGITS ((8192 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif + #elif !defined(WOLFSSL_SP_NO_3072) + #if defined(WOLFSSL_HAVE_SP_DH) + #define SP_INT_DIGITS ((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((3072 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif #else - #define SP_INT_DIGITS ((256 + SP_WORD_SIZE) / SP_WORD_SIZE) - #endif -#elif defined(WOLFSSL_SP_4096) - #if defined(WOLFSSL_HAVE_SP_DH) - #define SP_INT_DIGITS ((8192 + SP_WORD_SIZE) / SP_WORD_SIZE) - #else - #define SP_INT_DIGITS ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE) - #endif -#elif !defined(WOLFSSL_SP_NO_3072) - #if defined(WOLFSSL_HAVE_SP_DH) - #define SP_INT_DIGITS ((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) - #else - #define SP_INT_DIGITS ((3072 + SP_WORD_SIZE) / SP_WORD_SIZE) - #endif -#else - #if defined(WOLFSSL_HAVE_SP_DH) - #define SP_INT_DIGITS ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE) - #else - #define SP_INT_DIGITS ((2048 + SP_WORD_SIZE) / SP_WORD_SIZE) + #if defined(WOLFSSL_HAVE_SP_DH) + #define SP_INT_DIGITS ((4096 + SP_WORD_SIZE) / SP_WORD_SIZE) + #else + #define SP_INT_DIGITS ((2048 + SP_WORD_SIZE) / SP_WORD_SIZE) + #endif #endif #endif -#define sp_isodd(a) ((a)->used != 0 && ((a)->dp[0] & 1)) -#define sp_iseven(a) ((a)->used != 0 && ((a)->dp[0] & 1) == 0) -#define sp_iszero(a) ((a)->used == 0) -#define sp_isone(a) ((a)->used == 1 && (a)->dp[0] == 1) -#define sp_abs(a, b) sp_copy(a, b) +#ifndef SP_INT_MAX_BITS + /* Convert number digits to number of bits. */ + #define SP_INT_MAX_BITS (SP_INT_DIGITS * SP_WORD_SIZE) +#endif + + +/* For debugging only - format string for different digit sizes. */ +#if SP_WORD_SIZE == 64 + #if SP_ULONG_BITS == 64 + #define SP_PRINT_FMT "%016lx" + #else + #define SP_PRINT_FMT "%016llx" + #endif +#elif SP_WORD_SIZE == 32 + #if SP_UINT_BITS == 32 + #define SP_PRINT_FMT "%08x" + #else + #define SP_PRINT_FMT "%08lx" + #endif +#elif SP_WORD_SIZE == 16 + #define SP_PRINT_FMT "%04x" +#elif SP_WORD_SIZE == 8 + #define SP_PRINT_FMT "%02x" +#endif + +#ifndef NO_FILESYSTEM +/* Output is formatted to be used with script that checks calculations. */ + +/* Print out a number in big endian. */ +#ifndef WOLFSSL_SP_INT_NEGATIVE +/* Print out a positive multi-precision number. + * + * @param [in] a SP integer to print. + * @param [in] s String that describes the use of the number. + */ +#define sp_print(a, s) \ + do { \ + int ii; \ + fprintf(stderr, "%s=0x0", s); \ + for (ii = (a)->used-1; ii >= 0; ii--) { \ + fprintf(stderr, SP_PRINT_FMT, (a)->dp[ii]); \ + } \ + fprintf(stderr, "\n"); \ + } \ + while (0) +#else +/* Print out a multi-precision number. + * + * @param [in] a SP integer to print. + * @param [in] s String that describes the use of the number. + */ +#define sp_print(a, s) \ + do { \ + int ii; \ + fprintf(stderr, "%s=0x", s); \ + if ((a)->sign == MP_NEG) { \ + fprintf(stderr, "-"); \ + } \ + fprintf(stderr, "0"); \ + for (ii = (a)->used-1; ii >= 0; ii--) { \ + fprintf(stderr, SP_PRINT_FMT, (a)->dp[ii]); \ + } \ + fprintf(stderr, "\n"); \ + } \ + while (0) +#endif + +/* Print out a single multi-precision digit. + * + * @param [in] a SP integer digit to print. + * @param [in] s String that describes the use of the number. + */ +#define sp_print_digit(a, s) \ + do { \ + fprintf(stderr, "%s=0x0", s); \ + fprintf(stderr, SP_PRINT_FMT, a); \ + fprintf(stderr, "\n"); \ + } \ + while (0) + +/* Print out an integer. + * + * @param [in] a Number to print. + * @param [in] s String that describes the use of the number. + */ +#define sp_print_int(a, s) \ + do { \ + fprintf(stderr, "%s=0x0%x\n", s, a); \ + } \ + while (0) + +#else + + /* No filesystem, no output + * TODO: Use logging API? + */ + #define sp_print(a, s) + #define sp_print_digit(a, s) + #define sp_print_int(a, s) + +#endif + +/* Returns whether multi-precision number is odd + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to check. + * @return 1 when odd. + * @return 0 when even. + */ +#define sp_isodd(a) (((a)->used != 0) && ((a)->dp[0] & 1)) +/* Returns whether multi-precision number is even + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to check. + * @return 1 when even. + * @return 0 when odd. + */ +#define sp_iseven(a) (((a)->used != 0) && (((a)->dp[0] & 1) == 0)) +/* Returns whether multi-precision number has the value zero. + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to check. + * @return 1 when zero. + * @return 0 when not zero. + */ +#define sp_iszero(a) ((a)->used == 0) +/* Returns whether multi-precision number has the value one. + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to check. + * @return 1 when one. + * @return 0 when not one. + */ +#define sp_isone(a) (((a)->used == 1) && ((a)->dp[0] == 1)) +/* Returns whether multi-precision number has the value 'd'. + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to check. + * @param [in] d SP integer digit. + * @return 1 when one. + * @return 0 when not one. + */ +#define sp_isword(a, d) (((a)->used == 1) && ((a)->dp[0] == d)) +#ifndef WOLFSSL_SP_INT_NEGATIVE +/* Calculate the absolute value of the multi-precision number. + * + * Negative support not compiled in so just copies. + * + * @param [in] a SP integer to calculate absolute value of. + * @param [out] r SP integer to hold result. + * + * @return MP_OKAY on success. + * @return MP_VAL when a or r is NULL. + */ +#define sp_abs(a, b) sp_copy(a, b) +/* Returns whether multi-precision number is negative. + * + * Negative support not compiled in so always returns 0 (false). + * + * @param [in] a SP integer to check. + * @param [in] d SP integer digit. + * @return 0 indicating not negative always. + */ +#define sp_isneg(a) (0) +#else +/* Returns whether multi-precision number is negative. + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to check. + * @param [in] d SP integer digit. + * @return 1 when negative. + * @return 0 when not negative. + */ +#define sp_isneg(a) ((a)->sign == MP_NEG) +#endif +/* Updates the used count to exclude leading zeros. + * + * Assumes a is not NULL. + * + * @param [in] a SP integer to update. + */ +#define sp_clamp(a) \ + do { \ + int ii; \ + for (ii = a->used - 1; ii >= 0 && a->dp[ii] == 0; ii--) { \ + } \ + a->used = ii + 1; \ + } while (0) +/* Get the count of digits in the multi-precision number. + * + * @param [in] a SP integer to use. + */ +#define sp_get_digit_count(a) (((a) == NULL) ? 0 : ((sp_int*)(a))->used) + +/* Check the compiled and linked math implementation are the same. + * Use the number of bits in a digit as indication of how code was compiled. + * + * @return 1 when the number of bits are the same. + * @return 0 when the number of bits are differnt. + */ +#define CheckFastMathSettings() (SP_WORD_SIZE == CheckRunTimeFastMath()) + + +#ifdef WOLFSSL_SP_INT_NEGATIVE + #ifdef HAVE_WOLF_BIGINT + #define SP_INT_EXTRA_OVERHEAD sizeof(int) + sizeof(struct WC_BIGINT) + #else + #define SP_INT_EXTRA_OVERHEAD sizeof(int) + #endif +#elif defined(HAVE_WOLF_BIGINT) + #define SP_INT_EXTRA_OVERHEAD sizeof(struct WC_BIGINT) +#else + #define SP_INT_EXTRA_OVERHEAD 0 +#endif +#define WOLFSSL_SP_INT_OVERHEAD \ + (sizeof(int) + sizeof(int) + SP_INT_EXTRA_OVERHEAD) + +#define MP_INT_SIZEOF(cnt) \ + (WOLFSSL_SP_INT_OVERHEAD + ((cnt) * SP_WORD_SIZEOF)) + + +/** + * A reuslt of NO. + * e.g. Is prime? NO. + */ +#define MP_NO 0 +/** + * A reuslt of YES. + * e.g. Is prime? YES. + */ +#define MP_YES 1 + +#ifdef WOLFSSL_SP_INT_NEGATIVE +/** Number is 0/positive. */ +#define MP_ZPOS 0 +/** Number is negative. */ +#define MP_NEG 1 +#endif + +/** Radix is base 10 or decimal. */ +#define MP_RADIX_DEC 10 +/** Radix is base 16 or hexadecimal. */ +#define MP_RADIX_HEX 16 + +/** Result of comparison is that the first number is greater than second. */ +#define MP_GT 1 +/** Result of comparison is they are equal. */ +#define MP_EQ 0 +/** Result of comparison is that the first number is less than second. */ +#define MP_LT -1 + +/** Error value on success. */ +#define MP_OKAY 0 +/** Error value when dynamic memory allocation fails. */ +#define MP_MEM -2 +/** Error value when value passed is not able to be used. */ +#define MP_VAL -3 +/** Error value when non-blocking operation is returning after partial + * completion. + */ +#define FP_WOULDBLOCK -4 + +/* Number of bits in each word/digit. */ +#define DIGIT_BIT SP_WORD_SIZE +/* Mask of all used bits in word/digit. */ +#define MP_MASK SP_MASK + #ifdef HAVE_WOLF_BIGINT - /* raw big integer */ + /* Raw big integer as a big-endian byte array. + * + * Useful for when using hardware - canonical format. + */ typedef struct WC_BIGINT { + /* Dynamically allocated buffer that is big-endian byte array. */ byte* buf; + /* Length of buffer in bytes. */ word32 len; + /* Hint for heap used to allocate buffer. */ void* heap; } WC_BIGINT; + + /* Ensure WC_BIGINT defined once. */ #define WOLF_BIGINT_DEFINED #endif + +/** + * SP integer. + * + * dp at end so user can allocate a smaller amount and set size. + */ typedef struct sp_int { + /** Number of words that contain data. */ int used; + /** Maximum number of words in data. */ int size; - sp_int_digit dp[SP_INT_DIGITS]; -#ifdef HAVE_WOLF_BIGINT - struct WC_BIGINT raw; /* unsigned binary (big endian) */ +#ifdef WOLFSSL_SP_INT_NEGATIVE + /** Indicates whether number is 0/positive or negative. */ + int sign; #endif +#ifdef HAVE_WOLF_BIGINT + /** Unsigned binary (big endian) representation of number. */ + struct WC_BIGINT raw; +#endif + /** Data of number. */ + sp_int_digit dp[SP_INT_DIGITS]; } sp_int; +/* Mulit-precision integer type is SP integer type. */ typedef sp_int mp_int; +/* Mulit-precision integer digit type is SP integer digit type. + * Type is unsigned. + */ typedef sp_int_digit mp_digit; + +/* Include the maths operations that are not implementation specific. */ #include +/* + * Function prototypes. + */ MP_API int sp_init(sp_int* a); -MP_API int sp_init_multi(sp_int* a, sp_int* b, sp_int* c, sp_int* d, - sp_int* e, sp_int* f); +MP_API int sp_init_size(sp_int* a, int size); +MP_API int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, + sp_int* n5, sp_int* n6); MP_API void sp_free(sp_int* a); -MP_API void sp_clear(sp_int* a); -MP_API int sp_unsigned_bin_size(sp_int* a); -MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz); -MP_API int sp_read_radix(sp_int* a, const char* in, int radix); -MP_API int sp_cmp(sp_int* a, sp_int* b); -MP_API int sp_count_bits(sp_int* a); -MP_API int sp_leading_bit(sp_int* a); -MP_API int sp_to_unsigned_bin(sp_int* a, byte* out); -MP_API int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz); -MP_API void sp_forcezero(sp_int* a); -MP_API int sp_copy(sp_int* a, sp_int* r); -MP_API int sp_set(sp_int* a, sp_int_digit d); -MP_API void sp_clamp(sp_int* a); MP_API int sp_grow(sp_int* a, int l); -MP_API int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r); -MP_API int sp_cmp_d(sp_int* a, sp_int_digit d); -MP_API int sp_sub(sp_int* a, sp_int* b, sp_int* r); -MP_API int sp_mod(sp_int* a, sp_int* m, sp_int* r); + MP_API void sp_zero(sp_int* a); -MP_API int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r); -MP_API int sp_lshd(sp_int* a, int s); -MP_API int sp_add(sp_int* a, sp_int* b, sp_int* r); -MP_API int sp_set_int(sp_int* a, unsigned long b); -MP_API int sp_tohex(sp_int* a, char* str); +MP_API void sp_clear(sp_int* a); +MP_API void sp_forcezero(sp_int* a); +MP_API int sp_init_copy (sp_int* r, sp_int* a); + +MP_API int sp_copy(sp_int* a, sp_int* r); +MP_API int sp_exch(sp_int* a, sp_int* b); +MP_API int sp_cond_swap_ct(mp_int * a, mp_int * b, int c, int m); + +#ifdef WOLFSSL_SP_INT_NEGATIVE +MP_API int sp_abs(sp_int* a, sp_int* b); +#endif +MP_API int sp_cmp_mag(sp_int* a, sp_int* b); +MP_API int sp_cmp(sp_int* a, sp_int* b); + +MP_API int sp_is_bit_set(sp_int* a, unsigned int b); +MP_API int sp_count_bits(sp_int* a); +#if defined(HAVE_ECC) && defined(HAVE_COMP_KEY) +MP_API int sp_cnt_lsb(sp_int* a); +#endif +MP_API int sp_leading_bit(sp_int* a); MP_API int sp_set_bit(sp_int* a, int i); MP_API int sp_2expt(sp_int* a, int e); -MP_API int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap); + +MP_API int sp_set(sp_int* a, sp_int_digit d); +MP_API int sp_set_int(sp_int* a, unsigned long n); +MP_API int sp_cmp_d(sp_int* a, sp_int_digit d); +MP_API int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r); +MP_API int sp_sub_d(sp_int* a, sp_int_digit d, sp_int* r); +MP_API int sp_mul_d(sp_int* a, sp_int_digit d, sp_int* r); +MP_API int sp_div_d(sp_int* a, sp_int_digit d, sp_int* r, sp_int_digit* rem); +#if defined(WOLFSSL_SP_MATH_ALL) || (defined(HAVE_ECC) && \ + defined(HAVE_COMP_KEY)) +MP_API int sp_mod_d(sp_int* a, const sp_int_digit d, sp_int_digit* r); +#endif +MP_API int sp_div_2_mod_ct (sp_int* a, sp_int* b, sp_int* c); +#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) +MP_API int sp_div_2(sp_int* a, sp_int* r); +#endif + +MP_API int sp_add(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_sub(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_addmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); +MP_API int sp_submod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); +MP_API int sp_submod_ct (sp_int* a, sp_int* b, sp_int* c, sp_int* d); +MP_API int sp_addmod_ct (sp_int* a, sp_int* b, sp_int* c, sp_int* d); + +MP_API int sp_lshd(sp_int* a, int s); +MP_API void sp_rshd(sp_int* a, int c); +MP_API void sp_rshb(sp_int* a, int n, sp_int* r); + +#ifdef WOLFSSL_SP_MATH_ALL +MP_API int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem); +#endif +MP_API int sp_mod(sp_int* a, sp_int* m, sp_int* r); + MP_API int sp_mul(sp_int* a, sp_int* b, sp_int* r); MP_API int sp_mulmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); -MP_API int sp_gcd(sp_int* a, sp_int* b, sp_int* r); + MP_API int sp_invmod(sp_int* a, sp_int* m, sp_int* r); -MP_API int sp_lcm(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_invmod_mont_ct(sp_int* a, sp_int* m, sp_int* r, sp_int_digit mp); + +MP_API int sp_exptmod_ex(sp_int* b, sp_int* e, int digits, sp_int* m, + sp_int* r); MP_API int sp_exptmod(sp_int* b, sp_int* e, sp_int* m, sp_int* r); +MP_API int sp_exptmod_nct(sp_int* b, sp_int* e, sp_int* m, sp_int* r); + +MP_API int sp_div_2d(sp_int* a, int e, sp_int* r, sp_int* rem); +MP_API int sp_mod_2d(sp_int* a, int e, sp_int* r); +MP_API int sp_mul_2d(sp_int* a, int e, sp_int* r); + +MP_API int sp_sqr(sp_int* a, sp_int* r); +MP_API int sp_sqrmod(sp_int* a, sp_int* m, sp_int* r); + +MP_API int sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp); +MP_API int sp_mont_setup(sp_int* m, sp_int_digit* rho); +MP_API int sp_mont_norm(sp_int* norm, sp_int* m); + +MP_API int sp_unsigned_bin_size(sp_int* a); +MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz); +MP_API int sp_to_unsigned_bin(sp_int* a, byte* out); +MP_API int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz); +MP_API int sp_to_unsigned_bin_at_pos(int o, sp_int* a, unsigned char* out); + +MP_API int sp_read_radix(sp_int* a, const char* in, int radix); +MP_API int sp_tohex(sp_int* a, char* str); +MP_API int sp_todecimal(mp_int* a, char* str); +MP_API int sp_toradix(mp_int* a, char* str, int radix); +MP_API int sp_radix_size(mp_int* a, int radix, int* size); + +MP_API int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap); MP_API int sp_prime_is_prime(mp_int* a, int t, int* result); MP_API int sp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng); -MP_API int sp_exch(sp_int* a, sp_int* b); -MP_API int sp_get_digit_count(sp_int *a); -MP_API int sp_init_copy (sp_int * a, sp_int * b); -MP_API void sp_rshb(sp_int* a, int n, sp_int* r); -MP_API int sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r); +MP_API int sp_gcd(sp_int* a, sp_int* b, sp_int* r); +MP_API int sp_lcm(sp_int* a, sp_int* b, sp_int* r); + +WOLFSSL_API word32 CheckRunTimeFastMath(void); -#define MP_NO 0 -#define MP_YES 1 +/* Map mp functions to SP math versions. */ +/* Different name or signature. */ +#define mp_mul_2(a, r) sp_mul_2d(a, 1, r) +#define mp_div_3(a, r, rem) sp_div_d(a, 3, r, rem) +#define mp_rshb(A,x) sp_rshb(A,x,A) +#define mp_is_bit_set(a,b) sp_is_bit_set(a,(unsigned int)b) +#define mp_montgomery_reduce sp_mont_red +#define mp_montgomery_setup sp_mont_setup +#define mp_montgomery_calc_normalization sp_mont_norm -#define MP_RADIX_HEX 16 +/* Macros mappings. */ +#define mp_isodd sp_isodd +#define mp_iseven sp_iseven +#define mp_iszero sp_iszero +#define mp_isone sp_isone +#define mp_isword sp_isword +#define mp_abs sp_abs +#define mp_isneg sp_isneg +#define mp_clamp sp_clamp +#define get_digit_count sp_get_digit_count -#define MP_GT 1 -#define MP_EQ 0 -#define MP_LT -1 +/* One to one mappings. */ +#define mp_init sp_init +#define mp_init_size sp_init_size +#define mp_init_multi sp_init_multi +#define mp_free sp_free +#define mp_grow sp_grow +#define mp_zero sp_zero +#define mp_clear sp_clear +#define mp_forcezero sp_forcezero +#define mp_copy sp_copy +#define mp_init_copy sp_init_copy +#define mp_exch sp_exch +#define mp_cond_swap_ct sp_cond_swap_ct +#define mp_cmp_mag sp_cmp_mag +#define mp_cmp sp_cmp +#define mp_count_bits sp_count_bits +#define mp_cnt_lsb sp_cnt_lsb +#define mp_leading_bit sp_leading_bit +#define mp_set_bit sp_set_bit +#define mp_2expt sp_2expt +#define mp_set sp_set +#define mp_set_int sp_set_int +#define mp_cmp_d sp_cmp_d +#define mp_add_d sp_add_d +#define mp_sub_d sp_sub_d +#define mp_mul_d sp_mul_d +#define mp_div_d sp_div_d +#define mp_mod_d sp_mod_d +#define mp_div_2_mod_ct sp_div_2_mod_ct +#define mp_div_2 sp_div_2 +#define mp_add sp_add +#define mp_sub sp_sub +#define mp_addmod sp_addmod +#define mp_submod sp_submod +#define mp_addmod_ct sp_addmod_ct +#define mp_submod_ct sp_submod_ct +#define mp_lshd sp_lshd +#define mp_rshd sp_rshd +#define mp_div sp_div +#define mp_mod sp_mod +#define mp_mul sp_mul +#define mp_mulmod sp_mulmod +#define mp_invmod sp_invmod +#define mp_invmod_mont_ct sp_invmod_mont_ct +#define mp_exptmod_ex sp_exptmod_ex +#define mp_exptmod sp_exptmod +#define mp_exptmod_nct sp_exptmod_nct +#define mp_div_2d sp_div_2d +#define mp_mod_2d sp_mod_2d +#define mp_mul_2d sp_mul_2d +#define mp_sqr sp_sqr +#define mp_sqrmod sp_sqrmod -#define MP_OKAY 0 -#define MP_MEM -2 -#define MP_VAL -3 -#define FP_WOULDBLOCK -4 +#define mp_unsigned_bin_size sp_unsigned_bin_size +#define mp_read_unsigned_bin sp_read_unsigned_bin +#define mp_to_unsigned_bin sp_to_unsigned_bin +#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len +#define mp_to_unsigned_bin_at_pos sp_to_unsigned_bin_at_pos +#define mp_read_radix sp_read_radix +#define mp_tohex sp_tohex +#define mp_todecimal sp_todecimal +#define mp_toradix sp_toradix +#define mp_radix_size sp_radix_size -#define DIGIT_BIT SP_WORD_SIZE -#define MP_MASK SP_MASK - -#define CheckFastMathSettings() 1 - -#define mp_free sp_free - -#define mp_isodd sp_isodd -#define mp_iseven sp_iseven -#define mp_iszero sp_iszero -#define mp_isone sp_isone -#define mp_abs sp_abs - -#define mp_init sp_init -#define mp_init_multi sp_init_multi -#define mp_clear sp_clear -#define mp_read_unsigned_bin sp_read_unsigned_bin -#define mp_unsigned_bin_size sp_unsigned_bin_size -#define mp_read_radix sp_read_radix -#define mp_cmp sp_cmp -#define mp_count_bits sp_count_bits -#define mp_leading_bit sp_leading_bit -#define mp_to_unsigned_bin sp_to_unsigned_bin -#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len -#define mp_forcezero sp_forcezero -#define mp_copy sp_copy -#define mp_set sp_set -#define mp_clamp sp_clamp -#define mp_grow sp_grow -#define mp_sub_d sp_sub_d -#define mp_cmp_d sp_cmp_d -#define mp_sub sp_sub -#define mp_mod sp_mod -#define mp_zero sp_zero -#define mp_add_d sp_add_d -#define mp_lshd sp_lshd -#define mp_add sp_add -#define mp_set_int sp_set_int -#define mp_tohex sp_tohex -#define mp_set_bit sp_set_bit -#define mp_2expt sp_2expt -#define mp_rand_prime sp_rand_prime -#define mp_mul sp_mul -#define mp_mulmod sp_mulmod -#define mp_gcd sp_gcd -#define mp_invmod sp_invmod -#define mp_lcm sp_lcm -#define mp_exptmod sp_exptmod -#define mp_exptmod_nct sp_exptmod -#define mp_prime_is_prime sp_prime_is_prime -#define mp_prime_is_prime_ex sp_prime_is_prime_ex -#define mp_exch sp_exch -#define get_digit_count sp_get_digit_count -#define mp_init_copy sp_init_copy -#define mp_rshb(A,x) sp_rshb(A,x,A) -#define mp_mul_d sp_mul_d +#define mp_rand_prime sp_rand_prime +#define mp_prime_is_prime sp_prime_is_prime +#define mp_prime_is_prime_ex sp_prime_is_prime_ex +#define mp_gcd sp_gcd +#define mp_lcm sp_lcm #endif