diff --git a/configure.ac b/configure.ac index 940f4cf9f..5749a35de 100644 --- a/configure.ac +++ b/configure.ac @@ -7608,6 +7608,12 @@ case $host_os in fi ;; esac +if test "$enable_shared" = "no"; then + if test "$enable_static" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TEST_STATIC_BUILD" + fi +fi + if test "x$ENABLED_LINUXKM" = "xyes"; then AX_SIMD_CC_COMPILER_FLAGS AC_SUBST([CFLAGS_FPU_DISABLE]) diff --git a/src/pk.c b/src/pk.c index 04070ec70..59350e8aa 100644 --- a/src/pk.c +++ b/src/pk.c @@ -33,63 +33,297 @@ /******************************************************************************* * COMMON FUNCTIONS ******************************************************************************/ -#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) -#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + +#if defined(OPENSSL_EXTRA) + +#if !defined(NO_CERTS) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA) || \ defined(HAVE_ECC)) /* Print the number bn in hex with name field and indentation indent to file fp. - * Used by wolfSSL_DSA_print_fp and wolfSSL_RSA_print_fp to print DSA and RSA - * keys and parameters. + * + * Used by wolfSSL_DSA_print_fp, wolfSSL_RSA_print_fp and + * wolfSSL_EC_KEY_print_fp to print DSA, RSA and ECC keys and parameters. + * + * @param [in] fp File pointer to write to. + * @param [in] indent Number of spaces to prepend to each line. + * @param [in] field Name of field. + * @param [in] bn Big number to print. + * @return 1 on success. + * @return 0 on failure. + * @return BAD_FUNC_ARG when fp is invalid, indent is less than 0, or field or + * bn or NULL. */ -static int PrintBNFieldFp(XFILE fp, int indent, const char* field, - const WOLFSSL_BIGNUM* bn) +static int pk_bn_field_print_fp(XFILE fp, int indent, const char* field, + const WOLFSSL_BIGNUM* bn) { static const int HEX_INDENT = 4; static const int MAX_DIGITS_PER_LINE = 30; - int ret = WOLFSSL_SUCCESS; + int ret = 1; int i = 0; char* buf = NULL; - if (fp == XBADFILE || indent < 0 || field == NULL || bn == NULL) { - ret = BAD_FUNC_ARG; - } + /* Internal function - assume parameters are valid. */ - if (ret == WOLFSSL_SUCCESS) { - buf = wolfSSL_BN_bn2hex(bn); - if (buf == NULL) { - ret = WOLFSSL_FAILURE; - } + /* Convert BN to hexadecimal character array (allocates buffer). */ + buf = wolfSSL_BN_bn2hex(bn); + if (buf == NULL) { + ret = 0; } - if (ret == WOLFSSL_SUCCESS) { - XFPRINTF(fp, "%*s", indent, ""); + if (ret == 1) { + /* Print leading spaces, name and spaces before data. */ + if (indent > 0) { + XFPRINTF(fp, "%*s", indent, ""); + } XFPRINTF(fp, "%s:\n", field); - XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); - while (buf[i]) { - if (i != 0) { - if (i % 2 == 0) { - XFPRINTF(fp, ":"); - } - if (i % MAX_DIGITS_PER_LINE == 0) { - XFPRINTF(fp, "\n"); - XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); - } - } + if (indent > 0) { + XFPRINTF(fp, "%*s", indent, ""); + } + XFPRINTF(fp, "%*s", HEX_INDENT, ""); + + /* Print first byte - should always exist. */ + if ((buf[i] != '\0') && (buf[i+1] != '\0')) { + XFPRINTF(fp, "%c", buf[i++]); XFPRINTF(fp, "%c", buf[i++]); } + /* Print each hexadecimal character with byte separator. */ + while ((buf[i] != '\0') && (buf[i+1] != '\0')) { + /* Byte separator every two nibbles - one byte. */ + XFPRINTF(fp, ":"); + /* New line after every 15 bytes - 30 nibbles. */ + if (i % MAX_DIGITS_PER_LINE == 0) { + XFPRINTF(fp, "\n"); + if (indent > 0) { + XFPRINTF(fp, "%*s", indent, ""); + } + XFPRINTF(fp, "%*s", HEX_INDENT, ""); + } + /* Print two nibbles - one byte. */ + XFPRINTF(fp, "%c", buf[i++]); + XFPRINTF(fp, "%c", buf[i++]); + } + /* Ensure on new line after data. */ XFPRINTF(fp, "\n"); } - if (buf != NULL) { - XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL); + /* Dispose of any allocated character array. */ + XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL); + + return ret; +} +#endif /* !NO_CERTS && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && + * (!NO_DSA || !NO_RSA || HAVE_ECC) */ + +#if defined(XSNPRINTF) && !defined(NO_BIO) && !defined(NO_RSA) && \ + !defined(HAVE_FAST_RSA) +/* snprintf() must be available */ + +/* Maximum number of extra indent spaces on each line. */ +#define PRINT_NUM_MAX_INDENT 48 +/* Maximum size of a line containing a value. */ +#define PRINT_NUM_MAX_VALUE_LINE PRINT_NUM_MAX_INDENT +/* Number of leading spaces on each line. */ +#define PRINT_NUM_INDENT_CNT 4 +/* Indent spaces for number lines. */ +#define PRINT_NUM_INDENT " " +/* 4 leading spaces and 15 bytes with colons is a complete line. */ +#define PRINT_NUM_MAX_DIGIT_LINE (PRINT_NUM_INDENT_CNT + 3 * 15) + +/* Print indent to BIO. + * + * @param [in] bio BIO object to write to. + * @param [in] line Buffer to put characters to before writing to BIO. + * @param [in] lineLen Length of buffer. + * @ereturn 1 on success. + * @ereturn 0 on failure. + */ +static int wolfssl_print_indent(WOLFSSL_BIO* bio, char* line, int lineLen, + int indent) +{ + int ret = 1; + + if (indent > 0) { + /* Print indent spaces. */ + lineLen = (int)XSNPRINTF(line, lineLen - 1, "%*s", indent, " "); + /* Write indents string to BIO */ + if (wolfSSL_BIO_write(bio, line, lineLen) <= 0) { + ret = 0; + } } return ret; } -#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && (!NO_DSA || - !NO_RSA || HAVE_ECC)*/ -#endif /* !NO_CERTS && OPENSSL_EXTRA */ +/* Print out name, and value in decimal and hex to BIO. + * + * @param [in] bio BIO object to write to. + * @param [in] value MP integer to write. + * @param [in] name Name of value. + * @param [in] indent Number of leading spaces before line. + * @return 1 on success. + * @return 0 on failure. + */ +static int wolfssl_print_value(WOLFSSL_BIO* bio, mp_int* value, + const char* name, int indent) +{ + int ret = 1; + int len; + char line[PRINT_NUM_MAX_VALUE_LINE + 1]; + word32 v; + + /* Get the length of hex encoded value. */ + len = mp_unsigned_bin_size(value); + /* Value must no more than 32-bits - 4 bytes. */ + if ((len < 0) || (len > 4)) { + WOLFSSL_MSG("Error getting exponent size"); + ret = 0; + } + if (ret == 1) { + /* Print any indent spaces. */ + ret = wolfssl_print_indent(bio, line, sizeof(line), indent); + } + if (ret == 1) { + /* Get 32-bits of value. */ + v = (word32)value->dp[0]; + /* Print the line to the string. */ + len = (int)XSNPRINTF(line, sizeof(line) - 1, "%s %u (0x%x)\n", name, v, + v); + /* Write string to BIO */ + if (wolfSSL_BIO_write(bio, line, len) <= 0) { + ret = 0; + } + } + + return ret; +} + +/* Print out name and multi-precision number to BIO. + * + * @param [in] bio BIO object to write to. + * @param [in] num MP integer to write. + * @param [in] name Name of value. + * @param [in] indent Number of leading spaces before each line. + * @return 1 on success. + * @return 0 on failure. + */ +static int wolfssl_print_number(WOLFSSL_BIO* bio, mp_int* num, const char* name, + int indent) +{ + int ret = 1; + int rawLen = 0; + byte* rawKey = NULL; + char line[PRINT_NUM_MAX_DIGIT_LINE + 1]; + int li = 0; /* Line index. */ + int i; + + /* Allocate a buffer to hold binary encoded data. */ + rawLen = mp_unsigned_bin_size(num); + if (rawLen == 0) { + WOLFSSL_MSG("Invalid number"); + ret = 0; + } + if (ret == 1) { + rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rawKey == NULL) { + WOLFSSL_MSG("Memory error"); + ret = 0; + } + } + /* Encode number as big-endian byte array. */ + if ((ret == 1) && (mp_to_unsigned_bin(num, rawKey) < 0)) { + ret = 0; + } + + if (ret == 1) { + /* Print any indent spaces. */ + ret = wolfssl_print_indent(bio, line, sizeof(line), indent); + } + if (ret == 1) { + /* Print header string line to string. */ + li = XSNPRINTF(line, sizeof(line) - 1, "%s\n", name); + if (wolfSSL_BIO_write(bio, line, li) <= 0) { + ret = 0; + } + } + if (ret == 1) { + /* Print any indent spaces. */ + ret = wolfssl_print_indent(bio, line, sizeof(line), indent); + } + if (ret == 1) { + /* Start first digit line with spaces. + * Writing out zeros ensures number is a positive value. */ + li = XSNPRINTF(line, sizeof(line) - 1, PRINT_NUM_INDENT "%s", + mp_leading_bit(num) ? "00:" : ""); + } + + /* Put out each line of numbers. */ + for (i = 0; (ret == 1) && (i < rawLen); i++) { + /* Check for a complete line. */ + if (li >= PRINT_NUM_MAX_DIGIT_LINE) { + /* More bytes coming so append carriage return. */ + line[li++] = '\n'; + /* Write out the line. */ + if (wolfSSL_BIO_write(bio, line, li) <= 0) { + ret = 0; + } + if (ret == 1) { + /* Print any indent spaces. */ + ret = wolfssl_print_indent(bio, line, sizeof(line), indent); + } + /* Put the leading spaces on new line. */ + XSTRNCPY(line, PRINT_NUM_INDENT, PRINT_NUM_INDENT_CNT + 1); + li = PRINT_NUM_INDENT_CNT; + } + /* Encode another byte as 2 hex digits and append colon. */ + li += XSNPRINTF(line + li, sizeof(line) - 1 - li, "%02x:", rawKey[i]); + } + + if (ret == 1) { + /* Put out last line - replace last colon with carriage return. */ + line[li-1] = '\n'; + if (wolfSSL_BIO_write(bio, line, li) <= 0) { + ret = 0; + } + } + + /* Dispose of any allocated data. */ + XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; +} + +#endif /* XSNPRINTF && !NO_BIO && !NO_RSA && !HAVE_FAST_RSA */ + +#ifndef NO_RSA + +/* Uses the DER SEQUENCE to determine size of DER data. + * + * Outer SEQUENCE encapsulates all the DER encoding. + * Add the length of the SEQUENCE data to the length of the SEQUENCE header. + * + * @param [in] seq Buffer holding DER encoded sequence. + * @praam [in] len Length of data in buffer (may be larger than SEQ). + * @return Size of complete DER encoding on success. + * @return 0 on failure. + */ +static int wolfssl_der_length(const unsigned char* seq, int len) +{ + int ret = 0; + word32 i = 0; + + /* Check it is a SEQUENCE and get the length of the underlying data. + * i is updated to be after SEQUENCE header bytes. + */ + if (GetSequence_ex(seq, &i, &ret, len, 0) >= 0) { + /* Add SEQUENCE header length to underlying data length. */ + ret += (int)i; + } + + return ret; +} + +#endif /* NO_RSA */ + +#endif /* OPENSSL_EXTRA */ /******************************************************************************* * START OF RSA API @@ -97,954 +331,1123 @@ static int PrintBNFieldFp(XFILE fp, int indent, const char* field, #ifndef NO_RSA -#if defined(OPENSSL_EXTRA) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) -WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG, int *initTmpRng) +/* + * RSA METHOD + * Could be used to hold function pointers to implementations of RSA operations. + */ + +#if defined(OPENSSL_EXTRA) +/* Return a blank RSA method and set the name and flags. + * + * Only one implemenation of RSA operations. + * name is duplicated. + * + * @param [in] name Name to use in method. + * @param [in] flags Flags to set into method. + * @return Newly allocated RSA method on success. + * @return NULL on failure. + */ +WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags) { - WC_RNG* rng = NULL; + WOLFSSL_RSA_METHOD* meth = NULL; + int name_len = 0; + int err; - if (!rsa || !initTmpRng) { - return NULL; + /* Validate name is not NULL. */ + err = (name == NULL); + if (!err) { + /* Allocate an RSA METHOD to return. */ + meth = (WOLFSSL_RSA_METHOD*)XMALLOC(sizeof(WOLFSSL_RSA_METHOD), NULL, + DYNAMIC_TYPE_OPENSSL); + err = (meth == NULL); } - *initTmpRng = 0; + if (!err) { + XMEMSET(meth, 0, sizeof(*meth)); + meth->flags = flags; + meth->dynamic = 1; -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ - !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) - rng = ((RsaKey*)rsa->internal)->rng; -#endif - if (tmpRNG != NULL + name_len = (int)XSTRLEN(name); + meth->name = (char*)XMALLOC(name_len + 1, NULL, DYNAMIC_TYPE_OPENSSL); + err = (meth->name == NULL); + } + if (!err) { + XMEMCPY(meth->name, name, name_len+1); + } + + if (err) { + /* meth->name won't be allocated on error. */ + XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL); + } + return meth; +} + +/* Default RSA method is one with wolfSSL name and no flags. + * + * @return Newly allocated wolfSSL RSA method on success. + * @return NULL on failure. + */ +const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void) +{ + static const WOLFSSL_RSA_METHOD wolfssl_rsa_meth = { + 0, /* No flags. */ + (char*)"wolfSSL RSA", + 0 /* Static definition. */ + }; + return &wolfssl_rsa_meth; +} + +/* Dispose of RSA method and allocated data. + * + * @param [in] meth RSA method to free. + */ +void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth) +{ + /* Free method if available and dynamically allocated. */ + if ((meth != NULL) && meth->dynamic) { + /* Name was duplicated and must be freed. */ + XFREE(meth->name, NULL, DYNAMIC_TYPE_OPENSSL); + /* Dispose of RSA method. */ + XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +#ifndef NO_WOLFSSL_STUB +/* Stub function for any RSA method setting function. + * + * Nothing is stored - not even flags or name. + * + * @param [in] meth RSA method. + * @param [in] p A pointer. + * @return 1 to indicate success. + */ +int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *meth, void* p) +{ + WOLFSSL_STUB("RSA_METHOD is not implemented."); + + (void)meth; + (void)p; + + return 1; +} +#endif /* !NO_WOLFSSL_STUB */ +#endif /* OPENSSL_EXTRA */ + +/* + * RSA constructor/decstructor APIs + */ + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) +/* Dispose of RSA key and allocated data. + * + * Cannot use rsa after this call. + * + * @param [in] rsa RSA key to free. + */ +void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) +{ + int doFree = 1; + + WOLFSSL_ENTER("wolfSSL_RSA_free"); + + /* Validate parameter. */ + if (rsa == NULL) { + doFree = 0; + } + if (doFree) { + int isZero; + int err; + + /* Decrement reference count. */ + wolfSSL_RefDec(&rsa->ref, &isZero, &err); + if (err == 0) { + /* Continue if reference count is zero. */ + doFree = isZero; + } + else { + /* Didn't reference decrement so can't free. */ + doFree = 0; + } + } + if (doFree) { + void* heap = rsa->heap; + + /* Dispose of allocated reference counting data. */ + wolfSSL_RefFree(&rsa->ref); + + #ifdef HAVE_EX_DATA_CLEANUP_HOOKS + wolfSSL_CRYPTO_cleanup_ex_data(&rsa->ex_data); + #endif + + if (rsa->internal != NULL) { + #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ + !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) + /* Check if RNG is owned before freeing it. */ + if (rsa->ownRng) { + WC_RNG* rng = ((RsaKey*)(rsa->internal))->rng; + if ((rng != NULL) && (rng != wolfssl_get_global_rng())) { + wc_FreeRng(rng); + XFREE(rng, heap, DYNAMIC_TYPE_RNG); + } + /* RNG isn't freed by wolfCrypt RSA free. */ + } + #endif + /* Dispose of allocated data in wolfCrypt RSA key. */ + wc_FreeRsaKey((RsaKey*)rsa->internal); + /* Dispose of memory for wolfCrypt RSA key. */ + XFREE(rsa->internal, heap, DYNAMIC_TYPE_RSA); + } + + /* Dispose of external representation of RSA values. */ + wolfSSL_BN_clear_free(rsa->iqmp); + wolfSSL_BN_clear_free(rsa->dmq1); + wolfSSL_BN_clear_free(rsa->dmp1); + wolfSSL_BN_clear_free(rsa->q); + wolfSSL_BN_clear_free(rsa->p); + wolfSSL_BN_clear_free(rsa->d); + wolfSSL_BN_free(rsa->e); + wolfSSL_BN_free(rsa->n); + + #if defined(OPENSSL_EXTRA) + if (rsa->meth) { + wolfSSL_RSA_meth_free((WOLFSSL_RSA_METHOD*)rsa->meth); + } + #endif + + /* Set back to NULLs for safety. */ + ForceZero(rsa, sizeof(*rsa)); + + XFREE(rsa, heap, DYNAMIC_TYPE_RSA); + (void)heap; + } +} + +/* Allocate and initialize a new RSA key. + * + * wolfSSL API. + * + * @param [in] heap Heap hint. + * @param [in] devId Device identifer value. + * @return RSA key on success. + * @return NULL on failure. + */ +WOLFSSL_RSA* wolfSSL_RSA_new_ex(void* heap, int devId) +{ + WOLFSSL_RSA* rsa = NULL; + RsaKey* key = NULL; + int err = 0; + int rsaKeyInited = 0; + + WOLFSSL_ENTER("wolfSSL_RSA_new"); + + /* Allocate memory for new wolfCrypt RSA key. */ + key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA); + if (key == NULL) { + WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure"); + err = 1; + } + if (!err) { + /* Allocate memory for new RSA key. */ + rsa = (WOLFSSL_RSA*)XMALLOC(sizeof(WOLFSSL_RSA), heap, + DYNAMIC_TYPE_RSA); + if (rsa == NULL) { + WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure"); + err = 1; + } + } + if (!err) { + /* Clear all fields of RSA key. */ + XMEMSET(rsa, 0, sizeof(WOLFSSL_RSA)); + /* Cache heap to use for all allocations. */ + rsa->heap = heap; + #ifdef OPENSSL_EXTRA + /* Always have a method set. */ + rsa->meth = wolfSSL_RSA_get_default_method(); + #endif + + /* Initialize reference counting. */ + wolfSSL_RefInit(&rsa->ref, &err); + } + if (!err) { + /* Initialize wolfCrypt RSA key. */ + if (wc_InitRsaKey_ex(key, heap, devId) != 0) { + WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure"); + err = 1; + } + else { + rsaKeyInited = 1; + } + } #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) - && rng == NULL - #endif - ) { - if (*tmpRNG == NULL) { -#ifdef WOLFSSL_SMALL_STACK - *tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (*tmpRNG == NULL) - return NULL; -#else - WOLFSSL_MSG("*tmpRNG is null"); - return NULL; -#endif - } - - if (wc_InitRng(*tmpRNG) == 0) { - rng = *tmpRNG; - *initTmpRng = 1; - } - else { - WOLFSSL_MSG("Bad RNG Init, trying global"); - rng = wolfssl_get_global_rng(); -#ifdef WOLFSSL_SMALL_STACK - if (*tmpRNG) - XFREE(*tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); - *tmpRNG = NULL; -#endif - } - } - return rng; -} -#endif - -#ifdef OPENSSL_EXTRA - -/* return wolfSSL native error codes. */ -static int wolfSSL_RSA_generate_key_native(WOLFSSL_RSA* rsa, int bits, - WOLFSSL_BIGNUM* bn, void* cb) -{ - int ret; - - (void)cb; - (void)bn; - (void)bits; - - WOLFSSL_ENTER("wolfSSL_RSA_generate_key_native"); - - if (rsa == NULL || rsa->internal == NULL) { - /* bit size checked during make key call */ - WOLFSSL_MSG("bad arguments"); - return BAD_FUNC_ARG; - } - -#ifdef WOLFSSL_KEY_GEN - { - #ifdef WOLFSSL_SMALL_STACK + if (!err) { WC_RNG* rng; - #else - WC_RNG rng[1]; - #endif - #ifdef WOLFSSL_SMALL_STACK - rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (rng == NULL) - return MEMORY_E; - #endif + /* Create a local RNG. */ + rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG); + if ((rng != NULL) && (wc_InitRng_ex(rng, heap, devId) != 0)) { + WOLFSSL_MSG("InitRng failure, attempting to use global RNG"); + XFREE(rng, heap, DYNAMIC_TYPE_RNG); + rng = NULL; + } - if ((ret = wc_InitRng(rng)) < 0) - WOLFSSL_MSG("RNG init failed"); - else if ((ret = wc_MakeRsaKey((RsaKey*)rsa->internal, bits, - wolfSSL_BN_get_word(bn), rng)) != MP_OKAY) - WOLFSSL_MSG("wc_MakeRsaKey failed"); - else if ((ret = SetRsaExternal(rsa)) != WOLFSSL_SUCCESS) - WOLFSSL_MSG("SetRsaExternal failed"); + rsa->ownRng = 1; + if (rng == NULL) { + /* Get the wolfSSL global RNG - not thread safe. */ + rng = wolfssl_get_global_rng(); + rsa->ownRng = 0; + } + if (rng == NULL) { + /* Couldn't create global either. */ + WOLFSSL_MSG("wolfSSL_RSA_new no WC_RNG for blinding"); + err = 1; + } else { - rsa->inSet = 1; - ret = WOLFSSL_ERROR_NONE; - } - - wc_FreeRng(rng); - #ifdef WOLFSSL_SMALL_STACK - XFREE(rng, NULL, DYNAMIC_TYPE_RNG); - #endif - } -#else - WOLFSSL_MSG("No Key Gen built in"); - ret = NOT_COMPILED_IN; -#endif - return ret; -} - -/* Generates a RSA key of length len - * - * len length of RSA key i.e. 2048 - * e e to use when generating RSA key - * f callback function for generation details - * data user callback argument - * - * Note: Because of wc_MakeRsaKey an RSA key size generated can be slightly - * rounded down. For example generating a key of size 2999 with e = - * 65537 will make a key of size 374 instead of 375. - * Returns a new RSA key on success and NULL on failure - */ -WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long e, - void(*f)(int, int, void*), void* data) -{ - WOLFSSL_RSA* rsa = NULL; - WOLFSSL_BIGNUM* bn = NULL; - - WOLFSSL_ENTER("wolfSSL_RSA_generate_key"); - - (void)f; - (void)data; - - if (len < 0) { - WOLFSSL_MSG("Bad argument: length was less than 0"); - return NULL; - } - - bn = wolfSSL_BN_new(); - if (bn == NULL) { - WOLFSSL_MSG("Error creating big number"); - return NULL; - } - - if (wolfSSL_BN_set_word(bn, e) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error using e value"); - wolfSSL_BN_free(bn); - return NULL; - } - - rsa = wolfSSL_RSA_new(); - if (rsa == NULL) { - WOLFSSL_MSG("memory error"); - } - else { -#ifdef HAVE_FIPS - for (;;) -#endif - { - int gen_ret = wolfSSL_RSA_generate_key_native(rsa, len, bn, NULL); - if (gen_ret != WOLFSSL_ERROR_NONE) { -#ifdef HAVE_FIPS - if (gen_ret == PRIME_GEN_E) - continue; -#endif - wolfSSL_RSA_free(rsa); - rsa = NULL; - } -#ifdef HAVE_FIPS - break; -#endif + /* Set the local or global RNG into the wolfCrypt RSA key. */ + (void)wc_RsaSetRNG(key, rng); + /* Won't fail as key and rng are not NULL. */ } } - wolfSSL_BN_free(bn); + #endif /* !HAVE_FIPS && !HAVE_USER_RSA && !HAVE_FAST_RSA && + * WC_RSA_BLINDING */ + if (!err) { + /* Set wolfCrypt RSA key into RSA key. */ + rsa->internal = key; + /* Data from external RSA key has not been set into internal one. */ + rsa->inSet = 0; + } + if (err) { + /* Dispose of any allocated data on error. */ + /* No failure after RNG allocation - no need to free RNG. */ + if (rsaKeyInited) { + wc_FreeRsaKey(key); + } + XFREE(key, heap, DYNAMIC_TYPE_RSA); + XFREE(rsa, heap, DYNAMIC_TYPE_RSA); + /* Return NULL. */ + rsa = NULL; + } return rsa; } -/* return compliant with OpenSSL - * 1 if success, 0 if error +/* Allocate and initialize a new RSA key. + * + * @return RSA key on success. + * @return NULL on failure. */ -int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn, - void* cb) +WOLFSSL_RSA* wolfSSL_RSA_new(void) { -#ifdef HAVE_FIPS - for (;;) -#endif - { - int gen_ret = wolfSSL_RSA_generate_key_native(rsa, bits, bn, cb); - if (gen_ret == WOLFSSL_ERROR_NONE) - return WOLFSSL_SUCCESS; -#ifdef HAVE_FIPS - else if (gen_ret == PRIME_GEN_E) - continue; -#endif - else - return WOLFSSL_FAILURE; - } + /* Call wolfSSL API to do work. */ + return wolfSSL_RSA_new_ex(NULL, INVALID_DEVID); } -#if !defined(HAVE_USER_RSA) - -#ifdef DEBUG_SIGN -static void DEBUG_SIGN_msg(const char *title, const unsigned char *out, - unsigned int outlen) -{ - const unsigned char *pt; - printf("%s[%d] = \n", title, (int)outlen); - outlen = outlen>100?100:outlen; - for (pt = out; pt < out + outlen; - printf("%c", ((*pt)&0x6f)>='A'?((*pt)&0x6f):'.'), pt++); - printf("\n"); -} -#else -#define DEBUG_SIGN_msg(a,b,c) -#endif - -static int nid2HashSum(int type) { - switch (type) { - #ifdef WOLFSSL_MD2 - case NID_md2: type = MD2h; break; - #endif - #ifndef NO_MD5 - case NID_md5: type = MD5h; break; - #endif - #ifndef NO_SHA - case NID_sha1: type = SHAh; break; - #endif - #ifndef NO_SHA256 - case NID_sha256: type = SHA256h; break; - #endif - #ifdef WOLFSSL_SHA384 - case NID_sha384: type = SHA384h; break; - #endif - #ifdef WOLFSSL_SHA512 - case NID_sha512: type = SHA512h; break; - #endif - #ifndef WOLFSSL_NOSHA3_224 - case NID_sha3_224: type = SHA3_224h; break; - #endif - #ifndef WOLFSSL_NOSHA3_256 - case NID_sha3_256: type = SHA3_256h; break; - #endif - #ifndef WOLFSSL_NOSHA3_384 - case NID_sha3_384: type = SHA3_384h; break; - #endif - #ifndef WOLFSSL_NOSHA3_512 - case NID_sha3_512: type = SHA3_512h; break; - #endif - default: - WOLFSSL_MSG("This NID (md type) not configured or not implemented"); - return 0; - } - return type; -} - -/* return WOLFSSL_SUCCESS on ok, 0 otherwise */ -int wolfSSL_RSA_sign(int type, const unsigned char* m, - unsigned int mLen, unsigned char* sigRet, - unsigned int* sigLen, WOLFSSL_RSA* rsa) -{ - return wolfSSL_RSA_sign_ex(type, m, mLen, sigRet, sigLen, rsa, 1); -} - -int wolfSSL_RSA_sign_ex(int type, const unsigned char* m, - unsigned int mLen, unsigned char* sigRet, - unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag) -{ - if (sigLen != NULL) - *sigLen = RSA_MAX_SIZE / CHAR_BIT; /* No size checking in this API */ - return wolfSSL_RSA_sign_generic_padding(type, m, mLen, sigRet, sigLen, - rsa, flag, RSA_PKCS1_PADDING); -} - -/** - * Sign a message with the chosen message digest, padding, and RSA key. - * @param type Hash NID - * @param m Message to sign. Most likely this will be the digest of - * the message to sign - * @param mLen Length of message to sign - * @param sigRet Output buffer - * @param sigLen On Input: length of sigRet buffer - * On Output: length of data written to sigRet - * @param rsa RSA key used to sign the input - * @param flag 1: Output the signature - * 0: Output the value that the unpadded signature should be - * compared to. Note: for RSA_PKCS1_PSS_PADDING the - * wc_RsaPSS_CheckPadding_ex function should be used to check - * the output of a *Verify* function. - * @param padding Padding to use. Only RSA_PKCS1_PSS_PADDING and - * RSA_PKCS1_PADDING are currently supported for signing. - * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error +/* Increments ref count of RSA key. + * + * @param [in, out] rsa RSA key. + * @return 1 on success + * @return 0 on error */ -int wolfSSL_RSA_sign_generic_padding(int type, const unsigned char* m, - unsigned int mLen, unsigned char* sigRet, - unsigned int* sigLen, WOLFSSL_RSA* rsa, int flag, - int padding) +int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa) { - word32 outLen; - word32 signSz; - int initTmpRng = 0; - WC_RNG* rng = NULL; - int ret = 0; -#ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; - byte* encodedSig = NULL; -#else - WC_RNG tmpRNG[1]; - byte encodedSig[MAX_ENCODED_SIG_SZ]; -#endif - - WOLFSSL_ENTER("wolfSSL_RSA_sign_generic_padding"); - - if (m == NULL || sigRet == NULL || sigLen == NULL || rsa == NULL) { - WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + int err = 0; + if (rsa != NULL) { + wolfSSL_RefInc(&rsa->ref, &err); } - DEBUG_SIGN_msg("Message to Sign", m, mLen); - - if (rsa->inSet == 0) { - WOLFSSL_MSG("No RSA internal set, do it"); - - if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return WOLFSSL_FAILURE; - } - } - - type = nid2HashSum(type); - - outLen = (word32)wolfSSL_BN_num_bytes(rsa->n); - -#ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) - return WOLFSSL_FAILURE; - - encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, - DYNAMIC_TYPE_SIGNATURE); - if (encodedSig == NULL) { - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); - return WOLFSSL_FAILURE; - } -#endif - - if (outLen == 0) { - WOLFSSL_MSG("Bad RSA size"); - } - else if (outLen > *sigLen) { - WOLFSSL_MSG("Output buffer too small"); - return WOLFSSL_FAILURE; - } - else if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; - initTmpRng = 1; - } - else { - WOLFSSL_MSG("Bad RNG Init, trying global"); - - rng = wolfssl_get_global_rng(); - } - - if (rng) { - if (flag != 0) { - switch (padding) { -#ifdef WC_RSA_NO_PADDING - case RSA_NO_PADDING: - WOLFSSL_MSG("RSA_NO_PADDING not supported for signing"); - ret = BAD_FUNC_ARG; - break; -#endif -#if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,1))) - case RSA_PKCS1_PSS_PADDING: - { - enum wc_HashType hType = wc_OidGetHash(type); -#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER - WOLFSSL_MSG("Using RSA-PSS with hash length salt. " - "OpenSSL uses max length by default."); -#endif - ret = wc_RsaPSS_Sign_ex(m, mLen, sigRet, outLen, - hType, wc_hash2mgf(hType), -#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER - RSA_PSS_SALT_LEN_DEFAULT, -#else - RSA_PSS_SALT_LEN_DISCOVER, -#endif - (RsaKey*)rsa->internal, rng); - break; - } -#endif -#ifndef WC_NO_RSA_OAEP - case RSA_PKCS1_OAEP_PADDING: - { - WOLFSSL_MSG("RSA_PKCS1_OAEP_PADDING not supported for signing"); - ret = BAD_FUNC_ARG; - break; - } -#endif - case RSA_PKCS1_PADDING: - signSz = wc_EncodeSignature(encodedSig, m, mLen, type); - if (signSz == 0) { - WOLFSSL_MSG("Bad Encode Signature"); - } - DEBUG_SIGN_msg("Encoded Message", encodedSig, signSz); - ret = wc_RsaSSL_Sign(encodedSig, signSz, sigRet, outLen, - (RsaKey*)rsa->internal, rng); - break; - default: - WOLFSSL_MSG("Unsupported padding"); - ret = BAD_FUNC_ARG; - break; - } - if (ret <= 0) { - WOLFSSL_MSG("Bad Rsa Sign"); - ret = 0; - } - else { - *sigLen = (unsigned int)ret; - ret = WOLFSSL_SUCCESS; - DEBUG_SIGN_msg("Signature", sigRet, *sigLen); - } - } else { - switch (padding) { - case RSA_NO_PADDING: - case RSA_PKCS1_PSS_PADDING: - case RSA_PKCS1_OAEP_PADDING: - ret = WOLFSSL_SUCCESS; - XMEMCPY(sigRet, m, mLen); - *sigLen = mLen; - break; - case RSA_PKCS1_PADDING: - default: - signSz = wc_EncodeSignature(encodedSig, m, mLen, type); - if (signSz == 0) { - WOLFSSL_MSG("Bad Encode Signature"); - } - ret = WOLFSSL_SUCCESS; - XMEMCPY(sigRet, encodedSig, signSz); - *sigLen = signSz; - break; - } - } - } - - if (initTmpRng) - wc_FreeRng(tmpRNG); - -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); - XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE); -#endif - - if (ret == WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_RSA_sign_generic_padding success"); - } - else { - WOLFSSL_LEAVE("wolfSSL_RSA_sign_generic_padding", ret); - WOLFSSL_MSG("wolfSSL_RSA_sign_generic_padding failed. " - "Returning WOLFSSL_FAILURE."); - ret = WOLFSSL_FAILURE; - } - return ret; + return !err; } -/* returns WOLFSSL_SUCCESS on successful verify and WOLFSSL_FAILURE on fail */ -int wolfSSL_RSA_verify(int type, const unsigned char* m, - unsigned int mLen, const unsigned char* sig, - unsigned int sigLen, WOLFSSL_RSA* rsa) -{ - return wolfSSL_RSA_verify_ex(type, m, mLen, sig, sigLen, rsa, - RSA_PKCS1_PADDING); -} +#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ -/* returns WOLFSSL_SUCCESS on successful verify and WOLFSSL_FAILURE on fail */ -int wolfSSL_RSA_verify_ex(int type, const unsigned char* m, - unsigned int mLen, const unsigned char* sig, - unsigned int sigLen, WOLFSSL_RSA* rsa, - int padding) { - int ret = WOLFSSL_FAILURE; - unsigned char *sigRet = NULL; - unsigned char *sigDec = NULL; - unsigned int len = sigLen; - int verLen; -#if (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \ - FIPS_VERSION_GE(5,1))) && !defined(HAVE_SELFTEST) - int hSum = nid2HashSum(type); - enum wc_HashType hType; -#endif - - WOLFSSL_ENTER("wolfSSL_RSA_verify"); - if ((m == NULL) || (sig == NULL)) { - WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; - } - sigDec = (unsigned char *)XMALLOC(sigLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sigDec == NULL) { - WOLFSSL_MSG("Memory failure"); - goto cleanup; - } - if (padding != RSA_PKCS1_PSS_PADDING) { - sigRet = (unsigned char *)XMALLOC(sigLen, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (sigRet == NULL) { - WOLFSSL_MSG("Memory failure"); - goto cleanup; - } - /* get non-encrypted signature to be compared with decrypted signature */ - if (wolfSSL_RSA_sign_generic_padding(type, m, mLen, sigRet, &len, rsa, - 0, padding) <= 0) { - WOLFSSL_MSG("Message Digest Error"); - goto cleanup; - } - DEBUG_SIGN_msg("Encoded Message", sigRet, len); - } - else { - DEBUG_SIGN_msg("Encoded Message", m, mLen); - } - /* decrypt signature */ -#if (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && \ - FIPS_VERSION_GE(5,1))) && !defined(HAVE_SELFTEST) - hType = wc_OidGetHash(hSum); - if ((verLen = wc_RsaSSL_Verify_ex2(sig, sigLen, (unsigned char *)sigDec, - sigLen, (RsaKey*)rsa->internal, padding, hType)) <= 0) { - WOLFSSL_MSG("RSA Decrypt error"); - goto cleanup; - } -#else - verLen = wc_RsaSSL_Verify(sig, sigLen, (unsigned char *)sigDec, sigLen, - (RsaKey*)rsa->internal); -#endif - DEBUG_SIGN_msg("Decrypted Signature", sigDec, ret); -#if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,1))) - if (padding == RSA_PKCS1_PSS_PADDING) { - if (wc_RsaPSS_CheckPadding_ex(m, mLen, sigDec, verLen, - hType, -#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER - RSA_PSS_SALT_LEN_DEFAULT, -#else - RSA_PSS_SALT_LEN_DISCOVER, -#endif - mp_count_bits(&((RsaKey*)rsa->internal)->n)) != 0) { - WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error"); - goto cleanup; - } - } - else -#endif /* !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) */ - if ((int)len != verLen || XMEMCMP(sigRet, sigDec, verLen) != 0) { - WOLFSSL_MSG("wolfSSL_RSA_verify_ex failed"); - goto cleanup; - } - - WOLFSSL_MSG("wolfSSL_RSA_verify_ex success"); - ret = WOLFSSL_SUCCESS; -cleanup: - if (sigRet) - XFREE(sigRet, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sigDec) - XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return ret; -} - -void wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA *r, - const WOLFSSL_BIGNUM **dmp1, const WOLFSSL_BIGNUM **dmq1, - const WOLFSSL_BIGNUM **iqmp) -{ - WOLFSSL_ENTER("wolfSSL_RSA_get0_crt_params"); - - if (r != NULL) { - if (dmp1 != NULL) - *dmp1 = r->dmp1; - if (dmq1 != NULL) - *dmq1 = r->dmq1; - if (iqmp != NULL) - *iqmp = r->iqmp; - } else { - if (dmp1 != NULL) - *dmp1 = NULL; - if (dmq1 != NULL) - *dmq1 = NULL; - if (iqmp != NULL) - *iqmp = NULL; - } -} - -int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *dmp1, - WOLFSSL_BIGNUM *dmq1, WOLFSSL_BIGNUM *iqmp) -{ - WOLFSSL_ENTER("wolfSSL_RSA_set0_crt_params"); - - /* If a param is null in r then it must be non-null in the - * corresponding user input. */ - if (r == NULL || (r->dmp1 == NULL && dmp1 == NULL) || - (r->dmq1 == NULL && dmq1 == NULL) || - (r->iqmp == NULL && iqmp == NULL)) { - WOLFSSL_MSG("Bad parameters"); - return WOLFSSL_FAILURE; - } - - if (dmp1 != NULL) { - wolfSSL_BN_clear_free(r->dmp1); - r->dmp1 = dmp1; - } - if (dmq1 != NULL) { - wolfSSL_BN_clear_free(r->dmq1); - r->dmq1 = dmq1; - } - if (iqmp != NULL) { - wolfSSL_BN_clear_free(r->iqmp); - r->iqmp = iqmp; - } - - return SetRsaInternal(r) == WOLFSSL_SUCCESS ? - WOLFSSL_SUCCESS : WOLFSSL_FAILURE; -} - -void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **p, - const WOLFSSL_BIGNUM **q) -{ - WOLFSSL_ENTER("wolfSSL_RSA_get0_factors"); - - if (r != NULL) { - if (p != NULL) - *p = r->p; - if (q != NULL) - *q = r->q; - } else { - if (p != NULL) - *p = NULL; - if (q != NULL) - *q = NULL; - } -} - -int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *p, - WOLFSSL_BIGNUM *q) -{ - WOLFSSL_ENTER("wolfSSL_RSA_set0_factors"); - - /* If a param is null in r then it must be non-null in the - * corresponding user input. */ - if (r == NULL || (r->p == NULL && p == NULL) || - (r->q == NULL && q == NULL)) { - WOLFSSL_MSG("Bad parameters"); - return WOLFSSL_FAILURE; - } - - if (p != NULL) { - wolfSSL_BN_clear_free(r->p); - r->p = p; - } - if (q != NULL) { - wolfSSL_BN_clear_free(r->q); - r->q = q; - } - - return SetRsaInternal(r) == WOLFSSL_SUCCESS ? - WOLFSSL_SUCCESS : WOLFSSL_FAILURE; -} - -void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, - const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d) -{ - WOLFSSL_ENTER("wolfSSL_RSA_get0_key"); - - if (r != NULL) { - if (n != NULL) - *n = r->n; - if (e != NULL) - *e = r->e; - if (d != NULL) - *d = r->d; - } else { - if (n != NULL) - *n = NULL; - if (e != NULL) - *e = NULL; - if (d != NULL) - *d = NULL; - } -} - -/* generate p-1 and q-1, WOLFSSL_SUCCESS on ok */ -int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa) -{ - int err; - mp_int tmp; - - WOLFSSL_MSG("wolfSSL_RsaGenAdd"); - - if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL || - rsa->dmp1 == NULL || rsa->dmq1 == NULL) { - WOLFSSL_MSG("rsa no init error"); - return WOLFSSL_FATAL_ERROR; - } - - if (mp_init(&tmp) != MP_OKAY) { - WOLFSSL_MSG("mp_init error"); - return WOLFSSL_FATAL_ERROR; - } - - err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp); - if (err != MP_OKAY) { - WOLFSSL_MSG("mp_sub_d error"); - } - else - err = mp_mod((mp_int*)rsa->d->internal, &tmp, - (mp_int*)rsa->dmp1->internal); - - if (err != MP_OKAY) { - WOLFSSL_MSG("mp_mod error"); - } - else - err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp); - if (err != MP_OKAY) { - WOLFSSL_MSG("mp_sub_d error"); - } - else - err = mp_mod((mp_int*)rsa->d->internal, &tmp, - (mp_int*)rsa->dmq1->internal); - - mp_clear(&tmp); - - if (err == MP_OKAY) - return WOLFSSL_SUCCESS; - else - return WOLFSSL_FATAL_ERROR; -} - -#endif /* !HAVE_USER_RSA */ +#ifdef OPENSSL_EXTRA #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) + +/* Allocate a new RSA key and make it a copy. + * + * Encodes to and from DER to copy. + * + * @param [in] rsa RSA key to duplicate. + * @return RSA key on success. + * @return NULL on error. + */ +WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) +{ + WOLFSSL_RSA* ret = NULL; + int derSz = 0; + byte* derBuf = NULL; + int err; + + WOLFSSL_ENTER("wolfSSL_RSAPublicKey_dup"); + + err = (rsa == NULL); + if (!err) { + /* Create a new RSA key to return. */ + ret = wolfSSL_RSA_new(); + if (ret == NULL) { + WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure"); + err = 1; + } + } + if (!err) { + /* Encode RSA public key to copy to DER - allocates DER buffer. */ + if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, rsa->heap)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); + err = 1; + } + } + if (!err) { + /* Decode DER of the RSA public key into new key. */ + if (wolfSSL_RSA_LoadDer_ex(ret, derBuf, derSz, + WOLFSSL_RSA_LOAD_PUBLIC) != 1) { + WOLFSSL_MSG("wolfSSL_RSA_LoadDer_ex failed"); + err = 1; + } + } + + /* Dispose of any allocated DER buffer. */ + XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_ASN1); + if (err) { + /* Disposes of any created RSA key - on error. */ + wolfSSL_RSA_free(ret); + ret = NULL; + } + return ret; +} + +/* wolfSSL_RSAPrivateKey_dup not supported */ + +#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ + +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) +static int wolfSSL_RSA_To_Der_ex(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey, + void* heap); +#endif + +/* + * RSA to/from bin APIs + */ + +/* Convert RSA public key data to internal. + * + * Creates new RSA key from the DER encoded RSA public key. + * + * @param [out] out Pointer to RSA key to return through. May be NULL. + * @param [in, out] derBuf Pointer to start of DER encoded data. + * @parma [in] derSz Length of the data in the DER buffer. + * @return RSA key on success. + * @return NULL on failure. + */ +WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **out, + const unsigned char **derBuf, long derSz) +{ + WOLFSSL_RSA *rsa = NULL; + int err = 0; + + WOLFSSL_ENTER("wolfSSL_d2i_RSAPublicKey"); + + /* Validate parameters. */ + if (derBuf == NULL) { + WOLFSSL_MSG("Bad argument"); + err = 1; + } + /* Create a new RSA key to return. */ + if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) { + WOLFSSL_MSG("RSA_new failed"); + err = 1; + } + /* Decode RSA key from DER. */ + if ((!err) && (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz, + WOLFSSL_RSA_LOAD_PUBLIC) != 1)) { + WOLFSSL_MSG("RSA_LoadDer failed"); + err = 1; + } + if ((!err) && (out != NULL)) { + /* Return through parameter too. */ + *out = rsa; + /* Move buffer on by the used amount. */ + *derBuf += wolfssl_der_length(*derBuf, (int)derSz); + } + + if (err) { + /* Dispose of any created RSA key. */ + wolfSSL_RSA_free(rsa); + rsa = NULL; + } + return rsa; +} + +/* Convert RSA private key data to internal. + * + * Createa new RSA key from the DER encoded RSA private key. + * + * @param [out] out Pointer to RSA key to return through. May be NULL. + * @param [in, out] derBuf Pointer to start of DER encoded data. + * @parma [in] derSz Length of the data in the DER buffer. + * @return RSA key on success. + * @return NULL on failure. + */ +WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **out, + const unsigned char **derBuf, long derSz) +{ + WOLFSSL_RSA *rsa = NULL; + int err = 0; + + WOLFSSL_ENTER("wolfSSL_d2i_RSAPublicKey"); + + /* Validate parameters. */ + if (derBuf == NULL) { + WOLFSSL_MSG("Bad argument"); + err = 1; + } + /* Create a new RSA key to return. */ + if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) { + WOLFSSL_MSG("RSA_new failed"); + err = 1; + } + /* Decode RSA key from DER. */ + if ((!err) && (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz, + WOLFSSL_RSA_LOAD_PRIVATE) != 1)) { + WOLFSSL_MSG("RSA_LoadDer failed"); + err = 1; + } + if ((!err) && (out != NULL)) { + /* Return through parameter too. */ + *out = rsa; + /* Move buffer on by the used amount. */ + *derBuf += wolfssl_der_length(*derBuf, (int)derSz); + } + + if (err) { + /* Dispose of any created RSA key. */ + wolfSSL_RSA_free(rsa); + rsa = NULL; + } + return rsa; +} + +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && \ + !defined(HAVE_FAST_RSA) +/* Converts an internal RSA structure to DER format for the private key. + * + * If "pp" is null then buffer size only is returned. + * If "*pp" is null then a created buffer is set in *pp and the caller is + * responsible for free'ing it. + * + * @param [in] rsa RSA key. + * @param [in, out] pp On in, pointer to allocated buffer or NULL. + * May be NULL. + * On out, newly allocated buffer or pointer to byte after + * encoding in passed in buffer. + * + * @return Size of DER encoding on success + * @return BAD_FUNC_ARG when rsa is NULL. + * @return 0 on failure. + */ +int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey"); + + /* Validate parameters. */ + if (rsa == NULL) { + WOLFSSL_MSG("Bad Function Arguments"); + ret = BAD_FUNC_ARG; + } + /* Encode the RSA key as a DER. Call allocates buffer into pp. + * No heap hint as this gets returned to the user */ + else if ((ret = wolfSSL_RSA_To_Der_ex(rsa, pp, 0, NULL)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); + ret = 0; + } + + /* Size of DER encoding. */ + return ret; +} + +/* Converts an internal RSA structure to DER format for the public key. + * + * If "pp" is null then buffer size only is returned. + * If "*pp" is null then a created buffer is set in *pp and the caller is + * responsible for free'ing it. + * + * @param [in] rsa RSA key. + * @param [in, out] pp On in, pointer to allocated buffer or NULL. + * May be NULL. + * On out, newly allocated buffer or pointer to byte after + * encoding in passed in buffer. + * @return Size of DER encoding on success + * @return BAD_FUNC_ARG when rsa is NULL. + * @return 0 on failure. + */ +int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, unsigned char **pp) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_i2d_RSAPublicKey"); + + /* check for bad functions arguments */ + if (rsa == NULL) { + WOLFSSL_MSG("Bad Function Arguments"); + ret = BAD_FUNC_ARG; + } + /* Encode the RSA key as a DER. Call allocates buffer into pp. + * No heap hint as this gets returned to the user */ + else if ((ret = wolfSSL_RSA_To_Der_ex(rsa, pp, 1, NULL)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); + ret = 0; + } + + return ret; +} +#endif /* defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && + * !defined(HAVE_FAST_RSA) */ + +#endif /* OPENSSL_EXTRA */ + +/* + * RSA to/from BIO APIs + */ + +/* wolfSSL_d2i_RSAPublicKey_bio not supported */ + +#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \ + || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) + +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && \ + !defined(HAVE_FAST_RSA) && !defined(NO_BIO) + +/* Read DER data from a BIO. + * + * DER structures start with a constructed sequence. Use this to calculate the + * total length of the DER data. + * + * @param [in] bio BIO object to read from. + * @param [out] out Buffer holding DER encoding. + * @return Number of bytes to DER encoding on success. + * @return 0 on failure. + */ +static int wolfssl_read_der_bio(WOLFSSL_BIO* bio, unsigned char** out) +{ + int err = 0; + unsigned char seq[MAX_SEQ_SZ]; + unsigned char* der = NULL; + int derLen = 0; + + /* Read in a minimal amount to get a SEQUENCE header of any size. */ + if (wolfSSL_BIO_read(bio, seq, sizeof(seq)) != sizeof(seq)) { + WOLFSSL_MSG("wolfSSL_BIO_read() of sequence failure"); + err = 1; + } + /* Calculate complete DER encoding length. */ + if ((!err) && ((derLen = wolfssl_der_length(seq, sizeof(seq))) <= 0)) { + WOLFSSL_MSG("DER SEQUENCE decode failed"); + err = 1; + } + /* Allocate a buffer to read DER data into. */ + if ((!err) && ((der = (unsigned char*)XMALLOC(derLen, bio->heap, + DYNAMIC_TYPE_TMP_BUFFER)) == NULL)) { + WOLFSSL_MSG("Malloc failure"); + err = 1; + } + if (!err) { + /* Calculate the unread amount. */ + int len = derLen - sizeof(seq); + /* Copy the previously read data into the buffer. */ + XMEMCPY(der, seq, sizeof(seq)); + /* Read rest of DER data from BIO. */ + if (wolfSSL_BIO_read(bio, der + sizeof(seq), len) != len) { + WOLFSSL_MSG("wolfSSL_BIO_read() failure"); + err = 1; + } + } + if (!err) { + /* Return buffer through parameter. */ + *out = der; + } + + if (err) { + /* Dispose of any allocated buffer on error. */ + XFREE(der, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + derLen = 0; + } + return derLen; +} + +/* Reads the RSA private key data from a BIO to the internal form. + * + * Creates new RSA key from the DER encoded RSA private key read from the BIO. + * + * @param [in] bio BIO object to read from. + * @param [out] out Pointer to RSA key to return through. May be NULL. + * @return RSA key on success. + * @return NULL on failure. + */ +WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out) +{ + WOLFSSL_RSA* key = NULL; + unsigned char* der = NULL; + int derLen = 0; + int err; + + WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey_bio()"); + + /* Validate parameters. */ + err = (bio == NULL); + /* Read just DER encoding from BIO - buffer allocated in call. */ + if ((!err) && ((derLen = wolfssl_read_der_bio(bio, &der)) == 0)) { + err = 1; + } + if (!err) { + /* Keep der for call to deallocate. */ + const unsigned char* cder = der; + /* Create an RSA key from the data from the BIO. */ + key = wolfSSL_d2i_RSAPrivateKey(NULL, &cder, derLen); + err = (key == NULL); + } + if ((!err) && (out != NULL)) { + /* Return the created RSA key through the parameter. */ + *out = key; + } + + if (err) { + /* Dispose of created key on error. */ + wolfSSL_RSA_free(key); + key = NULL; + } + /* Dispose of allocated data. */ + XFREE(der, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + return key; +} +#endif /* defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && + * !defined(HAVE_FAST_RSA) && !NO_BIO */ + +#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */ + +/* + * RSA DER APIs + */ + +#ifdef OPENSSL_EXTRA + +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) +/* Create a DER encoding of key. + * + * wolfSSL API. + * + * @param [in] rsa RSA key. + * @param [out] outBuf Allocated buffer containing DER encoding. + * May be NULL. + * @param [in] publicKey Whether to encode as public key. + * @return Encoding size on success. + * @return -ve on failure. + */ int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey, void* heap) { - int derSz = 0; + byte* p = NULL; int ret; - byte* derBuf; + + if (outBuf != NULL) { + p = *outBuf; + } + ret = wolfSSL_RSA_To_Der_ex(rsa, outBuf, publicKey, heap); + if ((ret > 0) && (p != NULL)) { + *outBuf = p; + } + return ret; +} + +/* Create a DER encoding of key. + * + * Buffer allocated with heap and DYNAMIC_TYPE_TMP_BUFFER. + * + * @param [in] rsa RSA key. + * @param [in, out] outBuf On in, pointer to allocated buffer or NULL. + * May be NULL. + * On out, newly allocated buffer or pointer to byte + * after encoding in passed in buffer. + * @param [in] publicKey Whether to encode as public key. + * @return Encoding size on success. + * @return -ve on failure. + */ +static int wolfSSL_RSA_To_Der_ex(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey, + void* heap) +{ + int ret = 1; + int derSz = 0; + byte* derBuf = NULL; WOLFSSL_ENTER("wolfSSL_RSA_To_Der"); - if (!rsa || (publicKey != 0 && publicKey != 1)) { + /* Unused if memory is disabled. */ + (void)heap; + + /* Validate parameters. */ + if ((rsa == NULL) || ((publicKey != 0) && (publicKey != 1))) { WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", BAD_FUNC_ARG); - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; + } + /* Push external RSA data into internal RSA key if not set. */ + if ((ret == 1) && (!rsa->inSet)) { + ret = SetRsaInternal(rsa); + } + /* wc_RsaKeyToPublicDer encode regardless of values. */ + if ((ret == 1) && publicKey && (mp_iszero(&((RsaKey*)rsa->internal)->n) || + mp_iszero(&((RsaKey*)rsa->internal)->e))) { + ret = BAD_FUNC_ARG; } - if (rsa->inSet == 0) { - if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal() Failed"); - WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", ret); - return ret; - } - } - - if (publicKey) { - if ((derSz = wc_RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0) { - WOLFSSL_MSG("wc_RsaPublicKeyDerSize failed"); - WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz); - return derSz; - } - } - else { - if ((derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, NULL, 0)) < 0) { - WOLFSSL_MSG("wc_RsaKeyToDer failed"); - WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz); - return derSz; - } - } - - if (outBuf) { - if (!(derBuf = (byte*)XMALLOC(derSz, heap, DYNAMIC_TYPE_TMP_BUFFER))) { - WOLFSSL_MSG("malloc failed"); - WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", MEMORY_ERROR); - return MEMORY_ERROR; - } - - /* Key to DER */ + if (ret == 1) { if (publicKey) { + /* Calculate length of DER encoded RSA public key. */ + derSz = wc_RsaPublicKeyDerSize((RsaKey*)rsa->internal, 1); + if (derSz < 0) { + WOLFSSL_MSG("wc_RsaPublicKeyDerSize failed"); + ret = derSz; + } + } + else { + /* Calculate length of DER encoded RSA private key. */ + derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, NULL, 0); + if (derSz < 0) { + WOLFSSL_MSG("wc_RsaKeyToDer failed"); + ret = derSz; + } + } + } + + if ((ret == 1) && (outBuf != NULL)) { + derBuf = *outBuf; + if (derBuf == NULL) { + /* Allocate buffer to hold DER encoded RSA key. */ + derBuf = (byte*)XMALLOC(derSz, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (derBuf == NULL) { + WOLFSSL_MSG("malloc failed"); + ret = MEMORY_ERROR; + } + } + } + if ((ret == 1) && (outBuf != NULL)) { + if (publicKey) { + /* RSA public key to DER. */ derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derSz); } else { + /* RSA private key to DER. */ derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, derSz); } - if (derSz < 0) { - WOLFSSL_MSG("wc_RsaKeyToPublicDer failed"); - XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); + WOLFSSL_MSG("RSA key encoding failed"); + ret = derSz; + } + else if ((*outBuf) != NULL) { + derBuf = NULL; + *outBuf += derSz; } else { - if (*outBuf) { - XMEMCPY(*outBuf, derBuf, derSz); - XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); + /* Return allocated buffer. */ + *outBuf = derBuf; + } + } + if (ret == 1) { + /* Success - return DER encoding size. */ + ret = derSz; + } + + if ((outBuf != NULL) && (*outBuf != derBuf)) { + /* Not returning buffer, needs to be disposed of. */ + XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER); + } + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", ret); + return ret; +} +#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ + +#endif /* OPENSSL_EXTRA */ + +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + +/* Load the DER encoded private RSA key. + * + * wolfSSL API. + * + * @param [in] rsa RSA key. + * @param [in] derBuf Buffer holding DER encoding. + * @param [in] derSz Length of DER encoding. + * @return 1 on success. + * @return -1 on failure. + */ +int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, + int derSz) +{ + /* Call implementation that handles both private and public keys. */ + return wolfSSL_RSA_LoadDer_ex(rsa, derBuf, derSz, WOLFSSL_RSA_LOAD_PRIVATE); +} + +/* Load the DER encoded public or private RSA key. + * + * wolfSSL API. + * + * @param [in] rsa RSA key. + * @param [in] derBuf Buffer holding DER encoding. + * @param [in] derSz Length of DER encoding. + * @param [in] opt Indicates public or private key. + * (WOLFSSL_RSA_LOAD_PUBLIC or WOLFSSL_RSA_LOAD_PRIVATE) + * @return 1 on success. + * @return -1 on failure. + */ +int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf, + int derSz, int opt) +{ + int ret = 1; + int res; + word32 idx = 0; + word32 algId; + + WOLFSSL_ENTER("wolfSSL_RSA_LoadDer"); + + /* Validate parameters. */ + if ((rsa == NULL) || (rsa->internal == NULL) || (derBuf == NULL) || + (derSz <= 0)) { + WOLFSSL_MSG("Bad function arguments"); + ret = -1; + } + + if (ret == 1) { + rsa->pkcs8HeaderSz = 0; + /* Check if input buffer has PKCS8 header. In the case that it does not + * have a PKCS8 header then do not error out. */ + res = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz, + &algId); + if (res > 0) { + /* Store size of PKCS#8 header for encoding. */ + WOLFSSL_MSG("Found PKCS8 header"); + rsa->pkcs8HeaderSz = (word16)idx; + } + /* When decoding and not PKCS#8, return will be ASN_PARSE_E. */ + else if (res != ASN_PARSE_E) { + /* Something went wrong while decoding. */ + WOLFSSL_MSG("Unexpected error with trying to remove PKCS#8 header"); + ret = -1; + } + } + if (ret == 1) { + /* Decode private or public key data. */ + if (opt == WOLFSSL_RSA_LOAD_PRIVATE) { + res = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, + derSz); + } + else { + res = wc_RsaPublicKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, + derSz); + } + /* Check for error. */ + if (res < 0) { + if (opt == WOLFSSL_RSA_LOAD_PRIVATE) { + WOLFSSL_MSG("RsaPrivateKeyDecode failed"); } else { - *outBuf = derBuf; + WOLFSSL_MSG("RsaPublicKeyDecode failed"); } + ret = -1; + } + } + if (ret == 1) { + /* Set external RSA key data from wolfCrypt key. */ + if (SetRsaExternal(rsa) != 1) { + ret = -1; + } + else { + rsa->inSet = 1; } } - (void)heap; /* unused if memory is disabled */ - WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz); - return derSz; + return ret; } -#endif + +#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ + +/* + * RSA PEM APIs + */ + +#ifdef OPENSSL_EXTRA #ifndef NO_BIO -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) -/* Takes a WOLFSSL_RSA key and writes it out to a WOLFSSL_BIO + +/* Writes PEM encoding of an RSA private key to a BIO. * - * bio the WOLFSSL_BIO to write to - * key the WOLFSSL_RSA key to write out - * cipher cipher used - * passwd password string if used - * len length of password string - * cb password callback to use - * arg null terminated string for passphrase + * @param [in] bio BIO object to write to. + * @param [in] rsa RSA key to write. + * @param [in] cipher Cipher to use when PEM encrypted. + * @param [in] passwd Password string when PEM encrypted. + * @param [in] len Length of password string when PEM encrypted. + * @param [in] cb Password callback to use when PEM encrypted. + * @param [in] arg NUL terminated string for passphrase when PEM encrypted. + * @return 1 on success. + * @return 0 on failure. */ -int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, - const WOLFSSL_EVP_CIPHER* cipher, - unsigned char* passwd, int len, - wc_pem_password_cb* cb, void* arg) +int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, + const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len, + wc_pem_password_cb* cb, void* arg) { - int ret; - WOLFSSL_EVP_PKEY* pkey; + int ret = 1; + WOLFSSL_EVP_PKEY* pkey = NULL; +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) + int derSz; + byte* derBuf = NULL; +#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ + WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSAPrivateKey"); - if (bio == NULL || key == NULL) { + /* Validate parameters. */ + if ((bio == NULL) || (rsa == NULL)) { WOLFSSL_MSG("Bad Function Arguments"); - return WOLFSSL_FAILURE; + ret = 0; } - pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); - if (pkey == NULL) { - WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); - return WOLFSSL_FAILURE; - } - - pkey->type = EVP_PKEY_RSA; - pkey->rsa = key; - pkey->ownRsa = 0; -#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) - /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */ - { - int derSz; - byte* derBuf = NULL; - - if ((derSz = wolfSSL_RSA_To_Der(key, &derBuf, 0, bio->heap)) < 0) { - WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Create a new EVP PKEY to hold data. */ + pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); + if (pkey == NULL) { + WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); + ret = 0; + } + } + if (ret == 1) { + /* Setup EVP_PKEY. */ + pkey->type = EVP_PKEY_RSA; + pkey->rsa = rsa; + pkey->ownRsa = 0; + #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) + /* Encode key as DER - buffer allocated in call. */ + if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0, bio->heap)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); + ret = 0; } - if (derBuf == NULL) { WOLFSSL_MSG("wolfSSL_RSA_To_Der failed to get buffer"); - return WOLFSSL_FAILURE; + ret = 0; } - - pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (pkey->pkey.ptr == NULL) { - WOLFSSL_MSG("key malloc failed"); - XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; - } - pkey->pkey_sz = derSz; - XMEMCPY(pkey->pkey.ptr, derBuf, derSz); - XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); } -#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ + if (ret == 1) { + /* Store that buffer and length into EVP_PKEY. */ + pkey->pkey.ptr = (char*)derBuf; + pkey->pkey_sz = derSz; + #endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ - ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len, - cb, arg); + /* Use EVP_PKEY API to create PEM encoding and write to BIO. */ + ret = wolfSSL_PEM_write_bio_PrivateKey(bio, pkey, cipher, passwd, len, + cb, arg); + } +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) + /* Dispose of DER buffer. */ + XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (pkey != NULL) { + pkey->pkey.ptr = NULL; + pkey->pkey_sz = 0; + } +#endif + /* Dispose of EVP_PEY - no longer needed. */ wolfSSL_EVP_PKEY_free(pkey); return ret; } #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) -/* forward declaration for wolfSSL_PEM_write_bio_RSA_PUBKEY */ -static int WriteBioPUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key); +/* Forward declaration for wolfSSL_PEM_write_bio_RSA_PUBKEY. + * Implementation in ssl.c. + */ +static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key); -/* Takes an RSA public key and writes it out to a WOLFSSL_BIO - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE +/* Writes PEM encoding of an RSA public key to a BIO. + * + * @param [in] bio BIO object to write to. + * @param [in] rsa RSA key to write. + * @return 1 on success. + * @return 0 on failure. */ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa) { - int ret = 0; + int ret = 1; WOLFSSL_EVP_PKEY* pkey = NULL; WOLFSSL_ENTER("wolfSSL_PEM_write_bio_RSA_PUBKEY"); - if (bio == NULL || rsa == NULL) { + /* Validate parameters. */ + if ((bio == NULL) || (rsa == NULL)) { WOLFSSL_MSG("Bad Function Arguments"); - return WOLFSSL_FAILURE; + ret = 0; } - /* Initialize pkey structure */ - pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); - if (pkey == NULL) { - WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Create a new EVP PKEY to hold data. */ + pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); + if (pkey == NULL) { + WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); + ret = 0; + } + } + if (ret == 1) { + /* Setup EVP_PKEY */ + pkey->type = EVP_PKEY_RSA; + pkey->rsa = rsa; + pkey->ownRsa = 0; + + /* Use internal EVP_PKEY API to create PEM encoding and write to BIO. */ + ret = pem_write_bio_pubkey(bio, pkey); } - pkey->type = EVP_PKEY_RSA; - pkey->rsa = rsa; - pkey->ownRsa = 0; - - ret = WriteBioPUBKEY(bio, pkey); + /* Dispose of EVP_PEY - no longer needed. */ wolfSSL_EVP_PKEY_free(pkey); return ret; } #ifndef NO_FILESYSTEM +/* Writes PEM encoding of an RSA public key to a file pointer. + * + * TODO: Make API available even without BIOs. + * + * @param [in] fp File pointer to write to. + * @param [in] rsa RSA key to write. + * @return 1 on success. + * @return 0 on failure. + */ int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA* key) { - int ret = WOLFSSL_SUCCESS; + int ret = 1; WOLFSSL_BIO* bio = NULL; WOLFSSL_ENTER("wolfSSL_PEM_write_RSAPublicKey"); - if (fp == XBADFILE || key == NULL) { + /* Validate parameters. */ + if ((fp == XBADFILE) || (key == NULL)) { WOLFSSL_MSG("Bad argument."); - ret = WOLFSSL_FAILURE; + ret = 0; } - if (ret == WOLFSSL_SUCCESS) { - bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); + if (ret == 1) { + /* Create a file BIO to write into with file pointer. */ + bio = wolfSSL_BIO_new_fp(fp, BIO_NOCLOSE); if (bio == NULL) { WOLFSSL_MSG("wolfSSL_BIO_new failed."); - ret = WOLFSSL_FAILURE; - } - else if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_BIO_set_fp failed."); - ret = WOLFSSL_FAILURE; + ret = 0; } } - if (ret == WOLFSSL_SUCCESS && wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSA_PUBKEY failed."); - ret = WOLFSSL_FAILURE; + if (ret == 1) { + /* Call BIO version of API to do work. */ + ret = wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key); + if (ret != 1) { + WOLFSSL_MSG("wolfSSL_PEM_write_bio_RSA_PUBKEY failed."); + } } - if (bio != NULL) { - wolfSSL_BIO_free(bio); - } + /* Dispose of BIO - no longer needed. */ + wolfSSL_BIO_free(bio); WOLFSSL_LEAVE("wolfSSL_PEM_write_RSAPublicKey", ret); @@ -1053,282 +1456,375 @@ int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA* key) #endif /* !NO_FILESYSTEM */ #endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ -/* Reads an RSA public key from a WOLFSSL_BIO into a WOLFSSL_RSA - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE +/* Create an RSA public key by reading the PEM encoded data from the BIO. + * + * @param [in] bio BIO object to read from. + * @param [out] out RSA key created. + * @param [in] cb Password callback when PEM encrypted. + * @param [in] pass NUL terminated string for passphrase when PEM encrypted. + * @return RSA key on success. + * @return NULL on failure. */ -WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_RSA** rsa, - wc_pem_password_cb* cb, - void *pass) +WOLFSSL_RSA *wolfSSL_PEM_read_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, + WOLFSSL_RSA** out, wc_pem_password_cb* cb, void *pass) { WOLFSSL_EVP_PKEY* pkey; - WOLFSSL_RSA* local; + WOLFSSL_RSA* rsa = NULL; WOLFSSL_ENTER("wolfSSL_PEM_read_bio_RSA_PUBKEY"); + /* Read into a new EVP_PKEY. */ pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass); - if (pkey == NULL) { - return NULL; + if (pkey != NULL) { + /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY + * the flag indicating that the WOLFSSL_RSA structure is owned should be + * FALSE to avoid having it free'd. */ + pkey->ownRsa = 0; + rsa = pkey->rsa; + if (out != NULL) { + *out = rsa; + } + + wolfSSL_EVP_PKEY_free(pkey); } - /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY the - * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE - * to avoid having it free'd */ - pkey->ownRsa = 0; - local = pkey->rsa; - if (rsa != NULL) { - *rsa = local; - } - - wolfSSL_EVP_PKEY_free(pkey); - return local; + return rsa; } -#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) */ #endif /* !NO_BIO */ -#if (defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)) && \ +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && \ (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) -/* return code compliant with OpenSSL : - * 1 if success, 0 if error +/* Writes PEM encoding of an RSA private key to newly allocated buffer. + * + * Buffer returned was allocated with: DYNAMIC_TYPE_KEY. + * + * @param [in] rsa RSA key to write. + * @param [in] cipher Cipher to use when PEM encrypted. May be NULL. + * @param [in] passwd Password string when PEM encrypted. May be NULL. + * @param [in] passwdSz Length of password string when PEM encrypted. + * @param [out] pem Allocated buffer with PEM encoding. + * @param [out] plen Length of PEM encoding. + * @return 1 on success. + * @return 0 on failure. */ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, - unsigned char* passwd, int passwdSz, - unsigned char **pem, int *plen) + unsigned char* passwd, int passwdSz, unsigned char **pem, int *plen) { - byte *derBuf = NULL, *tmp, *cipherInfo = NULL; + int ret = 1; + byte* derBuf = NULL; + byte* tmp = NULL; + byte* cipherInfo = NULL; int derSz = 0; + int pemSz; const int type = PRIVATEKEY_TYPE; const char* header = NULL; const char* footer = NULL; WOLFSSL_ENTER("wolfSSL_PEM_write_mem_RSAPrivateKey"); - if (pem == NULL || plen == NULL || rsa == NULL || rsa->internal == NULL) { + /* Validate parameters. */ + if ((pem == NULL) || (plen == NULL) || (rsa == NULL) || + (rsa->internal == NULL)) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + ret = 0; } - if (wc_PemGetHeaderFooter(type, &header, &footer) != 0) - return WOLFSSL_FAILURE; - - if (rsa->inSet == 0) { - WOLFSSL_MSG("No RSA internal set, do it"); - - if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return WOLFSSL_FAILURE; - } + /* Get PEM header and footer strings. */ + if ((ret == 1) && (wc_PemGetHeaderFooter(type, &header, &footer) != 0)) { + ret = 0; } - if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0, rsa->heap)) < 0) { + /* Set the RSA key data into the wolfCrypt RSA key if not done so. */ + if ((ret == 1) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) { + ret = 0; + } + + /* Encode wolfCrypt RSA key to DER - derBuf allocated in call. */ + if ((ret == 1) && ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0, + rsa->heap)) < 0)) { WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); - return WOLFSSL_FAILURE; + ret = 0; } - /* encrypt DER buffer if required */ - if (passwd != NULL && passwdSz > 0 && cipher != NULL) { - int ret; + /* Encrypt DER buffer if required. */ + if ((ret == 1) && (passwd != NULL) && (passwdSz > 0) && (cipher != NULL)) { int blockSz = wolfSSL_EVP_CIPHER_block_size(cipher); byte *tmpBuf; - /* Add space for padding */ - if (!(tmpBuf = (byte*)XREALLOC(derBuf, derSz + blockSz, rsa->heap, - DYNAMIC_TYPE_TMP_BUFFER))) { + /* Add space for padding. */ + tmpBuf = (byte*)XREALLOC(derBuf, derSz + blockSz, rsa->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (tmpBuf == NULL) { WOLFSSL_MSG("Extending DER buffer failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); - return WOLFSSL_FAILURE; + ret = 0; } - derBuf = tmpBuf; + else { + derBuf = tmpBuf; - ret = EncryptDerKey(derBuf, &derSz, cipher, - passwd, passwdSz, &cipherInfo, derSz + blockSz); - if (ret != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("EncryptDerKey failed"); - XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER); - return ret; + /* Encrypt DER inline. */ + ret = EncryptDerKey(derBuf, &derSz, cipher, passwd, passwdSz, + &cipherInfo, derSz + blockSz); + if (ret != 1) { + WOLFSSL_MSG("EncryptDerKey failed"); + } } - - /* tmp buffer with a max size */ - *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + - (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE; - } - else { - /* tmp buffer with a max size */ - *plen = (derSz * 2) + (int)XSTRLEN(header) + 1 + - (int)XSTRLEN(footer) + 1; } - tmp = (byte*)XMALLOC(*plen, NULL, DYNAMIC_TYPE_PEM); - if (tmp == NULL) { - WOLFSSL_MSG("malloc failed"); - XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER); - if (cipherInfo != NULL) - XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Calculate PEM encoding size. */ + pemSz = wc_DerToPemEx(derBuf, derSz, NULL, 0, cipherInfo, type); + if (pemSz <= 0) { + WOLFSSL_MSG("wc_DerToPemEx failed"); + ret = 0; + } + } + if (ret == 1) { + /* Allocate space for PEM encoding plus a NUL terminator. */ + tmp = (byte*)XMALLOC(pemSz + 1, NULL, DYNAMIC_TYPE_KEY); + if (tmp == NULL) { + WOLFSSL_MSG("malloc failed"); + ret = 0; + } + } + if (ret == 1) { + /* DER to PEM */ + pemSz = wc_DerToPemEx(derBuf, derSz, tmp, pemSz, cipherInfo, type); + if (pemSz <= 0) { + WOLFSSL_MSG("wc_DerToPemEx failed"); + ret = 0; + } + } + if (ret == 1) { + /* NUL terminate string - PEM. */ + tmp[pemSz] = 0x00; + /* Return allocated buffer and size. */ + *pem = tmp; + *plen = pemSz; + /* Don't free returning buffer. */ + tmp = NULL; } - /* DER to PEM */ - *plen = wc_DerToPemEx(derBuf, derSz, tmp, *plen, cipherInfo, type); - if (*plen <= 0) { - WOLFSSL_MSG("wc_DerToPemEx failed"); - XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER); - XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - if (cipherInfo != NULL) - XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - return WOLFSSL_FAILURE; - } + XFREE(tmp, NULL, DYNAMIC_TYPE_KEY); + XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_DER); - if (cipherInfo != NULL) - XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - - *pem = (byte*)XMALLOC((*plen)+1, NULL, DYNAMIC_TYPE_KEY); - if (*pem == NULL) { - WOLFSSL_MSG("malloc failed"); - XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_FAILURE; - } - XMEMSET(*pem, 0, (*plen)+1); - - if (XMEMCPY(*pem, tmp, *plen) == NULL) { - WOLFSSL_MSG("XMEMCPY failed"); - XFREE(pem, NULL, DYNAMIC_TYPE_KEY); - XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_FAILURE; - } - XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - - return WOLFSSL_SUCCESS; + return ret; } - #ifndef NO_FILESYSTEM -/* return code compliant with OpenSSL : - * 1 if success, 0 if error +/* Writes PEM encoding of an RSA private key to a file pointer. + * + * TODO: Support use of the password callback and callback context. + * + * @param [in] fp File pointer to write to. + * @param [in] rsa RSA key to write. + * @param [in] cipher Cipher to use when PEM encrypted. May be NULL. + * @param [in] passwd Password string when PEM encrypted. May be NULL. + * @param [in] passwdSz Length of password string when PEM encrypted. + * @param [in] cb Password callback to use when PEM encrypted. Unused. + * @param [in] arg NUL terminated string for passphrase when PEM + * encrypted. Unused. + * @return 1 on success. + * @return 0 on failure. */ int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa, - const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - wc_pem_password_cb *cb, void *u) + const EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz, + wc_pem_password_cb *cb, void *arg) { - byte *pem; - int plen, ret; + int ret = 1; + byte* pem = NULL; + int plen; (void)cb; - (void)u; + (void)arg; - WOLFSSL_MSG("wolfSSL_PEM_write_RSAPrivateKey"); + WOLFSSL_ENTER("wolfSSL_PEM_write_RSAPrivateKey"); - if (fp == XBADFILE || rsa == NULL || rsa->internal == NULL) - { + /* Validate parameters. */ + if ((fp == XBADFILE) || (rsa == NULL) || (rsa->internal == NULL)) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + ret = 0; } - ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, enc, kstr, klen, &pem, - &plen); - if (ret != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Write PEM to buffer that is allocated in the call. */ + ret = wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, cipher, passwd, passwdSz, + &pem, &plen); + if (ret != 1) { + WOLFSSL_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed"); + } } - - ret = (int)XFWRITE(pem, plen, 1, fp); - if (ret != 1) { + /* Write PEM to file pointer. */ + if ((ret == 1) && ((int)XFWRITE(pem, plen, 1, fp) != 1)) { WOLFSSL_MSG("RSA private key file write failed"); - return WOLFSSL_FAILURE; + ret = 0; } + /* Dispose of any allocated PEM buffer. */ XFREE(pem, NULL, DYNAMIC_TYPE_KEY); - return WOLFSSL_SUCCESS; + return ret; } #endif /* NO_FILESYSTEM */ #endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA && WOLFSSL_PEM_TO_DER */ #ifndef NO_BIO -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) -/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects - * the results to be an RSA key. +/* Create an RSA private key by reading the PEM encoded data from the BIO. * - * bio structure to read RSA private key from - * rsa if not null is then set to the result - * cb password callback for reading PEM - * pass password string - * - * returns a pointer to a new WOLFSSL_RSA structure on success and NULL on fail + * @param [in] bio BIO object to read from. + * @param [out] out RSA key created. + * @param [in] cb Password callback when PEM encrypted. + * @param [in] pass NUL terminated string for passphrase when PEM encrypted. + * @return RSA key on success. + * @return NULL on failure. */ WOLFSSL_RSA* wolfSSL_PEM_read_bio_RSAPrivateKey(WOLFSSL_BIO* bio, - WOLFSSL_RSA** rsa, wc_pem_password_cb* cb, void* pass) + WOLFSSL_RSA** out, wc_pem_password_cb* cb, void* pass) { WOLFSSL_EVP_PKEY* pkey; - WOLFSSL_RSA* local; + WOLFSSL_RSA* rsa = NULL; WOLFSSL_ENTER("PEM_read_bio_RSAPrivateKey"); + /* Read PEM encoded RSA private key from a BIO. using generic EVP function. + */ pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass); - if (pkey == NULL) { - return NULL; - } - - /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY the - * flag indicating that the WOLFSSL_RSA structure is owned should be FALSE - * to avoid having it free'd */ - pkey->ownRsa = 0; - local = pkey->rsa; - if (rsa != NULL) { - *rsa = local; + if (pkey != NULL) { + /* Since the WOLFSSL_RSA structure is being taken from WOLFSSL_EVP_PKEY + * the flag indicating that the WOLFSSL_RSA structure is owned should be + * FALSE to avoid having it free'd. */ + pkey->ownRsa = 0; + rsa = pkey->rsa; + if (out != NULL) { + /* Return WOLFSSL_RSA object through parameter too. */ + *out = rsa; + } } + /* Dispose of EVP_PKEY wrapper. */ wolfSSL_EVP_PKEY_free(pkey); - return local; + return rsa; } -#endif /* OPENSSL_EXTRA || OPENSSL_ALL */ #endif /* NO_BIO */ +#if !defined(NO_FILESYSTEM) +#ifndef NO_WOLFSSL_STUB +/* Create an RSA public key by reading the PEM encoded data from the BIO. + * + * TODO: implement + * + * @param [in] bio BIO object to read from. + * @param [out] out RSA key created. + * @param [in] cb Password callback when PEM encrypted. May be NULL. + * @param [in] pass NUL terminated string for passphrase when PEM encrypted. + * May be NULL. + * @return RSA key on success. + * @return NULL on failure. + */ +WOLFSSL_RSA* wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA** rsa, + wc_pem_password_cb* cb, void* pass) +{ + WOLFSSL_STUB("PEM_read_RSAPublicKey"); + WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented"); + + (void)fp; + (void)rsa; + (void)cb; + (void)pass; + + return NULL; +} +#endif + +#ifndef NO_WOLFSSL_STUB +/* Writes PEM encoding of an RSA public key to a file pointer. + * + * TODO: implement by calling wolfSSL_PEM_write_RSAPublicKey()? + * + * @param [in] fp File pointer to write to. + * @param [in] rsa RSA key to write. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *rsa) +{ + WOLFSSL_STUB("PEM_write_RSA_PUBKEY"); + WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented"); + + (void)fp; + (void)rsa; + + return 0; +} +#endif + +#endif /* NO_FILESYSTEM */ + +/* + * RSA print APIs + */ + #if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ !defined(NO_STDIO_FILESYSTEM) +/* Print an RSA key to a file pointer. + * + * @param [in] fp File pointer to write to. + * @param [in] rsa RSA key to write. + * @param [in] indent Number of spaces to prepend to each line. + * @return 1 on success. + * @return 0 on failure. + */ int wolfSSL_RSA_print_fp(XFILE fp, WOLFSSL_RSA* rsa, int indent) { - int ret = WOLFSSL_SUCCESS; - int keySize; + int ret = 1; WOLFSSL_ENTER("wolfSSL_RSA_print_fp"); - if (fp == XBADFILE || rsa == NULL) { - ret = WOLFSSL_FAILURE; + /* Validate parameters. */ + if ((fp == XBADFILE) || (rsa == NULL)) { + ret = 0; } - if (ret == WOLFSSL_SUCCESS && rsa->n != NULL) { - keySize = wolfSSL_BN_num_bits(rsa->n); - if (keySize == WOLFSSL_FAILURE) { - ret = WOLFSSL_FAILURE; + /* Set the external data from the wolfCrypt RSA key if not done. */ + if ((ret == 1) && (!rsa->exSet)) { + ret = SetRsaExternal(rsa); + } + + /* Get the key size from modulus if available. */ + if ((ret == 1) && (rsa->n != NULL)) { + int keySize = wolfSSL_BN_num_bits(rsa->n); + if (keySize == 0) { + ret = 0; } else { XFPRINTF(fp, "%*s", indent, ""); XFPRINTF(fp, "RSA Private-Key: (%d bit, 2 primes)\n", keySize); } } - if (ret == WOLFSSL_SUCCESS && rsa->n != NULL) { - ret = PrintBNFieldFp(fp, indent, "modulus", rsa->n); + /* Print out any components available. */ + if ((ret == 1) && (rsa->n != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "modulus", rsa->n); } - if (ret == WOLFSSL_SUCCESS && rsa->d != NULL) { - ret = PrintBNFieldFp(fp, indent, "privateExponent", rsa->d); + if ((ret == 1) && (rsa->d != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "privateExponent", rsa->d); } - if (ret == WOLFSSL_SUCCESS && rsa->p != NULL) { - ret = PrintBNFieldFp(fp, indent, "prime1", rsa->p); + if ((ret == 1) && (rsa->p != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "prime1", rsa->p); } - if (ret == WOLFSSL_SUCCESS && rsa->q != NULL) { - ret = PrintBNFieldFp(fp, indent, "prime2", rsa->q); + if ((ret == 1) && (rsa->q != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "prime2", rsa->q); } - if (ret == WOLFSSL_SUCCESS && rsa->dmp1 != NULL) { - ret = PrintBNFieldFp(fp, indent, "exponent1", rsa->dmp1); + if ((ret == 1) && (rsa->dmp1 != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "exponent1", rsa->dmp1); } - if (ret == WOLFSSL_SUCCESS && rsa->dmq1 != NULL) { - ret = PrintBNFieldFp(fp, indent, "exponent2", rsa->dmq1); + if ((ret == 1) && (rsa->dmq1 != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "exponent2", rsa->dmq1); } - if (ret == WOLFSSL_SUCCESS && rsa->iqmp != NULL) { - ret = PrintBNFieldFp(fp, indent, "coefficient", rsa->iqmp); + if ((ret == 1) && (rsa->iqmp != NULL)) { + ret = pk_bn_field_print_fp(fp, indent, "coefficient", rsa->iqmp); } WOLFSSL_LEAVE("wolfSSL_RSA_print_fp", ret); @@ -1340,397 +1836,1059 @@ int wolfSSL_RSA_print_fp(XFILE fp, WOLFSSL_RSA* rsa, int indent) #if defined(XSNPRINTF) && !defined(NO_BIO) && !defined(HAVE_FAST_RSA) /* snprintf() must be available */ -/****************************************************************************** -* wolfSSL_RSA_print - writes the human readable form of RSA to bio -* -* RETURNS: -* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE -*/ -int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset) +/* Maximum size of a header line. */ +#define RSA_PRINT_MAX_HEADER_LINE PRINT_NUM_MAX_INDENT + +/* Writes the human readable form of RSA to a BIO. + * + * @param [in] bio BIO object to write to. + * @param [in] rsa RSA key to write. + * @param [in] indent Number of spaces before each line. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int indent) { - char tmp[100] = {0}; - word32 idx = 0; - int sz = 0; - byte lbit = 0; - int rawLen = 0; - byte* rawKey = NULL; - RsaKey* iRsa = NULL; + int ret = 1; + int sz = 0; + RsaKey* key = NULL; + char line[RSA_PRINT_MAX_HEADER_LINE]; + int len; int i = 0; - mp_int *rsaElem = NULL; - const char *rsaStr[] = { - "Modulus:", - "PublicExponent:", - "PrivateExponent:", - "Prime1:", - "Prime2:", - "Exponent1:", - "Exponent2:", - "Coefficient:" - }; + mp_int *num = NULL; + /* Header strings. */ + const char *name[] = { + "Modulus:", "Exponent:", "PrivateExponent:", "Prime1:", "Prime2:", + "Exponent1:", "Exponent2:", "Coefficient:" + }; WOLFSSL_ENTER("wolfSSL_RSA_print"); - (void)offset; - if (bio == NULL || rsa == NULL) { - return WOLFSSL_FATAL_ERROR; + /* Validate parameters. */ + if ((bio == NULL) || (rsa == NULL) || (indent > PRINT_NUM_MAX_INDENT)) { + ret = -1; } - if ((sz = wolfSSL_RSA_size(rsa)) < 0) { - WOLFSSL_MSG("Error getting RSA key size"); - return WOLFSSL_FAILURE; - } - iRsa = (RsaKey*)rsa->internal; + if (ret == 1) { + key = (RsaKey*)rsa->internal; - XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s: (%d bit)", - "RSA Private-Key", 8 * sz); - tmp[sizeof(tmp) - 1] = '\0'; - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { - return WOLFSSL_FAILURE; + /* Get size in bits of key for printing out. */ + sz = wolfSSL_RSA_bits(rsa); + if (sz <= 0) { + WOLFSSL_MSG("Error getting RSA key size"); + ret = 0; + } + } + if (ret == 1) { + /* Print any indent spaces. */ + ret = wolfssl_print_indent(bio, line, sizeof(line), indent); + } + if (ret == 1) { + /* Print header line. */ + len = XSNPRINTF(line, sizeof(line) - 1, "\nRSA %s: (%d bit)\n", + (!mp_iszero(&key->d)) ? "Private-Key" : "Public-Key", sz); + if (wolfSSL_BIO_write(bio, line, len) <= 0) { + ret = 0; + } } - for (i=0; in; + num = &key->n; break; case 1: - rsaElem = &iRsa->e; + num = &key->e; break; case 2: - rsaElem = &iRsa->d; + num = &key->d; break; case 3: - rsaElem = &iRsa->p; + num = &key->p; break; case 4: - rsaElem = &iRsa->q; + num = &key->q; break; case 5: - rsaElem = &iRsa->dP; + num = &key->dP; break; case 6: - rsaElem = &iRsa->dQ; + num = &key->dQ; break; case 7: - rsaElem = &iRsa->u; + num = &key->u; break; default: WOLFSSL_MSG("Bad index value"); } if (i == 1) { - /* Print out exponent values */ - rawLen = mp_unsigned_bin_size(rsaElem); - if (rawLen < 0) { - WOLFSSL_MSG("Error getting exponent size"); - return WOLFSSL_FAILURE; - } - - if ((word32)rawLen < sizeof(word32)) { - rawLen = sizeof(word32); - } - rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (rawKey == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(rawKey, 0, rawLen); - if (mp_to_unsigned_bin(rsaElem, rawKey) < 0) { - XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - if ((word32)rawLen <= sizeof(word32)) { - idx = *(word32*)rawKey; - #ifdef BIG_ENDIAN_ORDER - idx = ByteReverseWord32(idx); - #endif - } - XSNPRINTF(tmp, sizeof(tmp) - 1, "\nExponent: %u (0x%x)", idx, idx); - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { - XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + /* Print exponent as a 32-bit value. */ + ret = wolfssl_print_value(bio, num, name[i], indent); } - else { - XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s\n ", rsaStr[i]); - tmp[sizeof(tmp) - 1] = '\0'; - if (mp_leading_bit(rsaElem)) { - lbit = 1; - XSTRNCAT(tmp, "00", 3); - } - - rawLen = mp_unsigned_bin_size(rsaElem); - rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (rawKey == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - if (mp_to_unsigned_bin(rsaElem, rawKey) < 0) { - XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - for (idx = 0; idx < (word32)rawLen; idx++) { - char val[5]; - int valSz = 5; - - if ((idx == 0) && !lbit) { - XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]); - } - else if ((idx != 0) && (((idx + lbit) % 15) == 0)) { - tmp[sizeof(tmp) - 1] = '\0'; - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { - XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - XSNPRINTF(tmp, sizeof(tmp) - 1, - ":\n "); - XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]); - } - else { - XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]); - } - XSTRNCAT(tmp, val, valSz); - } - XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - /* print out remaining values */ - if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) { - tmp[sizeof(tmp) - 1] = '\0'; - if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { - return WOLFSSL_FAILURE; - } - } - lbit = 0; + else if (!mp_iszero(num)) { + /* Print name and MP integer. */ + ret = wolfssl_print_number(bio, num, name[i], indent); } - - } - /* done with print out */ - if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) { - return WOLFSSL_FAILURE; - } - - return WOLFSSL_SUCCESS; -} -#endif /* XSNPRINTF && !NO_BIO && !HAVE_FAST_RSA */ - -#if !defined(NO_FILESYSTEM) -#ifndef NO_WOLFSSL_STUB -WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x, - wc_pem_password_cb *cb, void *u) -{ - (void)fp; - (void)x; - (void)cb; - (void)u; - WOLFSSL_STUB("PEM_read_RSAPublicKey"); - WOLFSSL_MSG("wolfSSL_PEM_read_RSAPublicKey not implemented"); - - return NULL; -} -#endif - -/* return code compliant with OpenSSL : - * 1 if success, 0 if error - */ -#ifndef NO_WOLFSSL_STUB -int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x) -{ - (void)fp; - (void)x; - WOLFSSL_STUB("PEM_write_RSA_PUBKEY"); - WOLFSSL_MSG("wolfSSL_PEM_write_RSA_PUBKEY not implemented"); - - return WOLFSSL_FAILURE; -} -#endif - -#endif /* NO_FILESYSTEM */ - -WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp, - long len) -{ - WOLFSSL_RSA *rsa = NULL; - - WOLFSSL_ENTER("d2i_RSAPublicKey"); - - if (pp == NULL) { - WOLFSSL_MSG("Bad argument"); - return NULL; - } - if ((rsa = wolfSSL_RSA_new()) == NULL) { - WOLFSSL_MSG("RSA_new failed"); - return NULL; - } - - if (wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("RSA_LoadDer failed"); - wolfSSL_RSA_free(rsa); - rsa = NULL; - } - if (r != NULL) - *r = rsa; - - return rsa; -} - -/* Converts an RSA private key from DER format to an RSA structure. -Returns pointer to the RSA structure on success and NULL if error. */ -WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, - const unsigned char **derBuf, long derSz) -{ - WOLFSSL_RSA *rsa = NULL; - - WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey"); - - /* check for bad functions arguments */ - if (derBuf == NULL) { - WOLFSSL_MSG("Bad argument"); - return NULL; - } - if ((rsa = wolfSSL_RSA_new()) == NULL) { - WOLFSSL_MSG("RSA_new failed"); - return NULL; - } - - if (wolfSSL_RSA_LoadDer_ex(rsa, *derBuf, (int)derSz, - WOLFSSL_RSA_LOAD_PRIVATE) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("RSA_LoadDer failed"); - wolfSSL_RSA_free(rsa); - rsa = NULL; - } - if (r != NULL) - *r = rsa; - - return rsa; -} - -#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ - !defined(HAVE_USER_RSA) -/* Converts an internal RSA structure to DER format. - * If "pp" is null then buffer size only is returned. - * If "*pp" is null then a created buffer is set in *pp and the caller is - * responsible for free'ing it. - * Returns size of DER on success and WOLFSSL_FAILURE if error - */ -int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) -{ - int ret; - - WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey"); - - /* check for bad functions arguments */ - if (rsa == NULL) { - WOLFSSL_MSG("Bad Function Arguments"); - return BAD_FUNC_ARG; - } - - /* No heap hint as this gets returned to the user */ - if ((ret = wolfSSL_RSA_To_Der(rsa, pp, 0, NULL)) < 0) { - WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); - return WOLFSSL_FAILURE; - } - - return ret; /* returns size of DER if successful */ -} - - -int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, unsigned char **pp) -{ - int ret; - - /* check for bad functions arguments */ - if (rsa == NULL) { - WOLFSSL_MSG("Bad Function Arguments"); - return BAD_FUNC_ARG; - } - - /* No heap hint as this gets returned to the user */ - if ((ret = wolfSSL_RSA_To_Der(rsa, (byte**)pp, 1, NULL)) < 0) { - WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); - return WOLFSSL_FAILURE; } return ret; } -#endif /* !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && - * !defined(HAVE_USER_RSA) */ +#endif /* XSNPRINTF && !NO_BIO && !HAVE_FAST_RSA */ #endif /* OPENSSL_EXTRA */ +/* + * RSA get/set/test APIs + */ + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) -/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ -int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, - int derSz) +#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) +/* Set RSA key data (external) from wolfCrypt RSA key (internal). + * + * @param [in, out] rsa RSA key. + * @return 1 on success. + * @return 0 on failure. + */ +int SetRsaExternal(WOLFSSL_RSA* rsa) { - return wolfSSL_RSA_LoadDer_ex(rsa, derBuf, derSz, WOLFSSL_RSA_LOAD_PRIVATE); -} + int ret = 1; + WOLFSSL_ENTER("SetRsaExternal"); -int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf, - int derSz, int opt) -{ - int ret; - word32 idx = 0; - word32 algId; - - WOLFSSL_ENTER("wolfSSL_RSA_LoadDer"); - - if (rsa == NULL || rsa->internal == NULL || derBuf == NULL || derSz <= 0) { - WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + /* Validate parameters. */ + if ((rsa == NULL) || (rsa->internal == NULL)) { + WOLFSSL_MSG("rsa key NULL error"); + ret = -1; } - rsa->pkcs8HeaderSz = 0; - /* Check if input buffer has PKCS8 header. In the case that it does not - * have a PKCS8 header then do not error out. */ - if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz, - &algId)) > 0) { - WOLFSSL_MSG("Found PKCS8 header"); - rsa->pkcs8HeaderSz = (word16)idx; + if (ret == 1) { + RsaKey* key = (RsaKey*)rsa->internal; + + /* Copy modulus. */ + ret = SetIndividualExternal(&rsa->n, &key->n); + if (ret != 1) { + WOLFSSL_MSG("rsa n error"); + } + if (ret == 1) { + /* Copy public exponent. */ + ret = SetIndividualExternal(&rsa->e, &key->e); + if (ret != 1) { + WOLFSSL_MSG("rsa e error"); + } + } + + if (key->type == RSA_PRIVATE) { + if (ret == 1) { + /* Copy private exponent. */ + ret = SetIndividualExternal(&rsa->d, &key->d); + if (ret != 1) { + WOLFSSL_MSG("rsa d error"); + } + } + if (ret == 1) { + /* Copy first prime. */ + ret = SetIndividualExternal(&rsa->p, &key->p); + if (ret != 1) { + WOLFSSL_MSG("rsa p error"); + } + } + if (ret == 1) { + /* Copy second prime. */ + ret = SetIndividualExternal(&rsa->q, &key->q); + if (ret != 1) { + WOLFSSL_MSG("rsa q error"); + } + } + #ifndef RSA_LOW_MEM + if (ret == 1) { + /* Copy d mod p-1. */ + ret = SetIndividualExternal(&rsa->dmp1, &key->dP); + if (ret != 1) { + WOLFSSL_MSG("rsa dP error"); + } + } + if (ret == 1) { + /* Copy d mod q-1. */ + ret = SetIndividualExternal(&rsa->dmq1, &key->dQ); + if (ret != 1) { + WOLFSSL_MSG("rsa dq error"); + } + } + if (ret == 1) { + /* Copy 1/q mod p. */ + ret = SetIndividualExternal(&rsa->iqmp, &key->u); + if (ret != 1) { + WOLFSSL_MSG("rsa u error"); + } + } + #endif /* !RSA_LOW_MEM */ + } + } + if (ret == 1) { + /* External values set. */ + rsa->exSet = 1; } else { - if (ret != ASN_PARSE_E) { - WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header"); - return WOLFSSL_FATAL_ERROR; + /* Return 0 on failure. */ + ret = 0; + } + + return ret; +} +#endif /* !HAVE_USER_RSA && !HAVE_FAST_RSA */ +#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ + +#ifdef OPENSSL_EXTRA + +#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) +/* Set wolfCrypt RSA key data (internal) from RSA key (external). + * + * @param [in, out] rsa RSA key. + * @return 1 on success. + * @return 0 on failure. + */ +int SetRsaInternal(WOLFSSL_RSA* rsa) +{ + int ret = 1; + + WOLFSSL_ENTER("SetRsaInternal"); + + /* Validate parameters. */ + if ((rsa == NULL) || (rsa->internal == NULL)) { + WOLFSSL_MSG("rsa key NULL error"); + ret = -1; + } + + if (ret == 1) { + RsaKey* key = (RsaKey*)rsa->internal; + + /* Copy down modulus if available. */ + if ((rsa->n != NULL) && (SetIndividualInternal(rsa->n, &key->n) != 1)) { + WOLFSSL_MSG("rsa n key error"); + ret = -1; + } + + /* Copy down public exponent if available. */ + if ((ret == 1) && (rsa->e != NULL) && + (SetIndividualInternal(rsa->e, &key->e) != 1)) { + WOLFSSL_MSG("rsa e key error"); + ret = -1; + } + + /* Enough numbers for public key */ + key->type = RSA_PUBLIC; + + /* Copy down private exponent if available. */ + if ((ret == 1) && (rsa->d != NULL)) { + if (SetIndividualInternal(rsa->d, &key->d) != 1) { + WOLFSSL_MSG("rsa d key error"); + ret = -1; + } + else { + /* Enough numbers for private key */ + key->type = RSA_PRIVATE; + } + } + + /* Copy down first prime if available. */ + if ((ret == 1) && (rsa->p != NULL) && + (SetIndividualInternal(rsa->p, &key->p) != 1)) { + WOLFSSL_MSG("rsa p key error"); + ret = -1; + } + + /* Copy down second prime if available. */ + if ((ret == 1) && (rsa->q != NULL) && + (SetIndividualInternal(rsa->q, &key->q) != 1)) { + WOLFSSL_MSG("rsa q key error"); + ret = -1; + } + + #ifndef RSA_LOW_MEM + /* Copy down d mod p-1 if available. */ + if ((ret == 1) && (rsa->dmp1 != NULL) && + (SetIndividualInternal(rsa->dmp1, &key->dP) != 1)) { + WOLFSSL_MSG("rsa dP key error"); + ret = -1; + } + + /* Copy down d mod q-1 if available. */ + if ((ret == 1) && (rsa->dmp1 != NULL) && + (SetIndividualInternal(rsa->dmq1, &key->dQ) != 1)) { + WOLFSSL_MSG("rsa dQ key error"); + ret = -1; + } + + /* Copy down 1/q mod p if available. */ + if ((ret == 1) && (rsa->iqmp != NULL) && + (SetIndividualInternal(rsa->iqmp, &key->u) != 1)) { + WOLFSSL_MSG("rsa u key error"); + ret = -1; + } + #endif /* !RSA_LOW_MEM */ + + if (ret == 1) { + /* All available numbers have been set down. */ + rsa->inSet = 1; } } - if (opt == WOLFSSL_RSA_LOAD_PRIVATE) { - ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, - derSz); + return ret; +} + +#endif /* HAVE_USER_RSA */ + +/* Set the RSA method into object. + * + * @param [in, out] rsa RSA key. + * @param [in] meth RSA method. + * @return 1 always. + */ +int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth) +{ + if (rsa != NULL) { + /* Store the method into object. */ + rsa->meth = meth; + /* Copy over flags. */ + rsa->flags = meth->flags; } - else { - ret = wc_RsaPublicKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, - derSz); + /* OpenSSL always assumes it will work. */ + return 1; +} + +/* Get the RSA method from the RSA object. + * + * @param [in] rsa RSA key. + * @return RSA method on success. + * @return NULL when RSA is NULL or no method set. + */ +const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa) +{ + return (rsa != NULL) ? rsa->meth : NULL; +} + +/* Get the size in bytes of the RSA key. + * + * Return compliant with OpenSSL + * + * @param [in] rsa RSA key. + * @return RSA modulus size in bytes. + * @return 0 on error. + */ +int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa) +{ + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_RSA_size"); + + if (rsa != NULL) { + /* Make sure we have set the RSA values into wolfCrypt RSA key. */ + if (rsa->inSet || (SetRsaInternal((WOLFSSL_RSA*)rsa) == 1)) { + /* Get key size in bytes using wolfCrypt RSA key. */ + ret = wc_RsaEncryptSize((RsaKey*)rsa->internal); + } } - if (ret < 0) { - if (opt == WOLFSSL_RSA_LOAD_PRIVATE) { - WOLFSSL_MSG("RsaPrivateKeyDecode failed"); + return ret; +} + +/* Get the size in bits of the RSA key. + * + * Uses external modulus field. + * + * @param [in] rsa RSA key. + * @return RSA modulus size in bits. + * @return 0 on error. + */ +int wolfSSL_RSA_bits(const WOLFSSL_RSA* rsa) +{ + int ret = 0; + + WOLFSSL_ENTER("wolfSSL_RSA_bits"); + + if (rsa != NULL) { + /* Get number of bits in external modulus. */ + ret = wolfSSL_BN_num_bits(rsa->n); + } + + return ret; +} + +#ifndef HAVE_USER_RSA + +/* Get the BN objects that are the Chinese-Remainder Theorem (CRT) parameters. + * + * Only for those that are not NULL parameters. + * + * @param [in] rsa RSA key. + * @param [out] dmp1 BN that is d mod (p - 1). May be NULL. + * @param [out] dmq1 BN that is d mod (q - 1). May be NULL. + * @param [out] iqmp BN that is 1/q mod p. May be NULL. + */ +void wolfSSL_RSA_get0_crt_params(const WOLFSSL_RSA *rsa, + const WOLFSSL_BIGNUM **dmp1, const WOLFSSL_BIGNUM **dmq1, + const WOLFSSL_BIGNUM **iqmp) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get0_crt_params"); + + /* For any parameters not NULL, return the BN from the key or NULL. */ + if (dmp1 != NULL) { + *dmp1 = (rsa != NULL) ? rsa->dmp1 : NULL; + } + if (dmq1 != NULL) { + *dmq1 = (rsa != NULL) ? rsa->dmq1 : NULL; + } + if (iqmp != NULL) { + *iqmp = (rsa != NULL) ? rsa->iqmp : NULL; + } +} + +/* Set the BN objects that are the Chinese-Remainder Theorem (CRT) parameters + * into RSA key. + * + * If CRT parameter is NULL then there must be one in the RSA key already. + * + * @param [in, out] rsa RSA key. + * @param [in] dmp1 BN that is d mod (p - 1). May be NULL. + * @param [in] dmq1 BN that is d mod (q - 1). May be NULL. + * @param [in] iqmp BN that is 1/q mod p. May be NULL. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_set0_crt_params(WOLFSSL_RSA *rsa, WOLFSSL_BIGNUM *dmp1, + WOLFSSL_BIGNUM *dmq1, WOLFSSL_BIGNUM *iqmp) +{ + int ret = 1; + + WOLFSSL_ENTER("wolfSSL_RSA_set0_crt_params"); + + /* If a param is NULL in rsa then it must be non-NULL in the + * corresponding user input. */ + if ((rsa == NULL) || ((rsa->dmp1 == NULL) && (dmp1 == NULL)) || + ((rsa->dmq1 == NULL) && (dmq1 == NULL)) || + ((rsa->iqmp == NULL) && (iqmp == NULL))) { + WOLFSSL_MSG("Bad parameters"); + ret = 0; + } + if (ret == 1) { + /* Replace the BNs. */ + if (dmp1 != NULL) { + wolfSSL_BN_clear_free(rsa->dmp1); + rsa->dmp1 = dmp1; + } + if (dmq1 != NULL) { + wolfSSL_BN_clear_free(rsa->dmq1); + rsa->dmq1 = dmq1; + } + if (iqmp != NULL) { + wolfSSL_BN_clear_free(rsa->iqmp); + rsa->iqmp = iqmp; + } + + /* Set the values into the wolfCrypt RSA key. */ + if (SetRsaInternal(rsa) != 1) { + ret = 0; + } + } + + return ret; +} + +/* Get the BN objects that are the factors of the RSA key (two primes p and q). + * + * @param [in] rsa RSA key. + * @param [out] p BN that is first prime. May be NULL. + * @param [out] q BN that is second prime. May be NULL. + */ +void wolfSSL_RSA_get0_factors(const WOLFSSL_RSA *rsa, const WOLFSSL_BIGNUM **p, + const WOLFSSL_BIGNUM **q) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get0_factors"); + + /* For any primes not NULL, return the BN from the key or NULL. */ + if (p != NULL) { + *p = (rsa != NULL) ? rsa->p : NULL; + } + if (q != NULL) { + *q = (rsa != NULL) ? rsa->q : NULL; + } +} + +/* Set the BN objects that are the factors of the RSA key (two primes p and q). + * + * If factor parameter is NULL then there must be one in the RSA key already. + * + * @param [in, out] rsa RSA key. + * @param [in] p BN that is first prime. May be NULL. + * @param [in] q BN that is second prime. May be NULL. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_set0_factors(WOLFSSL_RSA *rsa, WOLFSSL_BIGNUM *p, + WOLFSSL_BIGNUM *q) +{ + int ret = 1; + + WOLFSSL_ENTER("wolfSSL_RSA_set0_factors"); + + /* If a param is null in r then it must be non-null in the + * corresponding user input. */ + if (rsa == NULL || ((rsa->p == NULL) && (p == NULL)) || + ((rsa->q == NULL) && (q == NULL))) { + WOLFSSL_MSG("Bad parameters"); + ret = 0; + } + if (ret == 1) { + /* Replace the BNs. */ + if (p != NULL) { + wolfSSL_BN_clear_free(rsa->p); + rsa->p = p; + } + if (q != NULL) { + wolfSSL_BN_clear_free(rsa->q); + rsa->q = q; + } + + /* Set the values into the wolfCrypt RSA key. */ + if (SetRsaInternal(rsa) != 1) { + ret = 0; + } + } + + return ret; +} + +/* Get the BN objects for the basic key numbers of the RSA key (modulus, public + * exponenet, private exponent). + * + * @param [in] rsa RSA key. + * @param [out] n BN that is the modulus. May be NULL. + * @param [out] e BN that is the public exponent. May be NULL. + * @param [out] d BN that is the private exponent. May be NULL. + */ +void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *rsa, const WOLFSSL_BIGNUM **n, + const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get0_key"); + + /* For any parameters not NULL, return the BN from the key or NULL. */ + if (n != NULL) { + *n = (rsa != NULL) ? rsa->n : NULL; + } + if (e != NULL) { + *e = (rsa != NULL) ? rsa->e : NULL; + } + if (d != NULL) { + *d = (rsa != NULL) ? rsa->d : NULL; + } +} + +/* Set the BN objects for the basic key numbers into the RSA key (modulus, + * public exponenet, private exponent). + * + * If BN parameter is NULL then there must be one in the RSA key already. + * + * @param [in,out] rsa RSA key. + * @param [in] n BN that is the modulus. May be NULL. + * @param [in] e BN that is the public exponent. May be NULL. + * @param [in] d BN that is the private exponent. May be NULL. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_set0_key(WOLFSSL_RSA *rsa, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, + WOLFSSL_BIGNUM *d) +{ + int ret = 1; + + /* If the fields n and e in r are NULL, the corresponding input + * parameters MUST be non-NULL for n and e. d may be + * left NULL (in case only the public key is used). + */ + if ((rsa == NULL) || ((rsa->n == NULL) && (n == NULL)) || + ((rsa->e == NULL) && (e == NULL))) { + ret = 0; + } + if (ret == 1) { + /* Replace the BNs. */ + if (n != NULL) { + wolfSSL_BN_free(rsa->n); + rsa->n = n; + } + if (e != NULL) { + wolfSSL_BN_free(rsa->e); + rsa->e = e; + } + if (d != NULL) { + /* Private key is sensitive data. */ + wolfSSL_BN_clear_free(rsa->d); + rsa->d = d; + } + + /* Set the values into the wolfCrypt RSA key. */ + if (SetRsaInternal(rsa) != 1) { + ret = 0; + } + } + + return ret; +} + +#endif /* !HAVE_USER_RSA */ + +/* Get the flags of the RSA key. + * + * @param [in] rsa RSA key. + * @return Flags set in RSA key on success. + * @return 0 when RSA key is NULL. + */ +int wolfSSL_RSA_flags(const WOLFSSL_RSA *rsa) +{ + int ret = 0; + + /* Get flags from the RSA key if available. */ + if (rsa != NULL) { + ret = rsa->flags; + } + + return ret; +} + +/* Set the flags into the RSA key. + * + * @param [in, out] rsa RSA key. + * @param [in] flags Flags to set. + */ +void wolfSSL_RSA_set_flags(WOLFSSL_RSA *rsa, int flags) +{ + /* Add the flags into RSA key if available. */ + if (rsa != NULL) { + rsa->flags |= flags; + } +} + +/* Clear the flags in the RSA key. + * + * @param [in, out] rsa RSA key. + * @param [in] flags Flags to clear. + */ +void wolfSSL_RSA_clear_flags(WOLFSSL_RSA *rsa, int flags) +{ + /* Clear the flags passed in that are on the RSA key if available. */ + if (rsa != NULL) { + rsa->flags &= ~flags; + } +} + +/* Test the flags in the RSA key. + * + * @param [in] rsa RSA key. + * @return Matching flags of RSA key on success. + * @return 0 when RSA keyis NULL. + */ +int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *rsa, int flags) +{ + /* Return the flags passed in that are set on the RSA key if available. */ + return (rsa != NULL) ? (rsa->flags & flags) : 0; +} + +/* Get the extra data, by index, associated with the RSA key. + * + * @param [in] rsa RSA key. + * @param [in] idx Index of extra data. + * @return Extra data (anonymous type) on success. + * @return NULL on failure. + */ +void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data"); + +#ifdef HAVE_EX_DATA + return (rsa == NULL) ? NULL : + wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx); +#else + (void)rsa; + (void)idx; + + return NULL; +#endif +} + +/* Set extra data against the RSA key at an index. + * + * @param [in, out] rsa RSA key. + * @param [in] idx Index set set extra data at. + * @param [in] data Extra data of anonymous type. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data) +{ + WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data"); + +#ifdef HAVE_EX_DATA + return (rsa == NULL) ? 0 : + wolfSSL_CRYPTO_set_ex_data(&rsa->ex_data, idx, data); +#else + (void)rsa; + (void)idx; + (void)data; + + return 0; +#endif +} + +#ifdef HAVE_EX_DATA_CLEANUP_HOOKS +/* Set the extra data and cleanup callback against the RSA key at an index. + * + * wolfSSL API. + * + * @param [in, out] rsa RSA key. + * @param [in] idx Index set set extra data at. + * @param [in] data Extra data of anonymous type. + * @param [in] freeCb Callback function to free extra data. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_set_ex_data_with_cleanup(WOLFSSL_RSA *rsa, int idx, void *data, + wolfSSL_ex_data_cleanup_routine_t freeCb) +{ + WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data_with_cleanup"); + + return (rsa == NULL) ? NULL : + wolfSSL_CRYPTO_set_ex_data_with_cleanup(&rsa->ex_data, idx, data, + freeCb); +} +#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */ + +/* + * RSA check key APIs + */ + +/* If not using old FIPS or CAVP selftest or not using fast or user RSA, able + * to check RSA key. */ +#if (defined(HAVE_USER_RSA) || defined(HAVE_FAST_RSA) || \ + defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(HAVE_INTEL_QA) || \ + !defined(WOLFSSL_KEY_GEN) || (defined(HAVE_FIPS) && \ + FIPS_VERSION_LT(2, 0)) || defined(HAVE_SELFTEST)) && \ + !defined(WOLFSSL_NO_RSA_KEY_CHECK) +#define WOLFSSL_NO_RSA_KEY_CHECK +#endif + + +#ifndef WOLFSSL_NO_RSA_KEY_CHECK +/* Check that the RSA key is valid using wolfCrypt. + * + * @param [in] rsa RSA key. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_check_key(const WOLFSSL_RSA* rsa) +{ + int ret = 1; + + WOLFSSL_ENTER("wolfSSL_RSA_check_key"); + + /* Validate parameters. */ + if ((rsa == NULL) || (rsa->internal == NULL)) { + ret = 0; + } + + /* Constant RSA - assume internal data has been set. */ + + /* Check wolfCrypt RSA key. */ + if ((ret == 1) && (wc_CheckRsaKey((RsaKey*)rsa->internal) != 0)) { + ret = 0; + } + + WOLFSSL_LEAVE("wolfSSL_RSA_check_key", ret); + + return ret; +} +#endif /* !WOLFSSL_NO_RSA_KEY_CHECK */ + +/* + * RSA generate APIs + */ + +#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) +/* Get a random number generator associated with the RSA key. + * + * If not able, then get the global if possible. + * *tmpRng must not be an initialized RNG. + * *tmpRng is allocated when WOLFSSL_SMALL_STACK is defined and an RNG isn't + * associated with the wolfCrypt RSA key. + * + * @param [in] rsa RSA key. + * @param [out] tmpRng Temporary random number generator. + * @param [out] initTmpRng Temporary random number generator was initialized. + * + * @return A wolfCrypt RNG to use on success. + * @return NULL on error. + */ +WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA* rsa, WC_RNG** tmpRng, int* initTmpRng) +{ + WC_RNG* rng = NULL; + int err = 0; + + /* Check validity of parameters. */ + if ((rsa == NULL) || (initTmpRng == NULL)) { + err = 1; + } + if (!err) { + /* Haven't initialized any RNG passed through tmpRng. */ + *initTmpRng = 0; + + #if !defined(HAVE_FIPS) && defined(WC_RSA_BLINDING) + /* Use wolfCrypt RSA key's RNG if available/set. */ + rng = ((RsaKey*)rsa->internal)->rng; + #endif + } + if ((!err) && (rng == NULL) && (tmpRng != NULL)) { + #ifdef WOLFSSL_SMALL_STACK + /* Allocate RNG object . */ + rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); + #else + /* Use object in *tmpRng. */ + rng = *tmpRng; + #endif + /* Initialize RNG object passed in or allocated. */ + if ((rng != NULL) && (wc_InitRng(rng) == 0)) { + #ifdef WOLFSSL_SMALL_STACK + /* Return RNG through tmpRng as well. */ + *tmpRng = rng; + #endif + /* Indicate RNG object must be finalized before freeing. */ + *initTmpRng = 1; + } + if (*tmpRng == NULL) { + WOLFSSL_MSG("Couldn't use local RNG, trying global"); + #ifdef WOLFSSL_SMALL_STACK + /* Dispose of allocated RNG and *tmpRng stays NULL. */ + XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + rng = wolfssl_get_global_rng(); + } + } + + return rng; +} +#endif + +/* Use the wolfCrypt RSA APIs to generate a new RSA key. + * + * @param [in, out] rsa RSA key. + * @param [in] bits Numner of bits that the modulus must have. + * @param [in] e A BN object holding the public exponent to use. + * @param [in] cb Status callback. Unused. + * @return 0 on success. + * @return wolfSSL native error code on error. + */ +static int wolfssl_rsa_generate_key_native(WOLFSSL_RSA* rsa, int bits, + WOLFSSL_BIGNUM* e, void* cb) +{ +#ifdef WOLFSSL_KEY_GEN + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG* tmpRng = NULL; +#else + WC_RNG _tmpRng[1]; + WC_RNG* tmpRng = _tmpRng; +#endif + int initTmpRng = 0; + WC_RNG* rng = NULL; +#endif + + (void)cb; + + WOLFSSL_ENTER("wolfssl_rsa_generate_key_native"); + +#ifdef WOLFSSL_KEY_GEN + /* Get RNG in wolfCrypt RSA key or initialize a new one (or global). */ + rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng); + if (rng == NULL) { + /* Something went wrong so return memory error. */ + ret = MEMORY_E; + } + if (ret == 0) { + /* Generate an RSA key. */ + ret = wc_MakeRsaKey((RsaKey*)rsa->internal, bits, + (long)wolfSSL_BN_get_word(e), rng); + if (ret != MP_OKAY) { + WOLFSSL_MSG("wc_MakeRsaKey failed"); + } + } + if (ret == 0) { + /* Get the values from wolfCrypt RSA key into external RSA key. */ + ret = SetRsaExternal(rsa); + if (ret == 1) { + /* Internal matches external. */ + rsa->inSet = 1; + /* Return success. */ + ret = 0; } else { - WOLFSSL_MSG("RsaPublicKeyDecode failed"); + /* Something went wrong so return memory error. */ + ret = MEMORY_E; } - return WOLFSSL_FATAL_ERROR; } - if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaExternal failed"); - return WOLFSSL_FATAL_ERROR; + /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */ + if (initTmpRng) { + wc_FreeRng(tmpRng); } +#ifdef WOLFSSL_SMALL_STACK + /* Dispose of any allocated RNG. */ + XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif - rsa->inSet = 1; + return ret; +#else + WOLFSSL_MSG("No Key Gen built in"); - return WOLFSSL_SUCCESS; + (void)rsa; + (void)e; + (void)bits; + + return NOT_COMPILED_IN; +#endif } +/* Generate an RSA key that has the specified modulus size and public exponent. + * + * Note: Because of wc_MakeRsaKey an RSA key size generated can be rounded + * down to nearest multiple of 8. For example generating a key of size + * 2999 bits will make a key of size 374 bytes instead of 375 bytes. + * + * @param [in] bits Numner of bits that the modulus must have i.e. 2048. + * @param [in] e Public exponent to use i.e. 65537. + * @param [in] cb Status callback. Unused. + * @param [in] data Data to pass to status callback. Unused. + * @return A new RSA key on success. + * @return NULL on failure. + */ +WOLFSSL_RSA* wolfSSL_RSA_generate_key(int bits, unsigned long e, + void(*cb)(int, int, void*), void* data) +{ + WOLFSSL_RSA* rsa = NULL; + WOLFSSL_BIGNUM* bn = NULL; + int err = 0; + + WOLFSSL_ENTER("wolfSSL_RSA_generate_key"); + + (void)cb; + (void)data; + + /* Validate bits. */ + if (bits < 0) { + WOLFSSL_MSG("Bad argument: bits was less than 0"); + err = 1; + } + /* Create a new BN to hold public exponent - for when wolfCrypt supports + * longer values. */ + if ((!err) && ((bn = wolfSSL_BN_new()) == NULL)) { + WOLFSSL_MSG("Error creating big number"); + err = 1; + } + /* Set public exponent. */ + if ((!err) && (wolfSSL_BN_set_word(bn, e) != 1)) { + WOLFSSL_MSG("Error using e value"); + err = 1; + } + + /* Create an RSA key object to hold generated key. */ + if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) { + WOLFSSL_MSG("memory error"); + err = 1; + } + while (!err) { + int ret; + + /* Use wolfCrypt to generate RSA key. */ + ret = wolfssl_rsa_generate_key_native(rsa, bits, bn, NULL); + #ifdef HAVE_FIPS + /* Keep trying if failed to find a prime. */ + if (ret == PRIME_GEN_E) { + continue; + } + #endif + if (ret != WOLFSSL_ERROR_NONE) { + /* Unrecoverable error in generation. */ + err = 1; + } + /* Done generating - unrecoverable error or success. */ + break; + } + if (err) { + /* Dispose of RSA key object if generation didn't work. */ + wolfSSL_RSA_free(rsa); + /* Returning NULL on error. */ + rsa = NULL; + } + /* Dispose of the temporary BN used for the public exponent. */ + wolfSSL_BN_free(bn); + + return rsa; +} + +/* Generate an RSA key that has the specified modulus size and public exponent. + * + * Note: Because of wc_MakeRsaKey an RSA key size generated can be rounded + * down to nearest multiple of 8. For example generating a key of size + * 2999 bits will make a key of size 374 bytes instead of 375 bytes. + * + * @param [in] bits Numner of bits that the modulus must have i.e. 2048. + * @param [in] e Public exponent to use, i.e. 65537, as a BN. + * @param [in] cb Status callback. Unused. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* e, + void* cb) +{ + int ret = 1; + + /* Validate parameters. */ + if ((rsa == NULL) || (rsa->internal == NULL)) { + WOLFSSL_MSG("bad arguments"); + ret = 0; + } + else { + for (;;) { + /* Use wolfCrypt to generate RSA key. */ + int gen_ret = wolfssl_rsa_generate_key_native(rsa, bits, e, cb); + #ifdef HAVE_FIPS + /* Keep trying again if public key value didn't work. */ + if (gen_ret == PRIME_GEN_E) { + continue; + } + #endif + if (gen_ret != WOLFSSL_ERROR_NONE) { + /* Unrecoverable error in generation. */ + ret = 0; + } + /* Done generating - unrecoverable error or success. */ + break; + } + } + + return ret; +} + +#endif /* OPENSSL_EXTRA */ + +/* + * RSA padding APIs + */ + #if defined(WC_RSA_PSS) && (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || \ defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) -/* +#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) +/* Add PKCS#1 PSS padding to hash. + * + * * +-----------+ * | M | * +-----------+ @@ -1756,1272 +2914,1210 @@ int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf, * EM = | maskedDB |maskedseed|bc| * +-------------------+----------+--+ * Diagram taken from https://tools.ietf.org/html/rfc3447#section-9.1 + * + * @param [in] rsa RSA key. + * @param [out] em Encoded message. + * @param [in[ mHash Message hash. + * @param [in] hashAlg Hash algorithm. + * @param [in] saltLen Length of salt to generate. + * @return 1 on success. + * @return 0 on failure. */ -int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *EM, +int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em, const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, int saltLen) { - int hashLen, emLen, mgf; - int ret = WOLFSSL_FAILURE; + int ret = 1; + enum wc_HashType hashType; + int hashLen; + int emLen; + int mgf; int initTmpRng = 0; WC_RNG *rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRng = NULL; #else - WC_RNG _tmpRNG[1]; - WC_RNG* tmpRNG = _tmpRNG; + WC_RNG _tmpRng[1]; + WC_RNG* tmpRng = _tmpRng; #endif - enum wc_HashType hashType; WOLFSSL_ENTER("wolfSSL_RSA_padding_add_PKCS1_PSS"); - if (!rsa || !EM || !mHash || !hashAlg) { - return WOLFSSL_FAILURE; + /* Validate parameters. */ + if ((rsa == NULL) || (em == NULL) || (mHash == NULL) || (hashAlg == NULL)) { + ret = 0; } - if (!(rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRNG, &initTmpRng))) { - WOLFSSL_MSG("WOLFSSL_RSA_GetRNG error"); - goto cleanup; + if (ret == 1) { + /* Get/create an RNG. */ + rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng); + if (rng == NULL) { + WOLFSSL_MSG("WOLFSSL_RSA_GetRNG error"); + ret = 0; + } } - if (!rsa->exSet && SetRsaExternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaExternal error"); - goto cleanup; + /* TODO: use wolfCrypt RSA key to get emLen and bits? */ + /* Set the external data from the wolfCrypt RSA key if not done. */ + if ((ret == 1) && (!rsa->exSet)) { + ret = SetRsaExternal(rsa); } - hashType = EvpMd2MacType(hashAlg); - if (hashType > WC_HASH_TYPE_MAX) { - WOLFSSL_MSG("EvpMd2MacType error"); - goto cleanup; + if (ret == 1) { + /* Get the wolfCrypt hash algorithm type. */ + hashType = EvpMd2MacType(hashAlg); + if (hashType > WC_HASH_TYPE_MAX) { + WOLFSSL_MSG("EvpMd2MacType error"); + ret = 0; + } + } + if (ret == 1) { + /* Get the wolfCrypt MGF algorithm from hash algorithm. */ + mgf = wc_hash2mgf(hashType); + if (mgf == WC_MGF1NONE) { + WOLFSSL_MSG("wc_hash2mgf error"); + ret = 0; + } + } + if (ret == 1) { + /* Get the length of the hash output. */ + hashLen = wolfSSL_EVP_MD_size(hashAlg); + if (hashLen < 0) { + WOLFSSL_MSG("wolfSSL_EVP_MD_size error"); + ret = 0; + } } - if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) { - WOLFSSL_MSG("wc_hash2mgf error"); - goto cleanup; - } - - if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) { - WOLFSSL_MSG("wolfSSL_EVP_MD_size error"); - goto cleanup; + if (ret == 1) { + /* Get length of RSA key - encrypted message length. */ + emLen = wolfSSL_RSA_size(rsa); + if (ret <= 0) { + WOLFSSL_MSG("wolfSSL_RSA_size error"); + ret = 0; + } } - if ((emLen = wolfSSL_RSA_size(rsa)) <= 0) { - WOLFSSL_MSG("wolfSSL_RSA_size error"); - goto cleanup; - } - - switch (saltLen) { - /* Negative saltLen values are treated differently */ + if (ret == 1) { + /* Calculate the salt length to use for special cases. */ + /* TODO: use special case wolfCrypt values? */ + switch (saltLen) { + /* Negative saltLen values are treated differently. */ case RSA_PSS_SALTLEN_DIGEST: saltLen = hashLen; break; case RSA_PSS_SALTLEN_MAX_SIGN: case RSA_PSS_SALTLEN_MAX: + #ifdef WOLFSSL_PSS_LONG_SALT saltLen = emLen - hashLen - 2; + #else + saltLen = hashLen; + #endif break; default: if (saltLen < 0) { - /* Not any currently implemented negative value */ + /* No other negative values implemented. */ WOLFSSL_MSG("invalid saltLen"); - goto cleanup; + ret = 0; } + } } - if (wc_RsaPad_ex(mHash, hashLen, EM, emLen, - RSA_BLOCK_TYPE_1, rng, WC_RSA_PSS_PAD, - hashType, mgf, NULL, 0, saltLen, - wolfSSL_BN_num_bits(rsa->n), NULL) != MP_OKAY) { - WOLFSSL_MSG("wc_RsaPad_ex error"); - goto cleanup; + if (ret == 1) { + /* Generate RSA PKCS#1 PSS padding for hash using wolfCrypt. */ + if (wc_RsaPad_ex(mHash, hashLen, em, emLen, RSA_BLOCK_TYPE_1, rng, + WC_RSA_PSS_PAD, hashType, mgf, NULL, 0, saltLen, + wolfSSL_BN_num_bits(rsa->n), NULL) != MP_OKAY) { + WOLFSSL_MSG("wc_RsaPad_ex error"); + ret = 0; + } } - ret = WOLFSSL_SUCCESS; -cleanup: - if (initTmpRng) - wc_FreeRng(tmpRNG); + /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */ + if (initTmpRng) { + wc_FreeRng(tmpRng); + } #ifdef WOLFSSL_SMALL_STACK - if (tmpRNG) - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); + /* Dispose of any allocated RNG. */ + XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; } -/* - * Refer to wolfSSL_RSA_padding_add_PKCS1_PSS - * for an explanation of the parameters. +/* Checks that the hash is valid for the RSA PKCS#1 PSS encoded message. + * + * Refer to wolfSSL_RSA_padding_add_PKCS1_PSS for a diagram. + * + * @param [in] rsa RSA key. + * @param [in[ mHash Message hash. + * @param [in] hashAlg Hash algorithm. + * @param [in] em Encoded message. + * @param [in] saltLen Length of salt to generate. + * @return 1 on success. + * @return 0 on failure. */ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, - const unsigned char *EM, int saltLen) + const unsigned char *em, int saltLen) { - int hashLen, mgf, emLen, mPrimeLen; + int ret = 1; + int hashLen; + int mgf; + int emLen; + int mPrimeLen; enum wc_HashType hashType; byte *mPrime = NULL; byte *buf = NULL; WOLFSSL_ENTER("wolfSSL_RSA_verify_PKCS1_PSS"); - if (!rsa || !mHash || !hashAlg || !EM) { - return WOLFSSL_FAILURE; + /* Validate parameters. */ + if ((rsa == NULL) || (mHash == NULL) || (hashAlg == NULL) || (em == NULL)) { + ret = 0; } - if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) { - return WOLFSSL_FAILURE; + /* TODO: use wolfCrypt RSA key to get emLen and bits? */ + /* Set the external data from the wolfCrypt RSA key if not done. */ + if ((ret == 1) && (!rsa->exSet)) { + ret = SetRsaExternal(rsa); } - if ((emLen = wolfSSL_RSA_size(rsa)) <= 0) { - WOLFSSL_MSG("wolfSSL_RSA_size error"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Get hash length for hash algorithm. */ + hashLen = wolfSSL_EVP_MD_size(hashAlg); + if (hashLen < 0) { + ret = 0; + } } - switch (saltLen) { - /* Negative saltLen values are treated differently */ + if (ret == 1) { + /* Get length of RSA key - encrypted message length. */ + emLen = wolfSSL_RSA_size(rsa); + if (emLen <= 0) { + WOLFSSL_MSG("wolfSSL_RSA_size error"); + ret = 0; + } + } + + if (ret == 1) { + /* Calculate the salt length to use for special cases. */ + /* TODO: use special case wolfCrypt values. */ + switch (saltLen) { + /* Negative saltLen values are treated differently */ case RSA_PSS_SALTLEN_DIGEST: saltLen = hashLen; break; case RSA_PSS_SALTLEN_MAX_SIGN: case RSA_PSS_SALTLEN_MAX: + #ifdef WOLFSSL_PSS_LONG_SALT saltLen = emLen - hashLen - 2; + #else + saltLen = hashLen; + #endif break; default: if (saltLen < 0) { - /* Not any currently implemented negative value */ + /* No other negative values implemented. */ WOLFSSL_MSG("invalid saltLen"); - return WOLFSSL_FAILURE; + ret = 0; } + } } - if (!rsa->exSet && SetRsaExternal(rsa) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Get the wolfCrypt hash algorithm type. */ + hashType = EvpMd2MacType(hashAlg); + if (hashType > WC_HASH_TYPE_MAX) { + WOLFSSL_MSG("EvpMd2MacType error"); + ret = 0; + } } - hashType = EvpMd2MacType(hashAlg); - if (hashType > WC_HASH_TYPE_MAX) { - WOLFSSL_MSG("EvpMd2MacType error"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Get the wolfCrypt MGF algorithm from hash algorithm. */ + if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) { + WOLFSSL_MSG("wc_hash2mgf error"); + ret = 0; + } } - if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) { - WOLFSSL_MSG("wc_hash2mgf error"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Allocate buffer to unpad inline with. */ + buf = (byte*)XMALLOC(emLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (buf == NULL) { + WOLFSSL_MSG("malloc error"); + ret = 0; + } } - if ((hashLen = wolfSSL_EVP_MD_size(hashAlg)) < 0) { - WOLFSSL_MSG("wolfSSL_EVP_MD_size error"); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Copy encrypted message to temp for inline unpadding. */ + XMEMCPY(buf, em, emLen); + + /* Remove and verify the PSS padding. */ + mPrimeLen = wc_RsaUnPad_ex(buf, emLen, &mPrime, RSA_BLOCK_TYPE_1, + WC_RSA_PSS_PAD, hashType, mgf, NULL, 0, saltLen, + wolfSSL_BN_num_bits(rsa->n), NULL); + if (mPrimeLen < 0) { + WOLFSSL_MSG("wc_RsaPad_ex error"); + ret = 0; + } } - if (!(buf = (byte*)XMALLOC(emLen, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { - WOLFSSL_MSG("malloc error"); - return WOLFSSL_FAILURE; - } - XMEMCPY(buf, EM, emLen); - - /* Remove and verify the PSS padding */ - if ((mPrimeLen = wc_RsaUnPad_ex(buf, emLen, &mPrime, - RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, hashType, - mgf, NULL, 0, saltLen, - wolfSSL_BN_num_bits(rsa->n), NULL)) < 0) { - WOLFSSL_MSG("wc_RsaPad_ex error"); - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + if (ret == 1) { + /* Verify the hash is correct. */ + if (wc_RsaPSS_CheckPadding_ex(mHash, hashLen, mPrime, mPrimeLen, + hashType, saltLen, wolfSSL_BN_num_bits(rsa->n)) != MP_OKAY) { + WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error"); + ret = 0; + } } - /* Verify the hash is correct */ - if (wc_RsaPSS_CheckPadding_ex(mHash, hashLen, mPrime, mPrimeLen, hashType, - saltLen, wolfSSL_BN_num_bits(rsa->n)) - != MP_OKAY) { - WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error"); - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } + /* Dispose of any allocated buffer. */ XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_SUCCESS; + return ret; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* WC_RSA_PSS && (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY - * || WOLFSSL_NGINX) - */ +#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */ +#endif /* WC_RSA_PSS && (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || + * WOLFSSL_NGINX) */ + +/* + * RSA sign/verify APIs + */ + +#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER + #define DEF_PSS_SALT_LEN RSA_PSS_SALT_LEN_DEFAULT +#else + #define DEF_PSS_SALT_LEN RSA_PSS_SALT_LEN_DISCOVER +#endif #if defined(OPENSSL_EXTRA) -WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags) + +#if !defined(HAVE_USER_RSA) + +/* Encode the message hash. + * + * Used by signing and verification. + * + * @param [in] hashAlg Hash algorithm OID. + * @param [in] hash Hash of message to encode for signing. + * @param [in] hLen Length of hash of message. + * @param [out] enc Encoded message hash. + * @param [out] encLen Length of encoded message hash. + * @param [in] padding Which padding scheme is being used. + * @return 1 on success. + * @return 0 on failure. + */ +static int wolfssl_rsa_sig_encode(int hashAlg, const unsigned char* hash, + unsigned int hLen, unsigned char* enc, unsigned int* encLen, int padding) { - int name_len; - WOLFSSL_RSA_METHOD* meth; + int ret = 1; + int hType = WC_HASH_TYPE_NONE; - if (name == NULL) { - return NULL; + /* Validate parmeters. */ + if ((hash == NULL) || (enc == NULL) || (encLen == NULL)) { + ret = 0; } - meth = (WOLFSSL_RSA_METHOD*)XMALLOC(sizeof(WOLFSSL_RSA_METHOD), NULL, - DYNAMIC_TYPE_OPENSSL); - name_len = (int)XSTRLEN(name); - if (!meth) { - return NULL; - } - meth->flags = flags; - meth->name = (char*)XMALLOC(name_len+1, NULL, DYNAMIC_TYPE_OPENSSL); - if (!meth->name) { - XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL); - return NULL; - } - XMEMCPY(meth->name, name, name_len+1); - - return meth; -} - -void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth) -{ - if (meth) { - XFREE(meth->name, NULL, DYNAMIC_TYPE_OPENSSL); - XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL); - } -} - -#ifndef NO_WOLFSSL_STUB -int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p) -{ - (void)rsa; - (void)p; - WOLFSSL_STUB("RSA_METHOD is not implemented."); - return 1; -} -#endif - -int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth) -{ - if (rsa) - rsa->meth = meth; - return 1; -} - -const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa) -{ - if (!rsa) { - return NULL; - } - return rsa->meth; -} - -const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void) -{ - return wolfSSL_RSA_meth_new("wolfSSL RSA", 0); -} - -int wolfSSL_RSA_flags(const WOLFSSL_RSA *r) -{ - if (r && r->meth) { - return r->meth->flags; - } else { - return 0; - } -} - -void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) -{ - if (r && r->meth) { - r->meth->flags |= flags; - } -} - -void wolfSSL_RSA_clear_flags(WOLFSSL_RSA *r, int flags) -{ - if (r && r->meth) { - r->meth->flags &= ~flags; - } -} - -int wolfSSL_RSA_test_flags(const WOLFSSL_RSA *r, int flags) -{ - return r && r->meth ? r->meth->flags & flags : 0; -} - -#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) -WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) -{ - int derSz = 0; - byte *derBuf = NULL; - WOLFSSL_RSA* local; - - WOLFSSL_ENTER("wolfSSL_RSAPublicKey_dup"); - - if (!rsa) { - return NULL; - } - - local = wolfSSL_RSA_new(); - if (local == NULL) { - WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure"); - return NULL; - } - - if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, rsa->heap)) < 0) { - WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); - return NULL; - } - - if (wolfSSL_RSA_LoadDer_ex(local, - derBuf, derSz, - WOLFSSL_RSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) { - wolfSSL_RSA_free(local); - local = NULL; - } - XFREE(derBuf, rsa->heap, DYNAMIC_TYPE_ASN1); - return local; -} -#endif - -void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx) -{ - WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data"); -#ifdef HAVE_EX_DATA - if (rsa) { - return wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx); - } -#else - (void)rsa; - (void)idx; -#endif - return NULL; -} - -int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data) -{ - WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data"); - #ifdef HAVE_EX_DATA - if (rsa) { - return wolfSSL_CRYPTO_set_ex_data(&rsa->ex_data, idx, data); - } - #else - (void)rsa; - (void)idx; - (void)data; - #endif - return WOLFSSL_FAILURE; -} - -#ifdef HAVE_EX_DATA_CLEANUP_HOOKS -int wolfSSL_RSA_set_ex_data_with_cleanup( - WOLFSSL_RSA *rsa, - int idx, - void *data, - wolfSSL_ex_data_cleanup_routine_t cleanup_routine) -{ - WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data_with_cleanup"); - if (rsa) { - return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&rsa->ex_data, idx, data, - cleanup_routine); - } - return WOLFSSL_FAILURE; -} -#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */ - -int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, - WOLFSSL_BIGNUM *d) -{ - /* If the fields n and e in r are NULL, the corresponding input - * parameters MUST be non-NULL for n and e. d may be - * left NULL (in case only the public key is used). - */ - if ((!r->n && !n) || (!r->e && !e)) - return 0; - - if (n) { - wolfSSL_BN_free(r->n); - r->n = n; - } - if (e) { - wolfSSL_BN_free(r->e); - r->e = e; - } - if (d) { - wolfSSL_BN_clear_free(r->d); - r->d = d; - } - - return SetRsaInternal(r) == WOLFSSL_SUCCESS ? - WOLFSSL_SUCCESS : WOLFSSL_FAILURE; -} -#endif /* OPENSSL_EXTRA */ - -/* increments ref count of WOLFSSL_RSA. Return 1 on success, 0 on error */ -int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa) -{ - if (rsa) { -#ifndef SINGLE_THREADED - if (wc_LockMutex(&rsa->refMutex) != 0) { - WOLFSSL_MSG("Failed to lock x509 mutex"); - return WOLFSSL_FAILURE; - } -#endif - rsa->refCount++; -#ifndef SINGLE_THREADED - wc_UnLockMutex(&rsa->refMutex); -#endif - - return WOLFSSL_SUCCESS; - } - - return WOLFSSL_FAILURE; -} - -#endif /* OPENSSL_EXTRA_X509_SMALL || OPENSSL_EXTRA */ - -#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \ - || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) - -#ifndef NO_BIO - -#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ - !defined(HAVE_USER_RSA) -/* Converts an rsa key from a bio buffer into an internal rsa structure. -Returns a pointer to the new WOLFSSL_RSA structure. */ -WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out) -{ - const unsigned char* bioMem = NULL; - int bioMemSz = 0; - WOLFSSL_RSA* key = NULL; - unsigned char *maxKeyBuf = NULL; - unsigned char* bufPtr = NULL; - unsigned char* extraBioMem = NULL; - int extraBioMemSz = 0; - int derLength = 0; - int j = 0, i = 0; - - WOLFSSL_ENTER("wolfSSL_d2i_RSAPrivateKey_bio()"); - - if (bio == NULL) { - WOLFSSL_MSG("Bad Function Argument"); - return NULL; - } - (void)out; - - bioMemSz = wolfSSL_BIO_get_len(bio); - if (bioMemSz <= 0) { - WOLFSSL_MSG("wolfSSL_BIO_get_len() failure"); - return NULL; - } - - bioMem = (unsigned char*)XMALLOC(bioMemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (bioMem == NULL) { - WOLFSSL_MSG("Malloc failure"); - return NULL; - } - - maxKeyBuf = (unsigned char*)XMALLOC(4096, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (maxKeyBuf == NULL) { - WOLFSSL_MSG("Malloc failure"); - XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - return NULL; - } - bufPtr = maxKeyBuf; - if (wolfSSL_BIO_read(bio, (unsigned char*)bioMem, (int)bioMemSz) == bioMemSz) { - const byte* bioMemPt = bioMem; /* leave bioMem pointer unaltered */ - if ((key = wolfSSL_d2i_RSAPrivateKey(NULL, &bioMemPt, bioMemSz)) == NULL) { - XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - return NULL; - } - - /* This function is used to get the total length of the rsa key. */ - derLength = wolfSSL_i2d_RSAPrivateKey(key, &bufPtr); - - /* Write extra data back into bio object if necessary. */ - extraBioMemSz = (bioMemSz - derLength); - if (extraBioMemSz > 0) { - extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (extraBioMem == NULL) { - WOLFSSL_MSG("Malloc failure"); - XFREE((unsigned char*)extraBioMem, bio->heap, - DYNAMIC_TYPE_TMP_BUFFER); - XFREE((unsigned char*)bioMem, bio->heap, - DYNAMIC_TYPE_TMP_BUFFER); - XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - return NULL; - } - - for (i = derLength; i < bioMemSz; i++) { - *(extraBioMem + j) = *(bioMem + i); - j++; - } - - wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz); - if (wolfSSL_BIO_get_len(bio) <= 0) { - WOLFSSL_MSG("Failed to write memory to bio"); - XFREE((unsigned char*)extraBioMem, bio->heap, - DYNAMIC_TYPE_TMP_BUFFER); - XFREE((unsigned char*)bioMem, bio->heap, - DYNAMIC_TYPE_TMP_BUFFER); - XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - return NULL; - } - XFREE((unsigned char*)extraBioMem, bio->heap, - DYNAMIC_TYPE_TMP_BUFFER); - } - - if (out != NULL && key != NULL) { - *out = key; + if ((ret == 1) && (hashAlg != NID_undef) && + (padding == RSA_PKCS1_PADDING)) { + /* Convert hash algorithm to hash type for PKCS#1.5 padding. */ + hType = nid2oid(hashAlg, oidHashType); + if (hType == -1) { + ret = 0; } } - XFREE((unsigned char*)bioMem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE((unsigned char*)maxKeyBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - return key; -} -#endif /* !HAVE_FAST_RSA && WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ - -#endif /* !NO_BIO */ - -#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */ - -#ifdef OPENSSL_EXTRA - -#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) -/* Openssl -> WolfSSL */ -int SetRsaInternal(WOLFSSL_RSA* rsa) -{ - RsaKey* key; - WOLFSSL_MSG("Entering SetRsaInternal"); - - if (rsa == NULL || rsa->internal == NULL) { - WOLFSSL_MSG("rsa key NULL error"); - return WOLFSSL_FATAL_ERROR; - } - - key = (RsaKey*)rsa->internal; - - if (rsa->n != NULL) { - if (SetIndividualInternal(rsa->n, &key->n) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa n key error"); - return WOLFSSL_FATAL_ERROR; + if ((ret == 1) && (padding == RSA_PKCS1_PADDING)) { + /* PKCS#1.5 encoding. */ + word32 encSz = wc_EncodeSignature(enc, hash, hLen, hType); + if (encSz == 0) { + WOLFSSL_MSG("Bad Encode Signature"); + ret = 0; + } + else { + *encLen = (unsigned int)encSz; } } - - if (rsa->e != NULL) { - if (SetIndividualInternal(rsa->e, &key->e) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa e key error"); - return WOLFSSL_FATAL_ERROR; - } + /* Other padding schemes require the hash as is. */ + if ((ret == 1) && (padding != RSA_PKCS1_PADDING)) { + XMEMCPY(enc, hash, hLen); + *encLen = hLen; } - /* public key */ - key->type = RSA_PUBLIC; - - if (rsa->d != NULL) { - if (SetIndividualInternal(rsa->d, &key->d) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa d key error"); - return WOLFSSL_FATAL_ERROR; - } - - /* private key */ - key->type = RSA_PRIVATE; - } - - if (rsa->p != NULL && - SetIndividualInternal(rsa->p, &key->p) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa p key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (rsa->q != NULL && - SetIndividualInternal(rsa->q, &key->q) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa q key error"); - return WOLFSSL_FATAL_ERROR; - } - -#ifndef RSA_LOW_MEM - if (rsa->dmp1 != NULL && - SetIndividualInternal(rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa dP key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (rsa->dmq1 != NULL && - SetIndividualInternal(rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa dQ key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (rsa->iqmp != NULL && - SetIndividualInternal(rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa u key error"); - return WOLFSSL_FATAL_ERROR; - } -#endif /* !RSA_LOW_MEM */ - - rsa->inSet = 1; - - return WOLFSSL_SUCCESS; -} - -/* WOLFSSL_SUCCESS on ok */ -#ifndef NO_WOLFSSL_STUB -int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bn) -{ - (void)rsa; - (void)bn; - WOLFSSL_STUB("RSA_blinding_on"); - WOLFSSL_MSG("wolfSSL_RSA_blinding_on"); - - return WOLFSSL_SUCCESS; /* on by default */ -} -#endif - -/* If not using old FIPS or CAVP selftest or not using fast or user RSA, able - * to check RSA key. */ -#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \ - !defined(HAVE_USER_RSA) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))) && \ - !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) && \ - defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) -int wolfSSL_RSA_check_key(const WOLFSSL_RSA* rsa) -{ - int ret = WOLFSSL_SUCCESS; - - WOLFSSL_ENTER("wolfSSL_RSA_check_key"); - - if (rsa == NULL || rsa->internal == NULL) { - ret = WOLFSSL_FAILURE; - } - - if (ret == WOLFSSL_SUCCESS && wc_CheckRsaKey((RsaKey*)rsa->internal) != 0) { - ret = WOLFSSL_FAILURE; - } - - WOLFSSL_LEAVE("wolfSSL_RSA_check_key", ret); - return ret; } + +/* Sign the message hash using hash algorithm and RSA key. + * + * @param [in] hashAlg Hash algorithm OID. + * @param [in] hash Hash of message to encode for signing. + * @param [in] hLen Length of hash of message. + * @param [out] enc Encoded message hash. + * @param [out] encLen Length of encoded message hash. + * @param [in] rsa RSA key. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_sign(int hashAlg, const unsigned char* hash, unsigned int hLen, + unsigned char* sigRet, unsigned int* sigLen, WOLFSSL_RSA* rsa) +{ + if (sigLen != NULL) { + /* No size checking in this API */ + *sigLen = RSA_MAX_SIZE / CHAR_BIT; + } + /* flag is 1: output complete signature. */ + return wolfSSL_RSA_sign_generic_padding(hashAlg, hash, hLen, sigRet, + sigLen, rsa, 1, RSA_PKCS1_PADDING); +} + +/* Sign the message hash using hash algorithm and RSA key. + * wolfSSL API. + * + * @param [in] hashAlg Hash algorithm NID. + * @param [in] hash Hash of message to encode for signing. + * @param [in] hLen Length of hash of message. + * @param [out] enc Encoded message hash. + * @param [out] encLen Length of encoded message hash. + * @param [in] rsa RSA key. + * @param [in] flag When 1: Output encrypted signature. + * When 0: Output encoded hash. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_sign_ex(int hashAlg, const unsigned char* hash, + unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen, + WOLFSSL_RSA* rsa, int flag) +{ + int ret = 0; + + if ((flag == 0) || (flag == 1)) { + if (sigLen != NULL) { + /* No size checking in this API */ + *sigLen = RSA_MAX_SIZE / CHAR_BIT; + } + ret = wolfSSL_RSA_sign_generic_padding(hashAlg, hash, hLen, sigRet, + sigLen, rsa, flag, RSA_PKCS1_PADDING); + } + + return ret; +} + +/** + * Sign a message hash with the chosen message digest, padding, and RSA key. + * + * wolfSSL API. + * + * @param [in] hashAlg Hash NID + * @param [in] hash Message hash to sign. + * @param [in] mLen Length of message hash to sign. + * @param [out] sigRet Output buffer. + * @param [in, out] sigLen On Input: length of sigRet buffer. + * On Output: length of data written to sigRet. + * @param [in] rsa RSA key used to sign the input. + * @param [in] flag 1: Output the signature. + * 0: Output the value that the unpadded signature + * should be compared to. + * @param [in] padding Padding to use. Only RSA_PKCS1_PSS_PADDING and + * RSA_PKCS1_PADDING are currently supported for + * signing. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash, + unsigned int hLen, unsigned char* sigRet, unsigned int* sigLen, + WOLFSSL_RSA* rsa, int flag, int padding) +{ + int ret = 1; + word32 outLen = 0; + int signSz; + WC_RNG* rng = NULL; + int initTmpRng = 0; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG* tmpRng = NULL; + byte* encodedSig = NULL; +#else + WC_RNG _tmpRng[1]; + WC_RNG* tmpRng = _tmpRng; + byte encodedSig[MAX_ENCODED_SIG_SZ]; +#endif + unsigned int encSz; + + + WOLFSSL_ENTER("wolfSSL_RSA_sign_generic_padding"); + + if (flag == 0) { + /* Only encode message. */ + return wolfssl_rsa_sig_encode(hashAlg, hash, hLen, sigRet, sigLen, + padding); + } + + /* Validate parameters. */ + if ((hash == NULL) || (sigRet == NULL) || sigLen == NULL || rsa == NULL) { + WOLFSSL_MSG("Bad function arguments"); + ret = 0; + } + + /* Set wolfCrypt RSA key data from external if not already done. */ + if ((ret == 1) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) { + ret = 0; + } + + if (ret == 1) { + /* Get the maximum signature length. */ + outLen = (word32)wolfSSL_BN_num_bytes(rsa->n); + /* Check not an error return. */ + if (outLen == 0) { + WOLFSSL_MSG("Bad RSA size"); + ret = 0; + } + /* Check signature buffer is big enough. */ + else if (outLen > *sigLen) { + WOLFSSL_MSG("Output buffer too small"); + ret = 0; + } + } + +#ifdef WOLFSSL_SMALL_STACK + if (ret == 1) { + /* Allocate encoded signature buffer if doing PKCS#1 padding. */ + encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, + DYNAMIC_TYPE_SIGNATURE); + if (encodedSig == NULL) { + ret = 0; + } + } #endif -/* return compliant with OpenSSL - * size of encrypted data if success , -1 if error + if (ret == 1) { + /* Get/create an RNG. */ + rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng); + if (rng == NULL) { + WOLFSSL_MSG("WOLFSSL_RSA_GetRNG error"); + ret = 0; + } + } + + /* Either encodes with PKCS#1.5 or copies hash into encodedSig. */ + if ((ret == 1) && (wolfssl_rsa_sig_encode(hashAlg, hash, hLen, encodedSig, + &encSz, padding) == 0)) { + WOLFSSL_MSG("Bad Encode Signature"); + ret = 0; + } + + if (ret == 1) { + switch (padding) { + #if defined(WC_RSA_NO_PADDING) || defined(WC_RSA_DIRECT) + case RSA_NO_PADDING: + if ((signSz = wc_RsaDirect(encodedSig, encSz, sigRet, &outLen, + (RsaKey*)rsa->internal, RSA_PRIVATE_ENCRYPT, rng)) <= 0) { + WOLFSSL_MSG("Bad Rsa Sign no pad"); + ret = 0; + } + break; + #endif + #if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,1)) + case RSA_PKCS1_PSS_PADDING: + { + enum wc_HashType hType = + wc_OidGetHash(nid2oid(hashAlg, oidHashType)); + #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER + WOLFSSL_MSG("Using RSA-PSS with hash length salt. " + "OpenSSL uses max length by default."); + #endif + /* Create RSA PSS signature. */ + if ((signSz = wc_RsaPSS_Sign_ex(encodedSig, encSz, sigRet, outLen, + hType, wc_hash2mgf(hType), DEF_PSS_SALT_LEN, + (RsaKey*)rsa->internal, rng)) <= 0) { + WOLFSSL_MSG("Bad Rsa Sign"); + ret = 0; + } + break; + } + #endif + #ifndef WC_NO_RSA_OAEP + case RSA_PKCS1_OAEP_PADDING: + /* Not a signature padding scheme. */ + WOLFSSL_MSG("RSA_PKCS1_OAEP_PADDING not supported for signing"); + ret = 0; + break; + #endif + case RSA_PKCS1_PADDING: + { + /* Sign (private encrypt) PKCS#1 encoded signature. */ + if ((signSz = wc_RsaSSL_Sign(encodedSig, encSz, sigRet, outLen, + (RsaKey*)rsa->internal, rng)) <= 0) { + WOLFSSL_MSG("Bad Rsa Sign"); + ret = 0; + } + break; + } + default: + WOLFSSL_MSG("Unsupported padding"); + ret = 0; + break; + } + } + + if (ret == 1) { + /* Return the size of signature generated. */ + *sigLen = (unsigned int)signSz; + } + + /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */ + if (initTmpRng) { + wc_FreeRng(tmpRng); + } +#ifdef WOLFSSL_SMALL_STACK + /* Dispose of any allocated RNG and encoded signature. */ + XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE); +#endif + + WOLFSSL_LEAVE("wolfSSL_RSA_sign_generic_padding", ret); + return ret; +} + +/** + * Verify a message hash with the chosen message digest, padding, and RSA key. + * + * @param [in] hashAlg Hash NID + * @param [in] hash Message hash. + * @param [in] mLen Length of message hash. + * @param [in] sigRet Signature data. + * @param [in] sigLen Length of signature data. + * @param [in] rsa RSA key used to sign the input + * @return 1 on success. + * @return 0 on failure. */ -int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr, - unsigned char* to, WOLFSSL_RSA* rsa, int padding) +int wolfSSL_RSA_verify(int hashAlg, const unsigned char* hash, + unsigned int hLen, const unsigned char* sig, unsigned int sigLen, + WOLFSSL_RSA* rsa) { + return wolfSSL_RSA_verify_ex(hashAlg, hash, hLen, sig, sigLen, rsa, + RSA_PKCS1_PADDING); +} + +/** + * Verify a message hash with the chosen message digest, padding, and RSA key. + * + * wolfSSL API. + * + * @param [in] hashAlg Hash NID + * @param [in] hash Message hash. + * @param [in] mLen Length of message hash. + * @param [in] sigRet Signature data. + * @param [in] sigLen Length of signature data. + * @param [in] rsa RSA key used to sign the input + * @param [in] padding Padding to use. Only RSA_PKCS1_PSS_PADDING and + * RSA_PKCS1_PADDING are currently supported for + * signing. + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_RSA_verify_ex(int hashAlg, const unsigned char* hash, + unsigned int hLen, const unsigned char* sig, unsigned int sigLen, + WOLFSSL_RSA* rsa, int padding) +{ + int ret = 1; +#ifdef WOLFSSL_SMALL_STACK + unsigned char* encodedSig = NULL; +#else + unsigned char encodedSig[MAX_ENCODED_SIG_SZ]; +#endif + unsigned char* sigDec = NULL; + unsigned int len = MAX_ENCODED_SIG_SZ; + int verLen; +#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1)) && !defined(HAVE_SELFTEST) + enum wc_HashType hType = WC_HASH_TYPE_NONE; +#endif + + WOLFSSL_ENTER("wolfSSL_RSA_verify"); + + /* Validate parameters. */ + if ((hash == NULL) || (sig == NULL) || (rsa == NULL)) { + WOLFSSL_MSG("Bad function arguments"); + ret = 0; + } + + if (ret == 1) { + /* Allocate memory for decrypted signature. */ + sigDec = (unsigned char *)XMALLOC(sigLen, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sigDec == NULL) { + WOLFSSL_MSG("Memory failure"); + ret = 0; + } + } +#ifdef WOLFSSL_SMALL_STACK + if ((ret == 1) && (padding != RSA_PKCS1_PSS_PADDING)) { + /* Allocate memory for encoded signature. */ + encodedSig = (unsigned char *)XMALLOC(len, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (encodedSig == NULL) { + WOLFSSL_MSG("Memory failure"); + ret = 0; + } + } +#endif + if ((ret == 1) && (padding != RSA_PKCS1_PSS_PADDING)) { + /* Make encoded signature to compare with decrypted signature. */ + if (wolfssl_rsa_sig_encode(hashAlg, hash, hLen, encodedSig, &len, + padding) <= 0) { + WOLFSSL_MSG("Message Digest Error"); + ret = 0; + } + } + if (ret == 1) { + /* Decrypt signature */ + #if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1)) && \ + !defined(HAVE_SELFTEST) + hType = wc_OidGetHash(nid2oid(hashAlg, oidHashType)); + if ((verLen = wc_RsaSSL_Verify_ex2(sig, sigLen, (unsigned char *)sigDec, + sigLen, (RsaKey*)rsa->internal, padding, hType)) <= 0) { + WOLFSSL_MSG("RSA Decrypt error"); + ret = 0; + } + #else + verLen = wc_RsaSSL_Verify(sig, sigLen, (unsigned char *)sigDec, sigLen, + (RsaKey*)rsa->internal); + if (verLen < 0) { + ret = 0; + } + #endif + } + if (ret == 1) { + #if defined(WC_RSA_PSS) && !defined(HAVE_SELFTEST) && \ + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 1)) + if (padding == RSA_PKCS1_PSS_PADDING) { + /* Check PSS padding is valid. */ + if (wc_RsaPSS_CheckPadding_ex(hash, hLen, sigDec, verLen, + hType, DEF_PSS_SALT_LEN, + mp_count_bits(&((RsaKey*)rsa->internal)->n)) != 0) { + WOLFSSL_MSG("wc_RsaPSS_CheckPadding_ex error"); + ret = 0; + } + } + else + #endif /* WC_RSA_PSS && !HAVE_SELFTEST && (!HAVE_FIPS || + * FIPS_VERSION >= 5.1) */ + /* Compare decrypted signature to encoded signature. */ + if ((int)len != verLen || XMEMCMP(encodedSig, sigDec, verLen) != 0) { + WOLFSSL_MSG("wolfSSL_RSA_verify_ex failed"); + ret = 0; + } + } + + /* Dispose of any allocated data. */ +#ifdef WOLFSSL_SMALL_STACK + XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + XFREE(sigDec, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; +} + +/* + * RSA public/private encrypt/decrypt APIs + */ + +#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) + +/* Encrypt with the RSA public key. + * + * Return compliant with OpenSSL. + * + * @param [in] len Length of data to encrypt. + * @param [in] from Data to encrypt. + * @param [out] to Encrypted data. + * @param [in] rsa RSA key. + * @param [in] padding Type of padding to place around plaintext. + * @return Size of encrypted data on success. + * @return -1 on failure. + */ +int wolfSSL_RSA_public_encrypt(int len, const unsigned char* from, + unsigned char* to, WOLFSSL_RSA* rsa, int padding) +{ + int ret = 0; int initTmpRng = 0; WC_RNG *rng = NULL; - int outLen; - int ret = 0; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRng = NULL; #else - WC_RNG _tmpRNG[1]; - WC_RNG* tmpRNG = _tmpRNG; + WC_RNG _tmpRng[1]; + WC_RNG* tmpRng = _tmpRng; #endif -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) +#if !defined(HAVE_FIPS) int mgf = WC_MGF1NONE; enum wc_HashType hash = WC_HASH_TYPE_NONE; int pad_type; #endif + int outLen = 0; WOLFSSL_ENTER("RSA_public_encrypt"); -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) - switch (padding) { - case RSA_PKCS1_PADDING: - pad_type = WC_RSA_PKCSV15_PAD; - break; - case RSA_PKCS1_OAEP_PADDING: - pad_type = WC_RSA_OAEP_PAD; - hash = WC_HASH_TYPE_SHA; - mgf = WC_MGF1SHA1; - break; - case RSA_PKCS1_PSS_PADDING: - pad_type = WC_RSA_PSS_PAD; - hash = WC_HASH_TYPE_SHA256; - mgf = WC_MGF1SHA256; - break; - case RSA_NO_PADDING: - pad_type = WC_RSA_NO_PAD; - break; - default: - WOLFSSL_MSG("RSA_public_encrypt unsupported padding"); - return WOLFSSL_FAILURE; + /* Validate parameters. */ + if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) || + (from == NULL)) { + WOLFSSL_MSG("Bad function arguments"); + ret = -1; } -#endif - if (rsa->inSet == 0) { - if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return WOLFSSL_FAILURE; + if (ret == 0) { + #if !defined(HAVE_FIPS) + /* Convert to wolfCrypt padding, hash and MGF. */ + switch (padding) { + case RSA_PKCS1_PADDING: + pad_type = WC_RSA_PKCSV15_PAD; + break; + case RSA_PKCS1_OAEP_PADDING: + pad_type = WC_RSA_OAEP_PAD; + hash = WC_HASH_TYPE_SHA; + mgf = WC_MGF1SHA1; + break; + case RSA_NO_PADDING: + pad_type = WC_RSA_NO_PAD; + break; + default: + WOLFSSL_MSG("RSA_public_encrypt doesn't support padding scheme"); + ret = -1; } - } - - outLen = wolfSSL_RSA_size(rsa); - if (outLen == 0) { - WOLFSSL_MSG("Bad RSA size"); - } - - rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRNG, &initTmpRng); - if (rng) { -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) - ret = wc_RsaPublicEncrypt_ex(fr, len, to, outLen, - (RsaKey*)rsa->internal, rng, pad_type, - hash, mgf, NULL, 0); -#else - if (padding == RSA_PKCS1_PADDING) { - ret = wc_RsaPublicEncrypt(fr, len, to, outLen, - (RsaKey*)rsa->internal, rng); - } - else { + #else + /* Check for supported padding schemes in FIPS. */ + /* TODO: Do we support more schemes in later versions of FIPS? */ + if (padding != RSA_PKCS1_PADDING) { WOLFSSL_MSG("RSA_public_encrypt pad type not supported in FIPS"); - ret = WOLFSSL_FAILURE; + ret = -1; } -#endif + #endif } - if (initTmpRng) - wc_FreeRng(tmpRNG); + /* Set wolfCrypt RSA key data from external if not already done. */ + if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) { + ret = -1; + } + + if (ret == 0) { + /* Calculate maximum length of encrypted data. */ + outLen = wolfSSL_RSA_size(rsa); + if (outLen == 0) { + WOLFSSL_MSG("Bad RSA size"); + ret = -1; + } + } + + if (ret == 0) { + /* Get an RNG. */ + rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng); + if (rng == NULL) { + ret = -1; + } + } + + if (ret == 0) { + /* Use wolfCrypt to public-encrypt with RSA key. */ + #if !defined(HAVE_FIPS) + ret = wc_RsaPublicEncrypt_ex(from, len, to, outLen, + (RsaKey*)rsa->internal, rng, pad_type, hash, mgf, NULL, 0); + #else + ret = wc_RsaPublicEncrypt(from, len, to, outLen, (RsaKey*)rsa->internal, + rng); + #endif + } + + /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */ + if (initTmpRng) { + wc_FreeRng(tmpRng); + } #ifdef WOLFSSL_SMALL_STACK - if (tmpRNG) - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER); + /* Dispose of any allocated RNG. */ + XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - WOLFSSL_LEAVE("RSA_public_encrypt", ret); - + /* wolfCrypt error means return -1. */ if (ret <= 0) { - ret = WOLFSSL_FAILURE; + ret = -1; } + WOLFSSL_LEAVE("RSA_public_encrypt", ret); return ret; } - - -/* return compliant with OpenSSL - * size of plain recovered data if success , -1 if error +/* Decrypt with the RSA public key. + * + * Return compliant with OpenSSL. + * + * @param [in] len Length of encrypted data. + * @param [in] from Encrypted data. + * @param [out] to Decrypted data. + * @param [in] rsa RSA key. + * @param [in] padding Type of padding to around plaintext to remove. + * @return Size of decrypted data on success. + * @return -1 on failure. */ -int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr, - unsigned char* to, WOLFSSL_RSA* rsa, int padding) +int wolfSSL_RSA_private_decrypt(int len, const unsigned char* from, + unsigned char* to, WOLFSSL_RSA* rsa, int padding) { - int outLen; int ret = 0; - #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) +#if !defined(HAVE_FIPS) int mgf = WC_MGF1NONE; enum wc_HashType hash = WC_HASH_TYPE_NONE; - int pad_type; - #endif + int pad_type = WC_RSA_NO_PAD; +#endif + int outLen = 0; WOLFSSL_ENTER("RSA_private_decrypt"); -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) - switch (padding) { - case RSA_PKCS1_PADDING: - pad_type = WC_RSA_PKCSV15_PAD; - break; - case RSA_PKCS1_OAEP_PADDING: - pad_type = WC_RSA_OAEP_PAD; - hash = WC_HASH_TYPE_SHA; - mgf = WC_MGF1SHA1; - break; - case RSA_PKCS1_PSS_PADDING: - pad_type = WC_RSA_PSS_PAD; - hash = WC_HASH_TYPE_SHA256; - mgf = WC_MGF1SHA256; - break; - case RSA_NO_PADDING: - pad_type = WC_RSA_NO_PAD; - break; - default: - WOLFSSL_MSG("RSA_private_decrypt unsupported padding"); - return WOLFSSL_FAILURE; + /* Validate parameters. */ + if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) || + (from == NULL)) { + WOLFSSL_MSG("Bad function arguments"); + ret = -1; } -#endif - if (rsa->inSet == 0) { - if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return WOLFSSL_FAILURE; + if (ret == 0) { + #if !defined(HAVE_FIPS) + switch (padding) { + case RSA_PKCS1_PADDING: + pad_type = WC_RSA_PKCSV15_PAD; + break; + case RSA_PKCS1_OAEP_PADDING: + pad_type = WC_RSA_OAEP_PAD; + hash = WC_HASH_TYPE_SHA; + mgf = WC_MGF1SHA1; + break; + case RSA_NO_PADDING: + pad_type = WC_RSA_NO_PAD; + break; + default: + WOLFSSL_MSG("RSA_private_decrypt unsupported padding"); + ret = -1; + } + #else + /* Check for supported padding schemes in FIPS. */ + /* TODO: Do we support more schemes in later versions of FIPS? */ + if (padding != RSA_PKCS1_PADDING) { + WOLFSSL_MSG("RSA_public_encrypt pad type not supported in FIPS"); + ret = -1; + } + #endif + } + + /* Set wolfCrypt RSA key data from external if not already done. */ + if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) { + ret = -1; + } + + if (ret == 0) { + /* Calculate maximum length of decrypted data. */ + outLen = wolfSSL_RSA_size(rsa); + if (outLen == 0) { + WOLFSSL_MSG("Bad RSA size"); + ret = -1; } } - outLen = wolfSSL_RSA_size(rsa); - if (outLen == 0) { - WOLFSSL_MSG("Bad RSA size"); + if (ret == 0) { + /* Use wolfCrypt to private-decrypt with RSA key. + * Size of 'to' buffer must be size of RSA key */ + #if !defined(HAVE_FIPS) + ret = wc_RsaPrivateDecrypt_ex(from, len, to, outLen, + (RsaKey*)rsa->internal, pad_type, hash, mgf, NULL, 0); + #else + ret = wc_RsaPrivateDecrypt(from, len, to, outLen, + (RsaKey*)rsa->internal); + #endif } - /* size of 'to' buffer must be size of RSA key */ -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) - ret = wc_RsaPrivateDecrypt_ex(fr, len, to, outLen, - (RsaKey*)rsa->internal, pad_type, - hash, mgf, NULL, 0); -#else - if (padding == RSA_PKCS1_PADDING) { - ret = wc_RsaPrivateDecrypt(fr, len, to, outLen, - (RsaKey*)rsa->internal); - } - else { - WOLFSSL_MSG("RSA_private_decrypt pad type not supported in FIPS"); - ret = WOLFSSL_FAILURE; - } -#endif - + /* wolfCrypt error means return -1. */ if (ret <= 0) { - ret = WOLFSSL_FAILURE; + ret = -1; } WOLFSSL_LEAVE("RSA_private_decrypt", ret); - return ret; } -int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from, - unsigned char* to, WOLFSSL_RSA* rsa, int padding) +/* Decrypt with the RSA public key. + * + * @param [in] len Length of encrypted data. + * @param [in] from Encrypted data. + * @param [out] to Decrypted data. + * @param [in] rsa RSA key. + * @param [in] padding Type of padding to around plaintext to remove. + * @return Size of decrypted data on success. + * @return -1 on failure. + */ +int wolfSSL_RSA_public_decrypt(int len, const unsigned char* from, + unsigned char* to, WOLFSSL_RSA* rsa, int padding) { int ret = 0; -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) - int pad_type; +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) + int pad_type = WC_RSA_NO_PAD; #endif + int outLen = 0; WOLFSSL_ENTER("RSA_public_decrypt"); - if (rsa == NULL || rsa->internal == NULL || from == NULL) { + /* Validate parameters. */ + if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) || + (from == NULL)) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + ret = -1; } -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) - switch (padding) { - case RSA_PKCS1_PADDING: - pad_type = WC_RSA_PKCSV15_PAD; - break; - case RSA_PKCS1_OAEP_PADDING: - pad_type = WC_RSA_OAEP_PAD; - break; - case RSA_PKCS1_PSS_PADDING: - pad_type = WC_RSA_PSS_PAD; - break; - case RSA_NO_PADDING: - pad_type = WC_RSA_NO_PAD; - break; - default: - WOLFSSL_MSG("RSA_public_decrypt unsupported padding"); - return WOLFSSL_FATAL_ERROR; + if (ret == 0) { + #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) + switch (padding) { + case RSA_PKCS1_PADDING: + pad_type = WC_RSA_PKCSV15_PAD; + break; + case RSA_NO_PADDING: + pad_type = WC_RSA_NO_PAD; + break; + /* TODO: RSA_X931_PADDING not supported */ + default: + WOLFSSL_MSG("RSA_public_decrypt unsupported padding"); + ret = -1; + } + #else + if (padding != RSA_PKCS1_PADDING) { + WOLFSSL_MSG("RSA_public_decrypt pad type not supported in FIPS"); + ret = -1; + } + #endif } -#endif - if (rsa->inSet == 0) { - WOLFSSL_MSG("No RSA internal set, do it"); + /* Set wolfCrypt RSA key data from external if not already done. */ + if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) { + ret = -1; + } - if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return WOLFSSL_FATAL_ERROR; + if (ret == 0) { + /* Calculate maximum length of encrypted data. */ + outLen = wolfSSL_RSA_size(rsa); + if (outLen == 0) { + WOLFSSL_MSG("Bad RSA size"); + ret = -1; } } -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) - /* size of 'to' buffer must be size of RSA key */ - ret = wc_RsaSSL_Verify_ex(from, flen, to, wolfSSL_RSA_size(rsa), - (RsaKey*)rsa->internal, pad_type); -#else - /* For FIPS v1/v2 only PKCSV15 padding is supported */ - if (padding == RSA_PKCS1_PADDING) { - ret = wc_RsaSSL_Verify(from, flen, to, wolfSSL_RSA_size(rsa), - (RsaKey*)rsa->internal); + if (ret == 0) { + /* Use wolfCrypt to public-decrypt with RSA key. */ + #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) + /* Size of 'to' buffer must be size of RSA key. */ + ret = wc_RsaSSL_Verify_ex(from, len, to, outLen, + (RsaKey*)rsa->internal, pad_type); + #else + /* For FIPS v1/v2 only PKCSV15 padding is supported */ + ret = wc_RsaSSL_Verify(from, len, to, outLen, (RsaKey*)rsa->internal); + #endif } - else { - WOLFSSL_MSG("RSA_public_decrypt pad type not supported in FIPS"); - ret = WOLFSSL_FATAL_ERROR; - } -#endif - - WOLFSSL_LEAVE("RSA_public_decrypt", ret); + /* wolfCrypt error means return -1. */ if (ret <= 0) { - ret = WOLFSSL_FATAL_ERROR; + ret = -1; } + WOLFSSL_LEAVE("RSA_public_decrypt", ret); return ret; } -/* RSA private encrypt calls wc_RsaSSL_Sign. Similar function set up as RSA - * public decrypt. +/* Encrypt with the RSA private key. * - * len Length of input buffer - * in Input buffer to sign - * out Output buffer (expected to be greater than or equal to RSA key size) - * rsa Key to use for encryption - * padding Type of RSA padding to use. + * Calls wc_RsaSSL_Sign. + * + * @param [in] len Length of data to encrypt. + * @param [in] from Data to encrypt. + * @param [out] to Encrypted data. + * @param [in] rsa RSA key. + * @param [in] padding Type of padding to place around plaintext. + * @return Size of encrypted data on success. + * @return -1 on failure. */ -int wolfSSL_RSA_private_encrypt(int len, const unsigned char* in, - unsigned char* out, WOLFSSL_RSA* rsa, int padding) +int wolfSSL_RSA_private_encrypt(int len, const unsigned char* from, + unsigned char* to, WOLFSSL_RSA* rsa, int padding) { - int sz = 0; - WC_RNG* rng = NULL; -#if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA) - WC_RNG rng_lcl; + int ret = 0; + int initTmpRng = 0; + WC_RNG *rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG* tmpRng = NULL; +#else + WC_RNG _tmpRng[1]; + WC_RNG* tmpRng = _tmpRng; #endif - RsaKey* key; WOLFSSL_MSG("wolfSSL_RSA_private_encrypt"); - if (len < 0 || rsa == NULL || rsa->internal == NULL || in == NULL) { + /* Validate parameters. */ + if ((len < 0) || (rsa == NULL) || (rsa->internal == NULL) || + (from == NULL)) { WOLFSSL_MSG("Bad function arguments"); - return 0; + ret = -1; } - if ( - #ifdef WC_RSA_PSS - padding != RSA_PKCS1_PSS_PADDING && - #endif - #ifdef WC_RSA_NO_PADDING - padding != RSA_NO_PADDING && - #endif - padding != RSA_PKCS1_PADDING) { - WOLFSSL_MSG("wolfSSL_RSA_private_encrypt unsupported padding"); - return 0; - } - - if (rsa->inSet == 0) - { - WOLFSSL_MSG("Setting internal RSA structure"); - - if (SetRsaInternal(rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return 0; - } - } - - key = (RsaKey*)rsa->internal; -#if defined(WC_RSA_BLINDING) && !defined(HAVE_USER_RSA) - rng = key->rng; -#else - rng = &rng_lcl; - #ifndef HAVE_FIPS - if (wc_InitRng_ex(rng, key->heap, INVALID_DEVID) != 0) - #else - if (wc_InitRng(rng) != 0) - #endif - { - WOLFSSL_MSG("Error with random number"); - return WOLFSSL_FATAL_ERROR; - } -#endif - - /* size of output buffer must be size of RSA key */ - switch (padding) { + if (ret == 0) { + switch (padding) { case RSA_PKCS1_PADDING: - sz = wc_RsaSSL_Sign(in, (word32)len, out, wolfSSL_RSA_size(rsa), - key, rng); - break; - #ifdef WC_RSA_PSS - case RSA_PKCS1_PSS_PADDING: - sz = wc_RsaPSS_Sign(in, (word32)len, out, wolfSSL_RSA_size(rsa), - WC_HASH_TYPE_NONE, WC_MGF1NONE, key, rng); - break; - #endif #ifdef WC_RSA_NO_PADDING case RSA_NO_PADDING: - { - word32 outLen = (word32)len; - sz = wc_RsaFunction(in, (word32)len, out, &outLen, - RSA_PRIVATE_ENCRYPT, key, rng); - if (sz == 0) - sz = (int)outLen; - break; - } #endif + break; + /* TODO: RSA_X931_PADDING not supported */ default: - sz = BAD_FUNC_ARG; - break; + WOLFSSL_MSG("RSA_private_encrypt unsupported padding"); + ret = -1; + } } - #if !defined(WC_RSA_BLINDING) || defined(HAVE_USER_RSA) - if (wc_FreeRng(rng) != 0) { - WOLFSSL_MSG("Error freeing random number generator"); - return WOLFSSL_FATAL_ERROR; + /* Set wolfCrypt RSA key data from external if not already done. */ + if ((ret == 0) && (!rsa->inSet) && (SetRsaInternal(rsa) != 1)) { + ret = -1; } + + if (ret == 0) { + /* Get an RNG. */ + rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng); + if (rng == NULL) { + ret = -1; + } + } + + if (ret == 0) { + /* Use wolfCrypt to private-encrypt with RSA key. + * Size of output buffer must be size of RSA key. */ + if (padding == RSA_PKCS1_PADDING) { + ret = wc_RsaSSL_Sign(from, (word32)len, to, wolfSSL_RSA_size(rsa), + (RsaKey*)rsa->internal, rng); + } + #ifdef WC_RSA_NO_PADDING + else if (padding == RSA_NO_PADDING) { + word32 outLen = wolfSSL_RSA_size(rsa); + ret = wc_RsaFunction(from, (word32)len, to, &outLen, + RSA_PRIVATE_ENCRYPT, (RsaKey*)rsa->internal, rng); + if (ret == 0) + ret = (int)outLen; + } #endif - if (sz <= 0) { - WOLFSSL_LEAVE("wolfSSL_RSA_private_encrypt", sz); - return 0; } - return sz; -} -#endif /* HAVE_USER_RSA */ + /* Finalize RNG if initialized in WOLFSSL_RSA_GetRNG(). */ + if (initTmpRng) { + wc_FreeRng(tmpRng); + } +#ifdef WOLFSSL_SMALL_STACK + /* Dispose of any allocated RNG. */ + XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif -/* return compliant with OpenSSL - * RSA modulus size in bytes, -1 if error + /* wolfCrypt error means return -1. */ + if (ret <= 0) { + ret = -1; + } + WOLFSSL_LEAVE("wolfSSL_RSA_private_encrypt", ret); + return ret; +} +#endif /* !HAVE_USER_RSA && !HAVE_FAST_RSA */ + +/* + * RSA misc operation APIs */ -int wolfSSL_RSA_size(const WOLFSSL_RSA* rsa) -{ - WOLFSSL_ENTER("wolfSSL_RSA_size"); - if (rsa == NULL) - return WOLFSSL_FATAL_ERROR; - if (rsa->inSet == 0) - { - if (SetRsaInternal((WOLFSSL_RSA*)rsa) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal failed"); - return 0; +/* Calculate d mod p-1 and q-1 into BNs. + * + * wolfSSL API. + * + * @param [in, out] rsa RSA key. + * @return 1 on success. + * @return -1 on faulure. + */ +int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa) +{ + int ret = 1; + int err; + mp_int tmp; + mp_int* t = NULL; + + WOLFSSL_ENTER("wolfSSL_RsaGenAdd"); + + /* Validate parameters. */ + if ((rsa == NULL) || (rsa->p == NULL) || (rsa->q == NULL) || + (rsa->d == NULL) || (rsa->dmp1 == NULL) || (rsa->dmq1 == NULL)) { + WOLFSSL_MSG("rsa no init error"); + ret = -1; + } + + if (ret == 1) { + /* Initialize temp MP integer. */ + if (mp_init(&tmp) != MP_OKAY) { + WOLFSSL_MSG("mp_init error"); + ret = -1; } } - return wc_RsaEncryptSize((RsaKey*)rsa->internal); + + if (ret == 1) { + t = &tmp; + + /* Sub 1 from p into temp. */ + err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp); + if (err != MP_OKAY) { + WOLFSSL_MSG("mp_sub_d error"); + ret = -1; + } + } + if (ret == 1) { + /* Calculate d mod (p - 1) into dmp1 MP integer of BN. */ + err = mp_mod((mp_int*)rsa->d->internal, &tmp, + (mp_int*)rsa->dmp1->internal); + if (err != MP_OKAY) { + WOLFSSL_MSG("mp_mod error"); + ret = -1; + } + } + if (ret == 1) { + /* Sub 1 from q into temp. */ + err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp); + if (err != MP_OKAY) { + WOLFSSL_MSG("mp_sub_d error"); + ret = -1; + } + } + if (ret == 1) { + /* Calculate d mod (q - 1) into dmq1 MP integer of BN. */ + err = mp_mod((mp_int*)rsa->d->internal, &tmp, + (mp_int*)rsa->dmq1->internal); + if (err != MP_OKAY) { + WOLFSSL_MSG("mp_mod error"); + ret = -1; + } + } + + mp_clear(t); + + return ret; } -/* return RSA modulus in bits */ -/* @param rsa a pointer to WOLFSSL_RSA structure */ -/* @return RSA modulus size in bits, 0 if error */ -int wolfSSL_RSA_bits(const WOLFSSL_RSA* rsa) + +#endif /* !HAVE_USER_RSA */ + +#ifndef NO_WOLFSSL_STUB +/* Enable blinding for RSA key operations. + * + * Blinding is a compile time option in wolfCrypt. + * + * @param [in] rsa RSA key. Unused. + * @param [in] bnCtx BN context to use for blinding. Unused. + * @return 1 always. + */ +int wolfSSL_RSA_blinding_on(WOLFSSL_RSA* rsa, WOLFSSL_BN_CTX* bnCtx) { - WOLFSSL_ENTER("wolfSSL_RSA_bits"); + WOLFSSL_STUB("RSA_blinding_on"); + WOLFSSL_MSG("wolfSSL_RSA_blinding_on"); - if (rsa == NULL) - return WOLFSSL_FAILURE; + (void)rsa; + (void)bnCtx; - return wolfSSL_BN_num_bits(rsa->n); + return 1; /* on by default */ } +#endif + #endif /* OPENSSL_EXTRA */ -#if !defined(HAVE_USER_RSA) && !defined(HAVE_FAST_RSA) && \ - (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) -/* WolfSSL -> OpenSSL */ -int SetRsaExternal(WOLFSSL_RSA* rsa) -{ - RsaKey* key; - WOLFSSL_MSG("Entering SetRsaExternal"); - - if (rsa == NULL || rsa->internal == NULL) { - WOLFSSL_MSG("rsa key NULL error"); - return WOLFSSL_FATAL_ERROR; - } - - key = (RsaKey*)rsa->internal; - - if (SetIndividualExternal(&rsa->n, &key->n) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa n key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (SetIndividualExternal(&rsa->e, &key->e) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa e key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (key->type == RSA_PRIVATE) { - if (SetIndividualExternal(&rsa->d, &key->d) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa d key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (SetIndividualExternal(&rsa->p, &key->p) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa p key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (SetIndividualExternal(&rsa->q, &key->q) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa q key error"); - return WOLFSSL_FATAL_ERROR; - } - - #ifndef RSA_LOW_MEM - if (SetIndividualExternal(&rsa->dmp1, &key->dP) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa dP key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (SetIndividualExternal(&rsa->dmq1, &key->dQ) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa dQ key error"); - return WOLFSSL_FATAL_ERROR; - } - - if (SetIndividualExternal(&rsa->iqmp, &key->u) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("rsa u key error"); - return WOLFSSL_FATAL_ERROR; - } - #endif /* !RSA_LOW_MEM */ - } - rsa->exSet = 1; - - return WOLFSSL_SUCCESS; -} -#endif /* !HAVE_USER_RSA && !HAVE_FAST_RSA && - * (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ - -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) -static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa) -{ - if (rsa) { - XMEMSET(rsa, 0, sizeof(WOLFSSL_RSA)); - } -} - - -void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) -{ - WOLFSSL_ENTER("wolfSSL_RSA_free"); - - if (rsa) { -#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - int doFree = 0; -#endif - void* heap = rsa->heap; - -#ifdef HAVE_EX_DATA_CLEANUP_HOOKS - wolfSSL_CRYPTO_cleanup_ex_data(&rsa->ex_data); -#endif -#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - #ifndef SINGLE_THREADED - if (wc_LockMutex(&rsa->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock rsa mutex"); - return; - } - #endif - - /* only free if all references to it are done */ - rsa->refCount--; - if (rsa->refCount == 0) { - doFree = 1; - } - #ifndef SINGLE_THREADED - wc_UnLockMutex(&rsa->refMutex); - #endif - - if (!doFree) { - return; - } - - #ifndef SINGLE_THREADED - wc_FreeMutex(&rsa->refMutex); - #endif -#endif - - if (rsa->internal) { -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ - !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) - WC_RNG* rng; - - /* check if RNG is owned before freeing it */ - if (rsa->ownRng) { - rng = ((RsaKey*)rsa->internal)->rng; - if (rng != NULL && rng != wolfssl_get_global_rng()) { - wc_FreeRng(rng); - XFREE(rng, heap, DYNAMIC_TYPE_RNG); - } - } -#endif /* WC_RSA_BLINDING */ - wc_FreeRsaKey((RsaKey*)rsa->internal); - XFREE(rsa->internal, heap, DYNAMIC_TYPE_RSA); - rsa->internal = NULL; - } - wolfSSL_BN_free(rsa->iqmp); - wolfSSL_BN_free(rsa->dmq1); - wolfSSL_BN_free(rsa->dmp1); - wolfSSL_BN_free(rsa->q); - wolfSSL_BN_free(rsa->p); - wolfSSL_BN_free(rsa->d); - wolfSSL_BN_free(rsa->e); - wolfSSL_BN_free(rsa->n); - - #ifdef WC_RSA_BLINDING - if (rsa->rng && wc_FreeRng(rsa->rng) != 0) { - WOLFSSL_MSG("Issue freeing rng"); - } - XFREE(rsa->rng, heap, DYNAMIC_TYPE_RNG); - #endif - -#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) - if (rsa->meth) { - wolfSSL_RSA_meth_free(rsa->meth); - } -#endif - - InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */ - - XFREE(rsa, heap, DYNAMIC_TYPE_RSA); - (void)heap; - - /* rsa = NULL, don't try to access or double free it */ - } -} - -WOLFSSL_RSA* wolfSSL_RSA_new_ex(void* heap, int devId) -{ - WOLFSSL_RSA* external; - RsaKey* key; - - WOLFSSL_ENTER("wolfSSL_RSA_new"); - - key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA); - if (key == NULL) { - WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure"); - return NULL; - } - - external = (WOLFSSL_RSA*)XMALLOC(sizeof(WOLFSSL_RSA), heap, - DYNAMIC_TYPE_RSA); - if (external == NULL) { - WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure"); - XFREE(key, heap, DYNAMIC_TYPE_RSA); - return NULL; - } - - external->heap = heap; - InitwolfSSL_Rsa(external); - -#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - external->refCount = 1; -#ifndef SINGLE_THREADED - if (wc_InitMutex(&external->refMutex) != 0) { - WOLFSSL_MSG("wc_InitMutex WOLFSSL_RSA failure"); - XFREE(external, heap, DYNAMIC_TYPE_RSA); - XFREE(key, heap, DYNAMIC_TYPE_RSA); - return NULL; - } -#endif -#endif - - if (wc_InitRsaKey_ex(key, heap, devId) != 0) { - WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure"); - XFREE(external, heap, DYNAMIC_TYPE_RSA); - XFREE(key, heap, DYNAMIC_TYPE_RSA); - return NULL; - } - -#if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ - !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) - { - WC_RNG* rng; - - rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG); - if (rng != NULL && wc_InitRng_ex(rng, heap, devId) != 0) { - WOLFSSL_MSG("InitRng failure, attempting to use global RNG"); - XFREE(rng, heap, DYNAMIC_TYPE_RNG); - rng = NULL; - } - - external->ownRng = 1; - if (rng == NULL) { - rng = wolfssl_get_global_rng(); - external->ownRng = 0; - } - - if (rng == NULL) { - WOLFSSL_MSG("wolfSSL_RSA_new no WC_RNG for blinding"); - XFREE(external, heap, DYNAMIC_TYPE_RSA); - XFREE(key, heap, DYNAMIC_TYPE_RSA); - return NULL; - } - - wc_RsaSetRNG(key, rng); - } -#else - XMEMSET(key, 0, sizeof(RsaKey)); -#endif /* WC_RSA_BLINDING */ - - external->internal = key; - external->inSet = 0; - return external; -} - -WOLFSSL_RSA* wolfSSL_RSA_new(void) -{ - return wolfSSL_RSA_new_ex(NULL, INVALID_DEVID); -} -#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ - #endif /* !NO_RSA */ /******************************************************************************* @@ -3042,39 +4138,39 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) */ int wolfSSL_DSA_print_fp(XFILE fp, WOLFSSL_DSA* dsa, int indent) { - int ret = WOLFSSL_SUCCESS; + int ret = 1; int pBits; WOLFSSL_ENTER("wolfSSL_DSA_print_fp"); if (fp == XBADFILE || dsa == NULL) { - ret = WOLFSSL_FAILURE; + ret = 0; } - if (ret == WOLFSSL_SUCCESS && dsa->p != NULL) { + if (ret == 1 && dsa->p != NULL) { pBits = wolfSSL_BN_num_bits(dsa->p); - if (pBits == WOLFSSL_FAILURE) { - ret = WOLFSSL_FAILURE; + if (pBits == 0) { + ret = 0; } else { XFPRINTF(fp, "%*s", indent, ""); XFPRINTF(fp, "Private-Key: (%d bit)\n", pBits); } } - if (ret == WOLFSSL_SUCCESS && dsa->priv_key != NULL) { - ret = PrintBNFieldFp(fp, indent, "priv", dsa->priv_key); + if (ret == 1 && dsa->priv_key != NULL) { + ret = pk_bn_field_print_fp(fp, indent, "priv", dsa->priv_key); } - if (ret == WOLFSSL_SUCCESS && dsa->pub_key != NULL) { - ret = PrintBNFieldFp(fp, indent, "pub", dsa->pub_key); + if (ret == 1 && dsa->pub_key != NULL) { + ret = pk_bn_field_print_fp(fp, indent, "pub", dsa->pub_key); } - if (ret == WOLFSSL_SUCCESS && dsa->p != NULL) { - ret = PrintBNFieldFp(fp, indent, "P", dsa->p); + if (ret == 1 && dsa->p != NULL) { + ret = pk_bn_field_print_fp(fp, indent, "P", dsa->p); } - if (ret == WOLFSSL_SUCCESS && dsa->q != NULL) { - ret = PrintBNFieldFp(fp, indent, "Q", dsa->q); + if (ret == 1 && dsa->q != NULL) { + ret = pk_bn_field_print_fp(fp, indent, "Q", dsa->q); } - if (ret == WOLFSSL_SUCCESS && dsa->g != NULL) { - ret = PrintBNFieldFp(fp, indent, "G", dsa->g); + if (ret == 1 && dsa->g != NULL) { + ret = pk_bn_field_print_fp(fp, indent, "G", dsa->g); } WOLFSSL_LEAVE("wolfSSL_DSA_print_fp", ret); @@ -3164,39 +4260,39 @@ int SetDsaExternal(WOLFSSL_DSA* dsa) if (dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("dsa key NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } key = (DsaKey*)dsa->internal; - if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->p, &key->p) != 1) { WOLFSSL_MSG("dsa p key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->q, &key->q) != 1) { WOLFSSL_MSG("dsa q key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->g, &key->g) != 1) { WOLFSSL_MSG("dsa g key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetIndividualExternal(&dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->pub_key, &key->y) != 1) { WOLFSSL_MSG("dsa y key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetIndividualExternal(&dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->priv_key, &key->x) != 1) { WOLFSSL_MSG("dsa x key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } dsa->exSet = 1; - return WOLFSSL_SUCCESS; + return 1; } #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -3209,33 +4305,33 @@ int SetDsaInternal(WOLFSSL_DSA* dsa) if (dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("dsa key NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } key = (DsaKey*)dsa->internal; if (dsa->p != NULL && - SetIndividualInternal(dsa->p, &key->p) != WOLFSSL_SUCCESS) { + SetIndividualInternal(dsa->p, &key->p) != 1) { WOLFSSL_MSG("rsa p key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (dsa->q != NULL && - SetIndividualInternal(dsa->q, &key->q) != WOLFSSL_SUCCESS) { + SetIndividualInternal(dsa->q, &key->q) != 1) { WOLFSSL_MSG("rsa q key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (dsa->g != NULL && - SetIndividualInternal(dsa->g, &key->g) != WOLFSSL_SUCCESS) { + SetIndividualInternal(dsa->g, &key->g) != 1) { WOLFSSL_MSG("rsa g key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (dsa->pub_key != NULL) { - if (SetIndividualInternal(dsa->pub_key, &key->y) != WOLFSSL_SUCCESS) { + if (SetIndividualInternal(dsa->pub_key, &key->y) != 1) { WOLFSSL_MSG("rsa pub_key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* public key */ @@ -3243,9 +4339,9 @@ int SetDsaInternal(WOLFSSL_DSA* dsa) } if (dsa->priv_key != NULL) { - if (SetIndividualInternal(dsa->priv_key, &key->x) != WOLFSSL_SUCCESS) { + if (SetIndividualInternal(dsa->priv_key, &key->x) != 1) { WOLFSSL_MSG("rsa priv_key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* private key */ @@ -3254,7 +4350,7 @@ int SetDsaInternal(WOLFSSL_DSA* dsa) dsa->inSet = 1; - return WOLFSSL_SUCCESS; + return 1; } /* return code compliant with OpenSSL : @@ -3262,19 +4358,19 @@ int SetDsaInternal(WOLFSSL_DSA* dsa) */ int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa) { - int ret = WOLFSSL_FAILURE; + int ret = 0; WOLFSSL_ENTER("wolfSSL_DSA_generate_key"); if (dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); - if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaInternal(dsa) != 1) { WOLFSSL_MSG("SetDsaInternal failed"); return ret; } @@ -3285,18 +4381,18 @@ int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa) int initTmpRng = 0; WC_RNG *rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG *tmpRNG; + WC_RNG *tmpRng; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; #endif #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) - return WOLFSSL_FATAL_ERROR; + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) + return -1; #endif - if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -3313,17 +4409,17 @@ int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa) if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY) WOLFSSL_MSG("wc_MakeDsaKey failed"); - else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) + else if (SetDsaExternal(dsa) != 1) WOLFSSL_MSG("SetDsaExternal failed"); else - ret = WOLFSSL_SUCCESS; + ret = 1; } if (initTmpRng) - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif } #else /* WOLFSSL_KEY_GEN */ @@ -3351,7 +4447,7 @@ WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed, } if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen, - counterRet, hRet, NULL) != WOLFSSL_SUCCESS) { + counterRet, hRet, NULL) != 1) { wolfSSL_DSA_free(dsa); return NULL; } @@ -3368,7 +4464,7 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, int* counterRet, unsigned long* hRet, void* cb) { - int ret = WOLFSSL_FAILURE; + int ret = 0; (void)bits; (void)seed; @@ -3381,7 +4477,7 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, if (dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } #ifdef WOLFSSL_KEY_GEN @@ -3389,18 +4485,18 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, int initTmpRng = 0; WC_RNG *rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG *tmpRNG; + WC_RNG *tmpRng; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; #endif #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) - return WOLFSSL_FATAL_ERROR; + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) + return -1; #endif - if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -3412,17 +4508,17 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, if (wc_MakeDsaParameters(rng, bits, (DsaKey*)dsa->internal) != MP_OKAY) WOLFSSL_MSG("wc_MakeDsaParameters failed"); - else if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) + else if (SetDsaExternal(dsa) != 1) WOLFSSL_MSG("SetDsaExternal failed"); else - ret = WOLFSSL_SUCCESS; + ret = 1; } if (initTmpRng) - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif } #else /* WOLFSSL_KEY_GEN */ @@ -3452,7 +4548,7 @@ int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p, WOLFSSL_ENTER("wolfSSL_DSA_set0_pqg"); if (d == NULL || p == NULL || q == NULL || g == NULL) { WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; + return 0; } wolfSSL_BN_free(d->p); wolfSSL_BN_free(d->q); @@ -3460,7 +4556,7 @@ int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p, d->p = p; d->q = q; d->g = g; - return WOLFSSL_SUCCESS; + return 1; } void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d, @@ -3483,7 +4579,7 @@ int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key, /* The private key may be NULL */ if (pub_key == NULL) { WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; + return 0; } wolfSSL_BN_free(d->pub_key); @@ -3491,7 +4587,7 @@ int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key, d->pub_key = pub_key; d->priv_key = priv_key; - return WOLFSSL_SUCCESS; + return 1; } WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void) @@ -3535,7 +4631,7 @@ int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r, WOLFSSL_ENTER("wolfSSL_DSA_SIG_set0"); if (r == NULL || s == NULL) { WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; + return 0; } wolfSSL_BN_clear_free(sig->r); @@ -3543,7 +4639,7 @@ int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r, sig->r = r; sig->s = s; - return WOLFSSL_SUCCESS; + return 1; } #ifndef HAVE_SELFTEST @@ -3565,20 +4661,20 @@ int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out) if (sig == NULL || sig->r == NULL || sig->s == NULL || out == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (StoreECC_DSA_Sig(buf, &bufLen, (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != 0) { WOLFSSL_MSG("StoreECC_DSA_Sig error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (*out == NULL) { byte* tmp = (byte*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_ASN1); if (tmp == NULL) { WOLFSSL_MSG("malloc error"); - return WOLFSSL_FATAL_ERROR; + return -1; } *out = tmp; } @@ -3703,17 +4799,17 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig, } #endif /* HAVE_SELFTEST */ -/* return WOLFSSL_SUCCESS on success, < 0 otherwise */ +/* return 1 on success, < 0 otherwise */ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, WOLFSSL_DSA* dsa) { - int ret = WOLFSSL_FATAL_ERROR; + int ret = -1; int initTmpRng = 0; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRng = NULL; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; #endif WOLFSSL_ENTER("wolfSSL_DSA_do_sign"); @@ -3725,20 +4821,20 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); - if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaInternal(dsa) != 1) { WOLFSSL_MSG("SetDsaInternal failed"); return ret; } } #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) - return WOLFSSL_FATAL_ERROR; + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) + return -1; #endif - if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -3750,13 +4846,13 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, if (wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) WOLFSSL_MSG("DsaSign failed"); else - ret = WOLFSSL_SUCCESS; + ret = 1; } if (initTmpRng) - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif return ret; @@ -3777,7 +4873,7 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, return NULL; } - if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != WOLFSSL_SUCCESS) { + if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != 1) { WOLFSSL_MSG("wolfSSL_DSA_do_sign error"); return NULL; } @@ -3801,21 +4897,21 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, WOLFSSL_DSA* dsa, int *dsacheck) { - int ret = WOLFSSL_FATAL_ERROR; + int ret = -1; WOLFSSL_ENTER("wolfSSL_DSA_do_verify"); if (d == NULL || sig == NULL || dsa == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); - if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaInternal(dsa) != 1) { WOLFSSL_MSG("SetDsaInternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } } @@ -3825,16 +4921,16 @@ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, return ret; } - return WOLFSSL_SUCCESS; + return 1; } int wolfSSL_DSA_bits(const WOLFSSL_DSA *d) { if (!d) - return WOLFSSL_FAILURE; - if (!d->exSet && SetDsaExternal((WOLFSSL_DSA*)d) != WOLFSSL_SUCCESS) - return WOLFSSL_FAILURE; + return 0; + if (!d->exSet && SetDsaExternal((WOLFSSL_DSA*)d) != 1) + return 0; return wolfSSL_BN_num_bits(d->p); } @@ -3852,19 +4948,19 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, if (!digest || !sig || !dsa || digest_len != WC_SHA_DIGEST_SIZE) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } if (!sig->r || !sig->s) { WOLFSSL_MSG("No signature found in DSA_SIG"); - return WOLFSSL_FAILURE; + return 0; } if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); - if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaInternal(dsa) != 1) { WOLFSSL_MSG("SetDsaInternal failed"); - return WOLFSSL_FAILURE; + return 0; } } @@ -3872,23 +4968,23 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, if (key == NULL) { WOLFSSL_MSG("dsa->internal is null"); - return WOLFSSL_FAILURE; + return 0; } qSz = mp_unsigned_bin_size(&key->q); if (qSz < 0 || qSz > DSA_MAX_HALF_SIZE) { WOLFSSL_MSG("mp_unsigned_bin_size error"); - return WOLFSSL_FAILURE; + return 0; } /* read r */ /* front pad with zeros */ if ((sz = wolfSSL_BN_num_bytes(sig->r)) < 0 || sz > DSA_MAX_HALF_SIZE) - return WOLFSSL_FAILURE; + return 0; while (sz++ < qSz) *sigBinPtr++ = 0; - if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == WOLFSSL_FATAL_ERROR) - return WOLFSSL_FAILURE; + if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == -1) + return 0; /* Move to s */ sigBinPtr = sigBin + qSz; @@ -3896,18 +4992,18 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, /* read s */ /* front pad with zeros */ if ((sz = wolfSSL_BN_num_bytes(sig->s)) < 0 || sz > DSA_MAX_HALF_SIZE) - return WOLFSSL_FAILURE; + return 0; while (sz++ < qSz) *sigBinPtr++ = 0; - if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == WOLFSSL_FATAL_ERROR) - return WOLFSSL_FAILURE; + if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1) + return 0; if ((wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck) - != WOLFSSL_SUCCESS) || dsacheck != 1) { - return WOLFSSL_FAILURE; + != 1) || dsacheck != 1) { + return 0; } - return WOLFSSL_SUCCESS; + return 1; } #endif /* !HAVE_SELFTEST */ @@ -3991,15 +5087,15 @@ WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa, const unsigned char** der, } if (err == 0) { err = SetIndividualExternal(&ret->p, &internalKey->p) - != WOLFSSL_SUCCESS; + != 1; } if (err == 0) { err = SetIndividualExternal(&ret->q, &internalKey->q) - != WOLFSSL_SUCCESS; + != 1; } if (err == 0) { err = SetIndividualExternal(&ret->g, &internalKey->g) - != WOLFSSL_SUCCESS; + != 1; } if (err == 0 && dsa != NULL) { *dsa = ret; @@ -4017,7 +5113,7 @@ WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa, const unsigned char** der, #ifndef NO_BIO /* Takes a DSA Privatekey and writes it out to a WOLFSSL_BIO - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE + * Returns 1 or 0 */ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, const EVP_CIPHER* cipher, @@ -4032,13 +5128,13 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, if (bio == NULL || dsa == NULL) { WOLFSSL_MSG("Bad Function Arguments"); - return WOLFSSL_FAILURE; + return 0; } pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); if (pkey == NULL) { WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); - return WOLFSSL_FAILURE; + return 0; } pkey->type = EVP_PKEY_DSA; @@ -4052,7 +5148,7 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, if (derBuf == NULL) { WOLFSSL_MSG("Malloc failed"); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return 0; } /* convert key to der format */ @@ -4061,7 +5157,7 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, WOLFSSL_MSG("wc_DsaKeyToDer failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return 0; } pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -4069,7 +5165,7 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, WOLFSSL_MSG("key malloc failed"); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return 0; } /* add der info to the evp key */ @@ -4086,7 +5182,7 @@ int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, #ifndef HAVE_SELFTEST /* Takes a DSA public key and writes it out to a WOLFSSL_BIO - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE + * Returns 1 or 0 */ int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa) { @@ -4096,20 +5192,20 @@ int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa) if (bio == NULL || dsa == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); if (pkey == NULL) { WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); - return WOLFSSL_FAILURE; + return 0; } pkey->type = EVP_PKEY_DSA; pkey->dsa = dsa; pkey->ownDsa = 0; - ret = WriteBioPUBKEY(bio, pkey); + ret = pem_write_bio_pubkey(bio, pkey); wolfSSL_EVP_PKEY_free(pkey); return ret; } @@ -4135,18 +5231,18 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, if (pem == NULL || plen == NULL || dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } if (wc_PemGetHeaderFooter(type, &header, &footer) != 0) - return WOLFSSL_FAILURE; + return 0; if (dsa->inSet == 0) { WOLFSSL_MSG("No DSA internal set, do it"); - if (SetDsaInternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaInternal(dsa) != 1) { WOLFSSL_MSG("SetDsaInternal failed"); - return WOLFSSL_FAILURE; + return 0; } } @@ -4155,7 +5251,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER); if (derBuf == NULL) { WOLFSSL_MSG("malloc failed"); - return WOLFSSL_FAILURE; + return 0; } /* Key to DER */ @@ -4163,7 +5259,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, if (derSz < 0) { WOLFSSL_MSG("wc_DsaKeyToDer failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); - return WOLFSSL_FAILURE; + return 0; } /* encrypt DER buffer if required */ @@ -4172,7 +5268,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, ret = EncryptDerKey(derBuf, &derSz, cipher, passwd, passwdSz, &cipherInfo, der_max_len); - if (ret != WOLFSSL_SUCCESS) { + if (ret != 1) { WOLFSSL_MSG("EncryptDerKey failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); return ret; @@ -4192,7 +5288,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); if (cipherInfo != NULL) XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - return WOLFSSL_FAILURE; + return 0; } /* DER to PEM */ @@ -4203,7 +5299,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); if (cipherInfo != NULL) XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - return WOLFSSL_FAILURE; + return 0; } XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); if (cipherInfo != NULL) @@ -4213,7 +5309,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, if (*pem == NULL) { WOLFSSL_MSG("malloc failed"); XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_FAILURE; + return 0; } XMEMSET(*pem, 0, (*plen)+1); @@ -4221,11 +5317,11 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, WOLFSSL_MSG("XMEMCPY failed"); XFREE(pem, NULL, DYNAMIC_TYPE_KEY); XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_FAILURE; + return 0; } XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_SUCCESS; + return 1; #else (void)dsa; (void)cipher; @@ -4233,7 +5329,7 @@ int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, (void)passwdSz; (void)pem; (void)plen; - return WOLFSSL_FAILURE; + return 0; #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */ } @@ -4256,24 +5352,24 @@ int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa, if (fp == XBADFILE || dsa == NULL || dsa->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem, &plen); - if (ret != WOLFSSL_SUCCESS) { + if (ret != 1) { WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed"); - return WOLFSSL_FAILURE; + return 0; } ret = (int)XFWRITE(pem, plen, 1, fp); if (ret != 1) { WOLFSSL_MSG("DSA private key file write failed"); - return WOLFSSL_FAILURE; + return 0; } XFREE(pem, NULL, DYNAMIC_TYPE_KEY); - return WOLFSSL_SUCCESS; + return 1; } #endif /* NO_FILESYSTEM */ @@ -4291,7 +5387,7 @@ int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x) WOLFSSL_STUB("PEM_write_DSA_PUBKEY"); WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented"); - return WOLFSSL_FAILURE; + return 0; } #endif #endif /* NO_FILESYSTEM */ @@ -4338,7 +5434,7 @@ WOLFSSL_DSA* wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO* bio, } /* Reads an DSA public key from a WOLFSSL_BIO into a WOLFSSL_DSA. - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE + * Returns 1 or 0 */ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa, wc_pem_password_cb* cb, void* pass) @@ -4373,7 +5469,7 @@ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa, #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) -/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ +/* return 1 if success, -1 if error */ int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz) { word32 idx = 0; @@ -4383,23 +5479,23 @@ int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal, derSz); if (ret < 0) { WOLFSSL_MSG("DsaPrivateKeyDecode failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaExternal(dsa) != 1) { WOLFSSL_MSG("SetDsaExternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } dsa->inSet = 1; - return WOLFSSL_SUCCESS; + return 1; } /* Loads DSA key from DER buffer. opt = DSA_LOAD_PRIVATE or DSA_LOAD_PUBLIC. @@ -4414,7 +5510,7 @@ int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf, if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (opt == WOLFSSL_DSA_LOAD_PRIVATE) { @@ -4426,21 +5522,21 @@ int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf, if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PRIVATE) { WOLFSSL_MSG("DsaPrivateKeyDecode failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } else if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PUBLIC) { WOLFSSL_MSG("DsaPublicKeyDecode failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetDsaExternal(dsa) != WOLFSSL_SUCCESS) { + if (SetDsaExternal(dsa) != 1) { WOLFSSL_MSG("SetDsaExternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } dsa->inSet = 1; - return WOLFSSL_SUCCESS; + return 1; } #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -4512,21 +5608,21 @@ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x, return NULL; } - if (SetIndividualExternal(&dsa->p, &key->p) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->p, &key->p) != 1) { WOLFSSL_MSG("dsa p key error"); FreeDer(&pDer); wolfSSL_DSA_free(dsa); return NULL; } - if (SetIndividualExternal(&dsa->q, &key->q) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->q, &key->q) != 1) { WOLFSSL_MSG("dsa q key error"); FreeDer(&pDer); wolfSSL_DSA_free(dsa); return NULL; } - if (SetIndividualExternal(&dsa->g, &key->g) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dsa->g, &key->g) != 1) { WOLFSSL_MSG("dsa g key error"); FreeDer(&pDer); wolfSSL_DSA_free(dsa); @@ -4562,25 +5658,25 @@ WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa) if (dsa->p != NULL && SetIndividualInternal(((WOLFSSL_DSA*)dsa)->p, &key->p) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("rsa p key error"); wolfSSL_DH_free(dh); return NULL; } if (dsa->g != NULL && SetIndividualInternal(((WOLFSSL_DSA*)dsa)->g, &key->g) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("rsa g key error"); wolfSSL_DH_free(dh); return NULL; } - if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dh->p, &key->p) != 1) { WOLFSSL_MSG("dsa p key error"); wolfSSL_DH_free(dh); return NULL; } - if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dh->g, &key->g) != 1) { WOLFSSL_MSG("dsa g key error"); wolfSSL_DH_free(dh); return NULL; @@ -4618,7 +5714,7 @@ int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes) WOLFSSL_ENTER("wolfSSL_DH_check"); if (dh == NULL) { - return WOLFSSL_FAILURE; + return 0; } if (dh->g == NULL || dh->g->internal == NULL) { @@ -4636,7 +5732,7 @@ int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes) } else { WOLFSSL_MSG("Error initializing rng"); - return WOLFSSL_FAILURE; + return 0; } wc_FreeRng(&rng); if (isPrime != MP_YES) { @@ -4650,13 +5746,13 @@ int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes) /* if codeTmp was set,some check was flagged invalid */ if (codeTmp) { - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) /* Converts DER encoded DH parameters to a WOLFSSL_DH structure. * * dh : structure to copy DH parameters into. @@ -4692,7 +5788,7 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp, } newDH->inSet = 1; - if (SetDhExternal(newDH) != WOLFSSL_SUCCESS) { + if (SetDhExternal(newDH) != 1) { WOLFSSL_MSG("SetDhExternal failed"); wolfSSL_DH_free(newDH); return NULL; @@ -4705,7 +5801,7 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp, return newDH; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#endif /* !(FIPS_VERSION == 1) */ #define ASN_LEN_SIZE(l) \ (((l) < 128) ? 1 : (((l) < 256) ? 2 : 3)) @@ -4715,7 +5811,7 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp, * dh : structure to copy DH parameters from. * out : DER buffer for DH parameters * - * Returns size of DER on success and WOLFSSL_FAILURE if error + * Returns size of DER on success and 0 if error */ int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out) { @@ -4728,7 +5824,7 @@ int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out) if (dh == NULL) { WOLFSSL_MSG("Bad parameters"); - return WOLFSSL_FAILURE; + return 0; } /* Get total length */ @@ -4778,7 +5874,7 @@ long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh) gSz = wolfSSL_BN_bn2bin(dh->g, NULL); if (pSz <= 0 || gSz <= 0) - return WOLFSSL_FATAL_ERROR; + return -1; p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); if (!p) @@ -4799,7 +5895,7 @@ long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh) XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR; + return pSz > 0 && gSz > 0 ? ret : -1; } @@ -4936,7 +6032,7 @@ WOLFSSL_DH* wolSSL_DH_new_by_nid(int nid) #endif #if defined(OPENSSL_ALL) || defined(OPENSSL_VERSION_NUMBER) && \ OPENSSL_VERSION_NUMBER >= 0x10100000L - if (err == 0 && wolfSSL_DH_set0_pqg(dh, pBn, qBn, gBn) != WOLFSSL_SUCCESS) { + if (err == 0 && wolfSSL_DH_set0_pqg(dh, pBn, qBn, gBn) != 1) { WOLFSSL_MSG("Failed to set DH params."); err = 1; } @@ -4945,7 +6041,7 @@ WOLFSSL_DH* wolSSL_DH_new_by_nid(int nid) dh->p = pBn; dh->q = qBn; dh->g = gBn; - if (SetDhInternal(dh) != WOLFSSL_SUCCESS) { + if (SetDhInternal(dh) != 1) { WOLFSSL_MSG("Failed to set internal DH params."); err = 1; } @@ -4992,14 +6088,14 @@ WOLFSSL_DH* wolSSL_DH_new_by_nid(int nid) WOLFSSL_MSG("wc_DhSetNamedKey failed."); err = 1; } - if (err == 0 && SetDhExternal_ex(dh, elements) != WOLFSSL_SUCCESS) { + if (err == 0 && SetDhExternal_ex(dh, elements) != 1) { WOLFSSL_MSG("Failed to set external DH params."); err = 1; } #else /* Unsupported configuration. */ err = 1; -#endif /* HAVE_PUBLIC_FFDHE || (HAVE_FIPS && HAVE_FIPS_VERSION == 2) */ +#endif /* HAVE_PUBLIC_FFDHE || FIPS_VERSION_GT(2,0) */ if (err == 1 && dh != NULL) { wolfSSL_DH_free(dh); @@ -5067,15 +6163,15 @@ int wolfSSL_DH_up_ref(WOLFSSL_DH* dh) #ifndef SINGLE_THREADED wc_UnLockMutex(&dh->refMutex); #endif - return WOLFSSL_SUCCESS; + return 1; } - return WOLFSSL_FAILURE; + return 0; } int SetDhInternal(WOLFSSL_DH* dh) { - int ret = WOLFSSL_FATAL_ERROR; + int ret = -1; int pSz = 1024; int gSz = 1024; #ifdef WOLFSSL_DH_EXTRA @@ -5146,11 +6242,11 @@ int SetDhInternal(WOLFSSL_DH* dh) ret = wc_DhImportKeyPair((DhKey*)dh->internal, priv_key, privSz, pub_key, pubSz); if (ret == 0) { - ret = WOLFSSL_SUCCESS; + ret = 1; } else { WOLFSSL_MSG("Failed setting private or public key."); - ret = WOLFSSL_FAILURE; + ret = 0; } } #endif /* WOLFSSL_DH_EXTRA */ @@ -5164,7 +6260,7 @@ int SetDhInternal(WOLFSSL_DH* dh) WOLFSSL_MSG("Bad DH SetKey"); else { dh->inSet = 1; - ret = WOLFSSL_SUCCESS; + ret = 1; } #ifdef WOLFSSL_SMALL_STACK @@ -5195,7 +6291,7 @@ WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) return NULL; } - if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS) { + if (dh->inSet == 0 && SetDhInternal(dh) != 1) { WOLFSSL_MSG("Bad DH set internal"); return NULL; } @@ -5212,7 +6308,7 @@ WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) } ret->inSet = 1; - if (SetDhExternal(ret) != WOLFSSL_SUCCESS) { + if (SetDhExternal(ret) != 1) { WOLFSSL_MSG("SetDhExternal error"); wolfSSL_DH_free(ret); return NULL; @@ -5232,48 +6328,48 @@ int SetDhExternal_ex(WOLFSSL_DH *dh, int elm) if (dh == NULL || dh->internal == NULL) { WOLFSSL_MSG("dh key NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } key = (DhKey*)dh->internal; if (elm & ELEMENT_P) { - if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dh->p, &key->p) != 1) { WOLFSSL_MSG("dh param p error"); - return WOLFSSL_FATAL_ERROR; + return -1; } } if (elm & ELEMENT_Q) { - if (SetIndividualExternal(&dh->q, &key->q) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dh->q, &key->q) != 1) { WOLFSSL_MSG("dh param q error"); - return WOLFSSL_FATAL_ERROR; + return -1; } } if (elm & ELEMENT_G) { - if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dh->g, &key->g) != 1) { WOLFSSL_MSG("dh param g error"); - return WOLFSSL_FATAL_ERROR; + return -1; } } #ifdef WOLFSSL_DH_EXTRA if (elm & ELEMENT_PRV) { if (SetIndividualExternal(&dh->priv_key, &key->priv) != - WOLFSSL_SUCCESS) { + 1) { WOLFSSL_MSG("No DH Private Key"); - return WOLFSSL_FATAL_ERROR; + return -1; } } if (elm & ELEMENT_PUB) { - if (SetIndividualExternal(&dh->pub_key, &key->pub) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&dh->pub_key, &key->pub) != 1) { WOLFSSL_MSG("No DH Public Key"); - return WOLFSSL_FATAL_ERROR; + return -1; } } #endif /* WOLFSSL_DH_EXTRA */ dh->exSet = 1; - return WOLFSSL_SUCCESS; + return 1; } /* Set the members of DhKey into WOLFSSL_DH * DhKey was populated from wc_DhKeyDecode @@ -5295,7 +6391,7 @@ int wolfSSL_DH_size(WOLFSSL_DH* dh) WOLFSSL_MSG("wolfSSL_DH_size"); if (dh == NULL) - return WOLFSSL_FATAL_ERROR; + return -1; return wolfSSL_BN_num_bytes(dh->p); } @@ -5320,7 +6416,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_768_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 768 prime to big number"); return NULL; } @@ -5350,7 +6446,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_1024_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 1024 prime to big number"); return NULL; } @@ -5384,7 +6480,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_1536_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 1536 prime to big number"); return NULL; } @@ -5422,7 +6518,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_2048_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 2048 prime to big number"); return NULL; } @@ -5468,7 +6564,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_3072_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 3072 prime to big number"); return NULL; } @@ -5522,7 +6618,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_4096_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 4096 prime to big number"); return NULL; } @@ -5592,7 +6688,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_6144_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 6144 prime to big number"); return NULL; } @@ -5679,7 +6775,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn) WOLFSSL_ENTER("wolfSSL_DH_8192_prime"); - if (wolfSSL_BN_hex2bn(&bn, prm) != WOLFSSL_SUCCESS) { + if (wolfSSL_BN_hex2bn(&bn, prm) != 1) { WOLFSSL_MSG("Error converting DH 8192 prime to big number"); return NULL; } @@ -5697,15 +6793,15 @@ WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn) */ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) { - int ret = WOLFSSL_FAILURE; - word32 pubSz = 0; - word32 privSz = 0; - int initTmpRng = 0; - WC_RNG* rng = NULL; + int ret = 0; + word32 pubSz = 0; + word32 privSz = 0; + int initTmpRng = 0; + WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG; + WC_RNG* tmpRng; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; #endif unsigned char* pub = NULL; unsigned char* priv = NULL; @@ -5713,19 +6809,19 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) WOLFSSL_MSG("wolfSSL_DH_generate_key"); #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) { - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) { + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); return ret; } #endif if (dh == NULL || dh->p == NULL || dh->g == NULL) WOLFSSL_MSG("Bad function arguments"); - else if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS) + else if (dh->inSet == 0 && SetDhInternal(dh) != 1) WOLFSSL_MSG("Bad DH set internal"); - else if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + else if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -5778,17 +6874,17 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) else if (wolfSSL_BN_bin2bn(priv, privSz, dh->priv_key) == NULL) WOLFSSL_MSG("Bad DH bn2bin error priv"); else - ret = WOLFSSL_SUCCESS; + ret = 1; } } PRIVATE_KEY_LOCK(); } if (initTmpRng) - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY); @@ -5803,7 +6899,7 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub, WOLFSSL_DH* dh) { - int ret = WOLFSSL_FATAL_ERROR; + int ret = -1; word32 keySz = 0; int pubSz = 1024; int privSz = 1024; @@ -5840,7 +6936,7 @@ int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub, else { privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv); pubSz = wolfSSL_BN_bn2bin(otherPub, pub); - if (dh->inSet == 0 && SetDhInternal(dh) != WOLFSSL_SUCCESS) { + if (dh->inSet == 0 && SetDhInternal(dh) != 1) { WOLFSSL_MSG("Bad DH set internal"); } PRIVATE_KEY_UNLOCK(); @@ -5874,17 +6970,17 @@ int wolfSSL_DH_set_length(WOLFSSL_DH *dh, long len) /* len is checked at generation */ if (dh == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } dh->length = (int)len; - return WOLFSSL_SUCCESS; + return 1; } /* ownership of p,q,and g get taken over by "dh" on success and should be free'd * with a call to wolfSSL_DH_free -- not individually. * - * returns WOLFSSL_SUCCESS on success + * returns 1 on success */ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g) @@ -5895,7 +6991,7 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, /* q can be NULL */ if (dh == NULL || p == NULL || g == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } /* free existing internal DH structure and recreate with new p / g */ @@ -5904,7 +7000,7 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, ret = wc_FreeDhKey((DhKey*)dh->internal); if (ret != 0) { WOLFSSL_MSG("Unable to free internal DH key"); - return WOLFSSL_FAILURE; + return 0; } #else /* Selftest code has this API with a void return type */ @@ -5921,16 +7017,16 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, dh->g = g; ret = SetDhInternal(dh); - if (ret != WOLFSSL_SUCCESS) { + if (ret != 1) { WOLFSSL_MSG("Unable to set internal DH key"); dh->p = NULL; dh->q = NULL; dh->g = NULL; dh->inSet = 0; - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } #endif /* OPENSSL_ALL || (v1.1.0 or later) */ #endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) || @@ -5943,10 +7039,10 @@ void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, if (dh != NULL) { if (pub_key != NULL && dh->pub_key != NULL && - wolfSSL_BN_is_zero(dh->pub_key) != WOLFSSL_SUCCESS) + wolfSSL_BN_is_zero(dh->pub_key) != 1) *pub_key = dh->pub_key; if (priv_key != NULL && dh->priv_key != NULL && - wolfSSL_BN_is_zero(dh->priv_key) != WOLFSSL_SUCCESS) + wolfSSL_BN_is_zero(dh->priv_key) != 1) *priv_key = dh->priv_key; } } @@ -5957,7 +7053,7 @@ int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, WOLFSSL_ENTER("wolfSSL_DH_set0_key"); if (dh == NULL) - return WOLFSSL_FAILURE; + return 0; if (pub_key != NULL) { wolfSSL_BN_free(dh->pub_key); @@ -5970,7 +7066,7 @@ int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, } if (dh->p == NULL || dh->g == NULL) - return WOLFSSL_SUCCESS; /* Allow loading parameters afterwards */ + return 1; /* Allow loading parameters afterwards */ else return SetDhInternal(dh); } @@ -6066,7 +7162,7 @@ WOLFSSL_DH* wolfSSL_DH_get_2048_256(void) if (err == 0) { #if defined(OPENSSL_ALL) || \ defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L - if (wolfSSL_DH_set0_pqg(ret, pBn, qBn, gBn) != WOLFSSL_SUCCESS) { + if (wolfSSL_DH_set0_pqg(ret, pBn, qBn, gBn) != 1) { WOLFSSL_MSG("Error setting DH parameters."); err = 1; } @@ -6075,7 +7171,7 @@ WOLFSSL_DH* wolfSSL_DH_get_2048_256(void) ret->q = qBn; ret->g = gBn; - if (SetDhInternal(ret) != WOLFSSL_SUCCESS) { + if (SetDhInternal(ret) != 1) { WOLFSSL_MSG("Error setting DH parameters."); err = 1; } @@ -6095,8 +7191,8 @@ WOLFSSL_DH* wolfSSL_DH_get_2048_256(void) #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || \ defined(WOLFSSL_OPENSSH) || defined(OPENSSL_EXTRA) -/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +/* return 1 if success, -1 if error */ +#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) { word32 idx = 0; @@ -6104,24 +7200,24 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) if (dh == NULL || dh->internal == NULL || derBuf == NULL || derSz <= 0) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } ret = wc_DhKeyDecode(derBuf, &idx, (DhKey*)dh->internal, (word32)derSz); if (ret < 0) { WOLFSSL_MSG("wc_DhKeyDecode failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } dh->inSet = 1; - if (SetDhExternal(dh) != WOLFSSL_SUCCESS) { + if (SetDhExternal(dh) != 1) { WOLFSSL_MSG("SetDhExternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } - return WOLFSSL_SUCCESS; + return 1; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#endif /* !HAVE_FIPS || FIPS_VERION > 2 */ #endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH || OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */ @@ -6241,7 +7337,7 @@ WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x, } if (localDh != NULL && localDh->inSet == 0) { - if (SetDhInternal(localDh) != WOLFSSL_SUCCESS) { + if (SetDhInternal(localDh) != 1) { WOLFSSL_MSG("Unable to set internal DH structure"); wolfSSL_DH_free(localDh); localDh = NULL; @@ -6289,7 +7385,7 @@ WOLFSSL_DH *wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH **x, return NULL; } - if (wolfSSL_BIO_set_fp(fbio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) { + if (wolfSSL_BIO_set_fp(fbio, fp, BIO_NOCLOSE) != 1) { wolfSSL_BIO_free(fbio); WOLFSSL_MSG("wolfSSL_BIO_set_fp error"); return NULL; @@ -6308,7 +7404,7 @@ WOLFSSL_DH *wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH **x, /* Writes the DH parameters in PEM format from "dh" out to the file pointer * passed in. * - * returns WOLFSSL_SUCCESS on success + * returns 1 on success */ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh) { @@ -6321,13 +7417,13 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh) if (dh == NULL) { WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", BAD_FUNC_ARG); - return WOLFSSL_FAILURE; + return 0; } if (dh->inSet == 0) { - if (SetDhInternal(dh) != WOLFSSL_SUCCESS) { + if (SetDhInternal(dh) != 1) { WOLFSSL_MSG("Unable to set internal DH structure"); - return WOLFSSL_FAILURE; + return 0; } } key = (DhKey*)dh->internal; @@ -6335,20 +7431,20 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh) if (ret != LENGTH_ONLY_E) { WOLFSSL_MSG("Failed to get size of DH params"); WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret); - return WOLFSSL_FAILURE; + return 0; } der = (byte*)XMALLOC(derSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", MEMORY_E); - return WOLFSSL_FAILURE; + return 0; } ret = wc_DhParamsToDer(key, der, &derSz); if (ret <= 0) { WOLFSSL_MSG("Failed to export DH params"); WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret); XFREE(der, key->heap, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + return 0; } /* convert to PEM */ @@ -6381,10 +7477,10 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh) if (ret <= 0) { WOLFSSL_MSG("Failed to write to file"); WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret); - return WOLFSSL_FAILURE; + return 0; } - WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", WOLFSSL_SUCCESS); - return WOLFSSL_SUCCESS; + WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", 1); + return 1; } #endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */ @@ -6412,7 +7508,7 @@ WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator, } if (wolfSSL_DH_generate_parameters_ex(dh, prime_len, generator, NULL) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("wolfSSL_DH_generate_parameters_ex error"); wolfSSL_DH_free(dh); return NULL; @@ -6433,13 +7529,13 @@ int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, if (dh == NULL) { WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; + return 0; } if ((rng = wolfssl_get_global_rng()) == NULL) { - if (wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) { + if (wolfSSL_RAND_Init() != 1) { WOLFSSL_MSG("No RNG to use"); - return WOLFSSL_FAILURE; + return 0; } rng = wolfssl_get_global_rng(); } @@ -6454,18 +7550,18 @@ int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len, if (wc_DhGenerateParams(rng, prime_len, key) != 0) { WOLFSSL_MSG("wc_DhGenerateParams error"); - return WOLFSSL_FAILURE; + return 0; } dh->inSet = 1; WOLFSSL_MSG("wolfSSL does not support using a custom generator."); - if (SetDhExternal(dh) != WOLFSSL_SUCCESS) { + if (SetDhExternal(dh) != 1) { WOLFSSL_MSG("SetDhExternal error"); - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } #endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST */ @@ -6520,7 +7616,7 @@ void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p, !defined(NO_STDIO_FILESYSTEM) int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent) { - int ret = WOLFSSL_SUCCESS; + int ret = 1; int bits = 0; int priv = 0; int nid = 0; @@ -6531,17 +7627,17 @@ int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent) WOLFSSL_ENTER("wolfSSL_EC_KEY_print_fp"); if (fp == XBADFILE || key == NULL || key->group == NULL || indent < 0) { - ret = WOLFSSL_FAILURE; + ret = 0; } - if (ret == WOLFSSL_SUCCESS) { + if (ret == 1) { bits = wolfSSL_EC_GROUP_order_bits(key->group); if (bits <= 0) { WOLFSSL_MSG("Failed to get group order bits."); - ret = WOLFSSL_FAILURE; + ret = 0; } } - if (ret == WOLFSSL_SUCCESS) { + if (ret == 1) { XFPRINTF(fp, "%*s", indent, ""); if (key->priv_key != NULL && !wolfSSL_BN_is_zero(key->priv_key)) { XFPRINTF(fp, "Private-Key: (%d bit)\n", bits); @@ -6552,22 +7648,22 @@ int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent) } if (priv) { - ret = PrintBNFieldFp(fp, indent, "priv", key->priv_key); + ret = pk_bn_field_print_fp(fp, indent, "priv", key->priv_key); } } - if (ret == WOLFSSL_SUCCESS && key->pub_key != NULL && key->pub_key->exSet) { + if (ret == 1 && key->pub_key != NULL && key->pub_key->exSet) { pubBn = wolfSSL_EC_POINT_point2bn(key->group, key->pub_key, POINT_CONVERSION_UNCOMPRESSED, NULL, NULL); if (pubBn == NULL) { WOLFSSL_MSG("wolfSSL_EC_POINT_point2bn failed."); - ret = WOLFSSL_FAILURE; + ret = 0; } else { - ret = PrintBNFieldFp(fp, indent, "pub", pubBn); + ret = pk_bn_field_print_fp(fp, indent, "pub", pubBn); } } - if (ret == WOLFSSL_SUCCESS) { + if (ret == 1) { nid = wolfSSL_EC_GROUP_get_curve_name(key->group); if (nid > 0) { curve = wolfSSL_OBJ_nid2ln(nid); @@ -6743,20 +7839,20 @@ static int SetIndividualInternalEcc(WOLFSSL_BIGNUM* bn, mp_int* mpi) if (bn == NULL || bn->internal == NULL) { WOLFSSL_MSG("bn NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (mpi == NULL) { WOLFSSL_MSG("mpi NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - return WOLFSSL_SUCCESS; + return 1; } #endif /* ALT_ECC_SIZE */ @@ -6768,52 +7864,52 @@ static int SetECPointInternal(WOLFSSL_EC_POINT *p) if (p == NULL || p->internal == NULL) { WOLFSSL_MSG("ECPoint NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } point = (ecc_point*)p->internal; #ifndef ALT_ECC_SIZE if (p->X != NULL && SetIndividualInternal(p->X, point->x) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecc point X error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (p->Y != NULL && SetIndividualInternal(p->Y, point->y) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecc point Y error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (p->Z != NULL && SetIndividualInternal(p->Z, point->z) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecc point Z error"); - return WOLFSSL_FATAL_ERROR; + return -1; } #else if (p->X != NULL && SetIndividualInternalEcc(p->X, point->x) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecc point X error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (p->Y != NULL && SetIndividualInternalEcc(p->Y, point->y) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecc point Y error"); - return WOLFSSL_FATAL_ERROR; + return -1; } if (p->Z != NULL && SetIndividualInternalEcc(p->Z, point->z) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecc point Z error"); - return WOLFSSL_FATAL_ERROR; + return -1; } #endif p->inSet = 1; - return WOLFSSL_SUCCESS; + return 1; } /* EC_POINT WolfSSL -> OpenSSL */ @@ -6825,29 +7921,29 @@ static int SetECPointExternal(WOLFSSL_EC_POINT *p) if (p == NULL || p->internal == NULL) { WOLFSSL_MSG("ECPoint NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } point = (ecc_point*)p->internal; - if (SetIndividualExternal(&p->X, point->x) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&p->X, point->x) != 1) { WOLFSSL_MSG("ecc point X error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetIndividualExternal(&p->Y, point->y) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&p->Y, point->y) != 1) { WOLFSSL_MSG("ecc point Y error"); - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetIndividualExternal(&p->Z, point->z) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&p->Z, point->z) != 1) { WOLFSSL_MSG("ecc point Z error"); - return WOLFSSL_FATAL_ERROR; + return -1; } p->exSet = 1; - return WOLFSSL_SUCCESS; + return 1; } @@ -6860,7 +7956,7 @@ int SetECKeyExternal(WOLFSSL_EC_KEY* eckey) if (eckey == NULL || eckey->internal == NULL) { WOLFSSL_MSG("ec key NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } key = (ecc_key*)eckey->internal; @@ -6875,27 +7971,27 @@ int SetECKeyExternal(WOLFSSL_EC_KEY* eckey) if (wc_ecc_copy_point(&key->pubkey, (ecc_point*)eckey->pub_key->internal) != MP_OKAY) { WOLFSSL_MSG("SetECKeyExternal ecc_copy_point failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* set the external pubkey (point) */ - if (SetECPointExternal(eckey->pub_key) != WOLFSSL_SUCCESS) { + if (SetECPointExternal(eckey->pub_key) != 1) { WOLFSSL_MSG("SetECKeyExternal SetECPointExternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } } /* set the external privkey */ if (key->type == ECC_PRIVATEKEY) { - if (SetIndividualExternal(&eckey->priv_key, &key->k) != WOLFSSL_SUCCESS) { + if (SetIndividualExternal(&eckey->priv_key, &key->k) != 1) { WOLFSSL_MSG("ec priv key error"); - return WOLFSSL_FATAL_ERROR; + return -1; } } eckey->exSet = 1; - return WOLFSSL_SUCCESS; + return 1; } /* EC_KEY Openssl -> WolfSSL */ @@ -6907,7 +8003,7 @@ int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) if (eckey == NULL || eckey->internal == NULL || eckey->group == NULL) { WOLFSSL_MSG("ec key NULL error"); - return WOLFSSL_FATAL_ERROR; + return -1; } key = (ecc_key*)eckey->internal; @@ -6916,7 +8012,7 @@ int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) if ((eckey->group->curve_idx < 0) || (wc_ecc_is_valid_idx(eckey->group->curve_idx) == 0)) { WOLFSSL_MSG("invalid curve idx"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* set group (idx of curve and corresponding domain parameters) */ @@ -6925,16 +8021,16 @@ int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) /* set pubkey (point) */ if (eckey->pub_key != NULL) { - if (SetECPointInternal(eckey->pub_key) != WOLFSSL_SUCCESS) { + if (SetECPointInternal(eckey->pub_key) != 1) { WOLFSSL_MSG("ec key pub error"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* copy over the public point to key */ if (wc_ecc_copy_point((ecc_point*)eckey->pub_key->internal, &key->pubkey) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_copy_point error"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* public key */ @@ -6944,9 +8040,9 @@ int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) /* set privkey */ if (eckey->priv_key != NULL) { if (SetIndividualInternal(eckey->priv_key, &key->k) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ec key priv error"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* private key */ @@ -6956,7 +8052,7 @@ int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) eckey->inSet = 1; - return WOLFSSL_SUCCESS; + return 1; } WOLFSSL_EC_POINT *wolfSSL_EC_KEY_get0_public_key(const WOLFSSL_EC_KEY *key) @@ -6994,7 +8090,7 @@ int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key, if (key == NULL || priv_key == NULL) { WOLFSSL_MSG("Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } /* free key if previously set */ @@ -7004,16 +8100,16 @@ int wolfSSL_EC_KEY_set_private_key(WOLFSSL_EC_KEY *key, key->priv_key = wolfSSL_BN_dup(priv_key); if (key->priv_key == NULL) { WOLFSSL_MSG("key ecc priv key NULL"); - return WOLFSSL_FAILURE; + return 0; } - if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(key) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); wolfSSL_BN_free(key->priv_key); - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } @@ -7219,7 +8315,7 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) } /* Increments ref count of WOLFSSL_EC_KEY. - * Return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on error */ + * Return 1 on success, 0 on error */ int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key) { if (key) { @@ -7232,17 +8328,17 @@ int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key) #ifndef SINGLE_THREADED wc_UnLockMutex(&key->refMutex); #endif - return WOLFSSL_SUCCESS; + return 1; } - return WOLFSSL_FAILURE; + return 0; } -/* set the group in WOLFSSL_EC_KEY and return WOLFSSL_SUCCESS on success */ +/* set the group in WOLFSSL_EC_KEY and return 1 on success */ int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group) { if (key == NULL || group == NULL) - return WOLFSSL_FAILURE; + return 0; WOLFSSL_ENTER("wolfSSL_EC_KEY_set_group"); @@ -7253,10 +8349,10 @@ int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group) key->group = wolfSSL_EC_GROUP_dup(group); if (key->group == NULL) { - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } @@ -7266,9 +8362,9 @@ int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) int eccEnum; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRng = NULL; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; #endif int ret; ecc_key* ecKey; @@ -7287,13 +8383,13 @@ int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) } #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) return 0; #endif - if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -7304,7 +8400,7 @@ int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) if (rng == NULL) { WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to set RNG"); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif return 0; } @@ -7322,18 +8418,18 @@ int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key) if (ret != 0) { WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key wc_ecc_make_key failed"); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif return 0; } if (initTmpRng) - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); #ifdef WOLFSSL_SMALL_STACK - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif - if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyExternal(key) != 1) { WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key SetECKeyExternal failed"); return 0; } @@ -7354,17 +8450,17 @@ void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag) static int setupPoint(const WOLFSSL_EC_POINT *p) { if (!p) { - return WOLFSSL_FAILURE; + return 0; } if (p->inSet == 0) { WOLFSSL_MSG("No ECPoint internal set, do it"); - if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != WOLFSSL_SUCCESS) { + if (SetECPointInternal((WOLFSSL_EC_POINT *)p) != 1) { WOLFSSL_MSG("SetECPointInternal SetECPointInternal failed"); - return WOLFSSL_FAILURE; + return 0; } } - return WOLFSSL_SUCCESS; + return 1; } /* return code compliant with OpenSSL : @@ -7380,18 +8476,18 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, if (key == NULL || key->internal == NULL || pub == NULL || pub->internal == NULL) { WOLFSSL_MSG("wolfSSL_EC_KEY_set_public_key Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } if (key->inSet == 0) { - if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(key) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FAILURE; + return 0; } } - if (setupPoint(pub) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (setupPoint(pub) != 1) { + return 0; } pub_p = (ecc_point*)pub->internal; @@ -7403,28 +8499,28 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, if (key_p == NULL) { WOLFSSL_MSG("key ecc point NULL"); - return WOLFSSL_FAILURE; + return 0; } if (wc_ecc_copy_point(pub_p, key_p) != MP_OKAY) { WOLFSSL_MSG("ecc_copy_point failure"); - return WOLFSSL_FAILURE; + return 0; } - if (SetECPointExternal(key->pub_key) != WOLFSSL_SUCCESS) { + if (SetECPointExternal(key->pub_key) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FAILURE; + return 0; } - if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(key) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FAILURE; + return 0; } wolfSSL_EC_POINT_dump("pub", pub); wolfSSL_EC_POINT_dump("key->pub_key", key->pub_key); - return WOLFSSL_SUCCESS; + return 1; } int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key) @@ -7433,18 +8529,18 @@ int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key) if (key == NULL || key->internal == NULL) { WOLFSSL_MSG("Bad parameter"); - return WOLFSSL_FAILURE; + return 0; } if (key->inSet == 0) { - if (SetECKeyInternal((WOLFSSL_EC_KEY*)key) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal((WOLFSSL_EC_KEY*)key) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FAILURE; + return 0; } } return wc_ecc_check_key((ecc_key*)key->internal) == 0 ? - WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + 1 : 0; } /* End EC_KEY */ @@ -7456,15 +8552,15 @@ int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key) word32 headerSz = SIG_HEADER_SZ; /* 2*ASN_TAG + 2*LEN(ENUM) */ if (key == NULL) { - return WOLFSSL_FAILURE; + return 0; } if ((group = wolfSSL_EC_KEY_get0_group(key)) == NULL) { - return WOLFSSL_FAILURE; + return 0; } if ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0) { /* group is not set */ - return WOLFSSL_FAILURE; + return 0; } bytes = (bits + 7) / 8; /* bytes needed to hold bits */ @@ -7477,29 +8573,29 @@ int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, int digestSz, unsigned char *sig, unsigned int *sigSz, WOLFSSL_EC_KEY *key) { - int ret = WOLFSSL_SUCCESS; + int ret = 1; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRng = NULL; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; #endif int initTmpRng = 0; WOLFSSL_ENTER("wolfSSL_ECDSA_sign"); if (!key) { - return WOLFSSL_FAILURE; + return 0; } #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) - return WOLFSSL_FAILURE; + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) + return 0; #endif - if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -7509,18 +8605,18 @@ int wolfSSL_ECDSA_sign(int type, if (rng) { if (wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng, (ecc_key*)key->internal) != 0) { - ret = WOLFSSL_FAILURE; + ret = 0; } if (initTmpRng) { - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); } } else { - ret = WOLFSSL_FAILURE; + ret = 0; } #ifdef WOLFSSL_SMALL_STACK - if (tmpRNG) - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + if (tmpRng) + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif (void)type; @@ -7531,22 +8627,22 @@ int wolfSSL_ECDSA_verify(int type, const unsigned char *digest, int digestSz, const unsigned char *sig, int sigSz, WOLFSSL_EC_KEY *key) { - int ret = WOLFSSL_SUCCESS; + int ret = 1; int verify = 0; WOLFSSL_ENTER("wolfSSL_ECDSA_verify"); if (key == NULL) { - return WOLFSSL_FAILURE; + return 0; } if (wc_ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, (ecc_key*)key->internal) != 0) { - ret = WOLFSSL_FAILURE; + ret = 0; } - if (ret == WOLFSSL_SUCCESS && verify != 1) { + if (ret == 1 && verify != 1) { WOLFSSL_MSG("wolfSSL_ECDSA_verify failed"); - ret = WOLFSSL_FAILURE; + ret = 0; } (void)type; @@ -7662,7 +8758,7 @@ int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b, if (a == NULL || b == NULL) { WOLFSSL_MSG("wolfSSL_EC_GROUP_cmp Bad arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* ok */ @@ -7694,7 +8790,7 @@ int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth) if (meth) { return NID_X9_62_prime_field; } - return WOLFSSL_FAILURE; + return 0; } void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group) @@ -7764,7 +8860,7 @@ int wolfSSL_EC_GROUP_get_curve_name(const WOLFSSL_EC_GROUP *group) if (group == NULL) { WOLFSSL_MSG("wolfSSL_EC_GROUP_get_curve_name Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } /* If curve_nid is ECC Enum type, return corresponding OpenSSL nid */ @@ -7786,7 +8882,7 @@ int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group) if (group == NULL || group->curve_idx < 0) { WOLFSSL_MSG("wolfSSL_EC_GROUP_get_degree Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } /* If curve_nid passed in is an ecc_curve_id enum, convert it to the @@ -7833,7 +8929,7 @@ int wolfSSL_EC_GROUP_get_degree(const WOLFSSL_EC_GROUP *group) case NID_brainpoolP512r1: return 512; default: - return WOLFSSL_FAILURE; + return 0; } } @@ -7914,22 +9010,22 @@ int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group, if (group == NULL || order == NULL || order->internal == NULL) { WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order NULL error"); - return WOLFSSL_FAILURE; + return 0; } if (mp_init((mp_int*)order->internal) != MP_OKAY) { WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_init failure"); - return WOLFSSL_FAILURE; + return 0; } if (mp_read_radix((mp_int*)order->internal, ecc_sets[group->curve_idx].order, MP_RADIX_HEX) != MP_OKAY) { WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order mp_read order failure"); mp_clear((mp_int*)order->internal); - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group) @@ -7971,11 +9067,11 @@ int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group, if (group == NULL || p == NULL || len == NULL) { WOLFSSL_MSG("wolfSSL_ECPoint_i2d NULL error"); - return WOLFSSL_FAILURE; + return 0; } - if (setupPoint(p) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (setupPoint(p) != 1) { + return 0; } if (out != NULL) { @@ -7986,10 +9082,10 @@ int wolfSSL_ECPoint_i2d(const WOLFSSL_EC_GROUP *group, out, len); if (err != MP_OKAY && !(out == NULL && err == LENGTH_ONLY_E)) { WOLFSSL_MSG("wolfSSL_ECPoint_i2d wc_ecc_export_point_der failed"); - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } /* return code compliant with OpenSSL : @@ -8002,15 +9098,14 @@ int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len, if (group == NULL || p == NULL || p->internal == NULL || in == NULL) { WOLFSSL_MSG("wolfSSL_ECPoint_d2i NULL error"); - return WOLFSSL_FAILURE; + return 0; } -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) if (wc_ecc_import_point_der_ex(in, len, group->curve_idx, (ecc_point*)p->internal, 0) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_import_point_der_ex failed"); - return WOLFSSL_FAILURE; + return 0; } #else /* ECC_POINT_UNCOMP is not defined CAVP self test so use magic number */ @@ -8018,24 +9113,24 @@ int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len, if (wc_ecc_import_point_der(in, len, group->curve_idx, (ecc_point*)p->internal) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_import_point_der failed"); - return WOLFSSL_FAILURE; + return 0; } } else { WOLFSSL_MSG("Only uncompressed points supported with HAVE_SELFTEST"); - return WOLFSSL_FAILURE; + return 0; } #endif /* Set new external point */ - if (SetECPointExternal(p) != WOLFSSL_SUCCESS) { + if (SetECPointExternal(p) != 1) { WOLFSSL_MSG("SetECPointExternal failed"); - return WOLFSSL_FAILURE; + return 0; } wolfSSL_EC_POINT_dump("d2i p", p); - return WOLFSSL_SUCCESS; + return 1; } size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, @@ -8044,19 +9139,18 @@ size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, byte *buf, size_t len, WOLFSSL_BN_CTX *ctx) { word32 min_len = (word32)len; -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) int compressed = form == POINT_CONVERSION_COMPRESSED ? 1 : 0; #endif /* !HAVE_SELFTEST */ WOLFSSL_ENTER("EC_POINT_point2oct"); if (!group || !p) { - return WOLFSSL_FAILURE; + return 0; } - if (setupPoint(p) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (setupPoint(p) != 1) { + return 0; } if (wolfSSL_EC_POINT_is_at_infinity(group, p)) { @@ -8064,7 +9158,7 @@ size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, if (buf != NULL) { if (len < 1) { ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); - return WOLFSSL_FAILURE; + return 0; } buf[0] = 0; } @@ -8077,19 +9171,18 @@ size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, #endif /* !HAVE_SELFTEST */ ) { WOLFSSL_MSG("Unsupported curve form"); - return WOLFSSL_FAILURE; + return 0; } -#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) if (wc_ecc_export_point_der_ex(group->curve_idx, (ecc_point*)p->internal, buf, &min_len, compressed) != (buf ? MP_OKAY : LENGTH_ONLY_E)) { - return WOLFSSL_FAILURE; + return 0; } #else if (wc_ecc_export_point_der(group->curve_idx, (ecc_point*)p->internal, buf, &min_len) != (buf ? MP_OKAY : LENGTH_ONLY_E)) { - return WOLFSSL_FAILURE; + return 0; } #endif /* !HAVE_SELFTEST */ @@ -8106,7 +9199,7 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point"); if (!group || !p) { - return WOLFSSL_FAILURE; + return 0; } (void)ctx; @@ -8130,7 +9223,7 @@ WOLFSSL_EC_KEY *wolfSSL_o2i_ECPublicKey(WOLFSSL_EC_KEY **a, const unsigned char ret = *a; if (wolfSSL_EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("wolfSSL_EC_POINT_oct2point error"); return NULL; } @@ -8148,13 +9241,13 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) if (!in) { WOLFSSL_MSG("wolfSSL_i2o_ECPublicKey Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } if (!in->exSet) { - if (SetECKeyExternal((WOLFSSL_EC_KEY*)in) != WOLFSSL_SUCCESS) { + if (SetECKeyExternal((WOLFSSL_EC_KEY*)in) != 1) { WOLFSSL_MSG("SetECKeyExternal failure"); - return WOLFSSL_FAILURE; + return 0; } } @@ -8170,23 +9263,23 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) len = wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form, NULL, 0, NULL); - if (len != WOLFSSL_FAILURE && out) { + if (len != 0 && out) { if (!*out) { if (!(tmp = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL))) { WOLFSSL_MSG("malloc failed"); - return WOLFSSL_FAILURE; + return 0; } *out = tmp; } if (wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form, *out, - len, NULL) == WOLFSSL_FAILURE) { + len, NULL) == 0) { if (tmp) { XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); *out = NULL; } - return WOLFSSL_FAILURE; + return 0; } if (!tmp) { @@ -8224,7 +9317,7 @@ WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned ch eckey->inSet = 1; - if (SetECKeyExternal(eckey) != WOLFSSL_SUCCESS) { + if (SetECKeyExternal(eckey) != 1) { WOLFSSL_MSG("SetECKeyExternal error"); goto error; } @@ -8249,30 +9342,30 @@ int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out) if (!in) { WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments"); - return WOLFSSL_FAILURE; + return 0; } if (!in->inSet && SetECKeyInternal( - (WOLFSSL_EC_KEY*)in) != WOLFSSL_SUCCESS) { + (WOLFSSL_EC_KEY*)in) != 1) { WOLFSSL_MSG("SetECKeyInternal error"); - return WOLFSSL_FAILURE; + return 0; } if ((len = wc_EccKeyDerSize((ecc_key*)in->internal, 0)) <= 0) { WOLFSSL_MSG("wc_EccKeyDerSize error"); - return WOLFSSL_FAILURE; + return 0; } if (out) { if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { WOLFSSL_MSG("tmp buffer malloc error"); - return WOLFSSL_FAILURE; + return 0; } if (wc_EccPrivateKeyToDer((ecc_key*)in->internal, buf, len) < 0) { WOLFSSL_MSG("wc_EccPrivateKeyToDer error"); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; + return 0; } if (*out) { @@ -8325,7 +9418,7 @@ WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, } if ((len = wolfSSL_EC_POINT_point2oct(group, p, form, - NULL, 0, ctx)) == WOLFSSL_FAILURE) { + NULL, 0, ctx)) == 0) { return NULL; } @@ -8344,8 +9437,7 @@ WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, return ret; } -#if defined(USE_ECC_B_PARAM) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#if defined(USE_ECC_B_PARAM) && (!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)) int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, const WOLFSSL_EC_POINT *point, WOLFSSL_BN_CTX *ctx) @@ -8355,19 +9447,19 @@ int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, if (!group || !point) { WOLFSSL_MSG("Invalid arguments"); - return WOLFSSL_FAILURE; + return 0; } if (!point->inSet && SetECPointInternal((WOLFSSL_EC_POINT*)point)) { WOLFSSL_MSG("SetECPointInternal error"); - return WOLFSSL_FAILURE; + return 0; } return wc_ecc_point_is_on_curve((ecc_point*)point->internal, group->curve_idx) - == MP_OKAY ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + == MP_OKAY ? 1 : 0; } -#endif /* USE_ECC_B_PARAM && (!HAVE_FIPS || HAVE_FIPS_VERSION > 2) */ +#endif /* USE_ECC_B_PARAM && !(FIPS_VERSION <= 2) */ WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) { @@ -8422,17 +9514,17 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, x == NULL || y == NULL || wolfSSL_EC_POINT_is_at_infinity(group, point)) { WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error"); - return WOLFSSL_FAILURE; + return 0; } - if (setupPoint(point) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (setupPoint(point) != 1) { + return 0; } #ifdef WOLFSSL_SMALL_STACK modulus = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (modulus == NULL) { - return WOLFSSL_FAILURE; + return 0; } #endif @@ -8442,7 +9534,7 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, #ifdef WOLFSSL_SMALL_STACK XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } /* Map the Jacobian point back to affine space */ if (mp_read_radix(modulus, ecc_sets[group->curve_idx].prime, @@ -8452,7 +9544,7 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, #ifdef WOLFSSL_SMALL_STACK XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } if (mp_montgomery_setup(modulus, &mp) != MP_OKAY) { WOLFSSL_MSG("mp_montgomery_setup failed"); @@ -8460,7 +9552,7 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, #ifdef WOLFSSL_SMALL_STACK XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } if (ecc_map((ecc_point*)point->internal, modulus, mp) != MP_OKAY) { WOLFSSL_MSG("ecc_map failed"); @@ -8468,15 +9560,15 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, #ifdef WOLFSSL_SMALL_STACK XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } - if (SetECPointExternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) { + if (SetECPointExternal((WOLFSSL_EC_POINT *)point) != 1) { WOLFSSL_MSG("SetECPointExternal failed"); mp_clear(modulus); #ifdef WOLFSSL_SMALL_STACK XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } mp_clear(modulus); @@ -8489,7 +9581,7 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, XFREE(modulus, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_SUCCESS; + return 1; } #endif @@ -8505,7 +9597,7 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, if (group == NULL || point == NULL || point->internal == NULL || x == NULL || y == NULL) { WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error"); - return WOLFSSL_FAILURE; + return 0; } if (!point->X) { @@ -8519,19 +9611,19 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, } if (!point->X || !point->Y || !point->Z) { WOLFSSL_MSG("wolfSSL_BN_new failed"); - return WOLFSSL_FAILURE; + return 0; } BN_copy(point->X, x); BN_copy(point->Y, y); BN_copy(point->Z, wolfSSL_BN_value_one()); - if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) { + if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != 1) { WOLFSSL_MSG("SetECPointInternal failed"); - return WOLFSSL_FAILURE; + return 0; } - return WOLFSSL_SUCCESS; + return 1; } #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ @@ -8555,40 +9647,40 @@ int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, ecc_point* montP2 = NULL; ecc_point* eccP1; ecc_point* eccP2; - int ret = WOLFSSL_FAILURE; + int ret = 0; (void)ctx; if (!group || !r || !p1 || !p2) { WOLFSSL_MSG("wolfSSL_EC_POINT_add error"); - return WOLFSSL_FAILURE; + return 0; } - if (setupPoint(r) != WOLFSSL_SUCCESS || - setupPoint(p1) != WOLFSSL_SUCCESS || - setupPoint(p2) != WOLFSSL_SUCCESS) { + if (setupPoint(r) != 1 || + setupPoint(p1) != 1 || + setupPoint(p2) != 1) { WOLFSSL_MSG("setupPoint error"); - return WOLFSSL_FAILURE; + return 0; } #ifdef WOLFSSL_SMALL_STACK a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (a == NULL) { WOLFSSL_MSG("Failed to allocate memory for mp_int a"); - return WOLFSSL_FAILURE; + return 0; } prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (prime == NULL) { WOLFSSL_MSG("Failed to allocate memory for mp_int prime"); XFREE(a, NULL, DYNAMIC_TYPE_BIGINT); - return WOLFSSL_FAILURE; + return 0; } mu = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (mu == NULL) { WOLFSSL_MSG("Failed to allocate memory for mp_int mu"); XFREE(a, NULL, DYNAMIC_TYPE_BIGINT); XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT); - return WOLFSSL_FAILURE; + return 0; } XMEMSET(a, 0, sizeof(mp_int)); XMEMSET(prime, 0, sizeof(mp_int)); @@ -8665,7 +9757,7 @@ int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, goto cleanup; } - ret = WOLFSSL_SUCCESS; + ret = 1; cleanup: mp_clear(a); mp_clear(prime); @@ -8694,7 +9786,7 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, #else mp_int a[1], prime[1]; #endif - int ret = WOLFSSL_FAILURE; + int ret = 0; ecc_point* result = NULL; ecc_point* tmp = NULL; @@ -8704,24 +9796,24 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, if (!group || !r) { WOLFSSL_MSG("wolfSSL_EC_POINT_mul NULL error"); - return WOLFSSL_FAILURE; + return 0; } #ifdef WOLFSSL_SMALL_STACK a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (a == NULL) { - return WOLFSSL_FAILURE; + return 0; } prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (prime == NULL) { XFREE(a, NULL, DYNAMIC_TYPE_BIGINT); - return WOLFSSL_FAILURE; + return 0; } #endif if (!(result = wc_ecc_new_point())) { WOLFSSL_MSG("wolfSSL_EC_POINT_new error"); - return WOLFSSL_FAILURE; + return 0; } /* read the curve prime and a */ @@ -8730,7 +9822,7 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, goto cleanup; } - if (q && setupPoint(q) != WOLFSSL_SUCCESS) { + if (q && setupPoint(q) != 1) { WOLFSSL_MSG("setupPoint error"); goto cleanup; } @@ -8749,8 +9841,7 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, if (n) { /* load generator */ - #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION>2)) + #if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) if (wc_ecc_get_generator(result, group->curve_idx) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_get_generator error"); @@ -8772,7 +9863,7 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, WOLFSSL_MSG("mp_set Gz error"); goto cleanup; } - #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ + #endif /* NOPT_FIPS_VERSION == 2 */ } if (n && q && m) { @@ -8842,12 +9933,12 @@ int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, goto cleanup; } r->inSet = 1; - if (SetECPointExternal(r) != WOLFSSL_SUCCESS) { + if (SetECPointExternal(r) != 1) { WOLFSSL_MSG("SetECPointExternal error"); goto cleanup; } - ret = WOLFSSL_SUCCESS; + ret = 1; cleanup: mp_clear(a); mp_clear(prime); @@ -8877,8 +9968,8 @@ int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, WOLFSSL_ENTER("wolfSSL_EC_POINT_invert"); - if (!group || !a || !a->internal || setupPoint(a) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (!group || !a || !a->internal || setupPoint(a) != 1) { + return 0; } p = (ecc_point*)a->internal; @@ -8886,7 +9977,7 @@ int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, #ifdef WOLFSSL_SMALL_STACK prime = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (prime == NULL) { - return WOLFSSL_FAILURE; + return 0; } #endif @@ -8896,7 +9987,7 @@ int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, #ifdef WOLFSSL_SMALL_STACK XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } if (mp_sub(prime, p->y, p->y) != MP_OKAY) { @@ -8904,22 +9995,22 @@ int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, #ifdef WOLFSSL_SMALL_STACK XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } - if (SetECPointExternal(a) != WOLFSSL_SUCCESS) { + if (SetECPointExternal(a) != 1) { WOLFSSL_MSG("SetECPointExternal error"); #ifdef WOLFSSL_SMALL_STACK XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_FAILURE; + return 0; } #ifdef WOLFSSL_SMALL_STACK XFREE(prime, NULL, DYNAMIC_TYPE_BIGINT); #endif - return WOLFSSL_SUCCESS; + return 1; } void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p) @@ -8945,7 +10036,7 @@ int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, if (group == NULL || a == NULL || a->internal == NULL || b == NULL || b->internal == NULL) { WOLFSSL_MSG("wolfSSL_EC_POINT_cmp Bad arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } ret = wc_ecc_cmp_point((ecc_point*)a->internal, (ecc_point*)b->internal); @@ -8954,7 +10045,7 @@ int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, else if (ret == MP_LT || ret == MP_GT) return 1; - return WOLFSSL_FATAL_ERROR; + return -1; } int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src) @@ -8962,25 +10053,25 @@ int wolfSSL_EC_POINT_copy(WOLFSSL_EC_POINT *dest, const WOLFSSL_EC_POINT *src) WOLFSSL_ENTER("wolfSSL_EC_POINT_copy"); if (!dest || !src) { - return WOLFSSL_FAILURE; + return 0; } - if (setupPoint(src) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (setupPoint(src) != 1) { + return 0; } if (wc_ecc_copy_point((ecc_point*) dest->internal, (ecc_point*) src->internal) != MP_OKAY) { - return WOLFSSL_FAILURE; + return 0; } dest->inSet = 1; - if (SetECPointExternal(dest) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (SetECPointExternal(dest) != 1) { + return 0; } - return WOLFSSL_SUCCESS; + return 1; } #endif /* OPENSSL_EXTRA */ @@ -9022,28 +10113,28 @@ int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, if (group == NULL || point == NULL || point->internal == NULL) { WOLFSSL_MSG("wolfSSL_EC_POINT_is_at_infinity NULL error"); - return WOLFSSL_FAILURE; + return 0; } - if (setupPoint(point) != WOLFSSL_SUCCESS) { - return WOLFSSL_FAILURE; + if (setupPoint(point) != 1) { + return 0; } #ifndef WOLF_CRYPTO_CB_ONLY_ECC ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal); if (ret < 0) { WOLFSSL_MSG("ecc_point_is_at_infinity failure"); - return WOLFSSL_FAILURE; + return 0; } #else WOLFSSL_MSG("ecc_point_is_at_infinitiy compiled out"); - return WOLFSSL_FAILURE; + return 0; #endif return ret; } /* End EC_POINT */ -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *r, size_t nitems) { size_t i, min_nitems; @@ -9065,7 +10156,7 @@ size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *r, size_t nitems) return min_nitems; } -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */ /* Start ECDSA_SIG */ void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig) @@ -9130,7 +10221,7 @@ int wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG* sig, WOLFSSL_BIGNUM* r, WOLFSSL_BIGNUM* s) { if (sig == NULL || r == NULL || s == NULL) { - return WOLFSSL_FAILURE; + return 0; } wolfSSL_BN_free(sig->r); @@ -9139,7 +10230,7 @@ int wolfSSL_ECDSA_SIG_set0(WOLFSSL_ECDSA_SIG* sig, WOLFSSL_BIGNUM* r, sig->r = r; sig->s = s; - return WOLFSSL_SUCCESS; + return 1; } /* return signature structure on success, NULL otherwise */ @@ -9150,12 +10241,12 @@ WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen, int initTmpRng = 0; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRng = NULL; byte* out = NULL; mp_int* sig_r = NULL; mp_int* sig_s = NULL; #else - WC_RNG tmpRNG[1]; + WC_RNG tmpRng[1]; byte out[ECC_BUFSIZE]; mp_int sig_r[1], sig_s[1]; #endif @@ -9173,38 +10264,38 @@ WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen, { WOLFSSL_MSG("wolfSSL_ECDSA_do_sign No EC key internal set, do it"); - if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(key) != 1) { WOLFSSL_MSG("wolfSSL_ECDSA_do_sign SetECKeyInternal failed"); return NULL; } } #ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) + tmpRng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRng == NULL) return NULL; out = (byte*)XMALLOC(outlen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) { - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); return NULL; } sig_r = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (sig_r == NULL) { XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); return NULL; } sig_s = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (sig_s == NULL) { XFREE(sig_r, NULL, DYNAMIC_TYPE_BIGINT); XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); return NULL; } #endif - if (wc_InitRng(tmpRNG) == 0) { - rng = tmpRNG; + if (wc_InitRng(tmpRng) == 0) { + rng = tmpRng; initTmpRng = 1; } else { @@ -9224,13 +10315,13 @@ WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen, WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed"); } else if (SetIndividualExternal(&sig->r, sig_r) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecdsa r key error"); wolfSSL_ECDSA_SIG_free(sig); sig = NULL; } else if (SetIndividualExternal(&sig->s, sig_s) - != WOLFSSL_SUCCESS) { + != 1) { WOLFSSL_MSG("ecdsa s key error"); wolfSSL_ECDSA_SIG_free(sig); sig = NULL; @@ -9246,12 +10337,12 @@ WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen, } if (initTmpRng) - wc_FreeRng(tmpRNG); + wc_FreeRng(tmpRng); #ifdef WOLFSSL_SMALL_STACK XFREE(sig_s, NULL, DYNAMIC_TYPE_BIGINT); XFREE(sig_r, NULL, DYNAMIC_TYPE_BIGINT); XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif return sig; @@ -9276,7 +10367,7 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen, if (d == NULL || sig == NULL || key == NULL || key->internal == NULL) { WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* set internal key if not done */ @@ -9284,9 +10375,9 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen, { WOLFSSL_MSG("No EC key internal set, do it"); - if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(key) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } } @@ -9295,11 +10386,11 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen, (mp_int*)sig->s->internal, d, dlen, &check_sign, (ecc_key *)key->internal) != MP_OKAY) { WOLFSSL_MSG("wc_ecc_verify_hash failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } else if (check_sign == 0) { WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected"); - return WOLFSSL_FAILURE; + return 0; } #else /* convert big number to hex */ @@ -9316,7 +10407,7 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen, if (ret != MP_OKAY) { WOLFSSL_MSG("wc_ecc_verify_hash failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* verify hash. expects to call wc_CryptoCb_EccVerify internally */ ret = wc_ecc_verify_hash(signature, signaturelen, d, dlen, &check_sign, @@ -9324,15 +10415,15 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *d, int dlen, if (ret != MP_OKAY) { WOLFSSL_MSG("wc_ecc_verify_hash failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } else if (check_sign == 0) { WOLFSSL_MSG("wc_ecc_verify_hash incorrect signature detected"); - return WOLFSSL_FAILURE; + return 0; } #endif - return WOLFSSL_SUCCESS; + return 1; } WOLFSSL_ECDSA_SIG *wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG **sig, @@ -9414,7 +10505,7 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, ecc_key* key; int ret; #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,0))) + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) int setGlobalRNG = 0; #endif (void)KDF; @@ -9424,7 +10515,7 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, if (out == NULL || pub_key == NULL || pub_key->internal == NULL || ecdh == NULL || ecdh->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } /* set internal key if not done */ @@ -9432,9 +10523,9 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, { WOLFSSL_MSG("No EC key internal set, do it"); - if (SetECKeyInternal(ecdh) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(ecdh) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } } @@ -9442,12 +10533,12 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, key = (ecc_key*)ecdh->internal; #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,0))) + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) if (key->rng == NULL) { if ((key->rng = wolfssl_get_global_rng()) == NULL) { - if (wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) { + if (wolfSSL_RAND_Init() != 1) { WOLFSSL_MSG("No RNG to use"); - return WOLFSSL_FATAL_ERROR; + return -1; } key->rng = wolfssl_get_global_rng(); } @@ -9459,13 +10550,13 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, (byte *)out, &len); PRIVATE_KEY_LOCK(); #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) && \ - (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,0))) + (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,0)) if (setGlobalRNG) key->rng = NULL; #endif if (ret != MP_OKAY) { WOLFSSL_MSG("wc_ecc_shared_secret failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } return len; @@ -9482,31 +10573,31 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen, */ int wolfSSL_PEM_write_EC_PUBKEY(XFILE fp, WOLFSSL_EC_KEY* key) { - int ret = WOLFSSL_SUCCESS; + int ret = 1; WOLFSSL_BIO* bio = NULL; WOLFSSL_ENTER("wolfSSL_PEM_write_EC_PUBKEY"); if (fp == XBADFILE || key == NULL) { WOLFSSL_MSG("Bad argument."); - ret = WOLFSSL_FAILURE; + ret = 0; } - if (ret == WOLFSSL_SUCCESS) { + if (ret == 1) { bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file()); if (bio == NULL) { WOLFSSL_MSG("wolfSSL_BIO_new failed."); - ret = WOLFSSL_FAILURE; + ret = 0; } - else if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) { + else if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != 1) { WOLFSSL_MSG("wolfSSL_BIO_set_fp failed."); - ret = WOLFSSL_FAILURE; + ret = 0; } } - if (ret == WOLFSSL_SUCCESS && wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key) - != WOLFSSL_SUCCESS) { + if (ret == 1 && wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key) + != 1) { WOLFSSL_MSG("wolfSSL_PEM_write_bio_EC_PUBKEY failed."); - ret = WOLFSSL_FAILURE; + ret = 0; } if (bio != NULL) { @@ -9560,7 +10651,7 @@ WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_EC_PUBKEY(WOLFSSL_BIO* bio, } /* Reads a private EC key from a WOLFSSL_BIO into a WOLFSSL_EC_KEY. - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE + * Returns 1 or 0 */ WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY** ec, @@ -9595,7 +10686,7 @@ WOLFSSL_EC_KEY* wolfSSL_PEM_read_bio_ECPrivateKey(WOLFSSL_BIO* bio, #if defined(WOLFSSL_KEY_GEN) #ifndef NO_BIO /* Takes a public WOLFSSL_EC_KEY and writes it out to WOLFSSL_BIO - * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE + * Returns 1 or 0 */ int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec) { @@ -9606,14 +10697,14 @@ int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec) if (bio == NULL || ec == NULL) { WOLFSSL_MSG("Bad Function Arguments"); - return WOLFSSL_FAILURE; + return 0; } /* Initialize pkey structure */ pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); if (pkey == NULL) { WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); - return WOLFSSL_FAILURE; + return 0; } /* Set pkey info */ @@ -9621,7 +10712,7 @@ int wolfSSL_PEM_write_bio_EC_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec) pkey->ownEcc = 0; /* pkey does not own ECC */ pkey->type = EVP_PKEY_EC; - if ((ret = WriteBioPUBKEY(bio, pkey)) != WOLFSSL_SUCCESS) { + if ((ret = pem_write_bio_pubkey(bio, pkey)) != 1) { WOLFSSL_MSG("wolfSSL_PEM_write_bio_PUBKEY failed"); } wolfSSL_EVP_PKEY_free(pkey); @@ -9644,14 +10735,14 @@ int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, if (bio == NULL || ec == NULL) { WOLFSSL_MSG("Bad Function Arguments"); - return WOLFSSL_FAILURE; + return 0; } /* Initialize pkey structure */ pkey = wolfSSL_EVP_PKEY_new_ex(bio->heap); if (pkey == NULL) { WOLFSSL_MSG("wolfSSL_EVP_PKEY_new_ex failed"); - return WOLFSSL_FAILURE; + return 0; } /* Set pkey info */ @@ -9667,7 +10758,7 @@ int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, if (derBuf == NULL) { WOLFSSL_MSG("Malloc failed"); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return 0; } /* convert key to der format */ @@ -9676,7 +10767,7 @@ int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, WOLFSSL_MSG("wc_EccKeyToDer failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return 0; } pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -9684,7 +10775,7 @@ int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, WOLFSSL_MSG("key malloc failed"); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return 0; } /* add der info to the evp key */ @@ -9719,18 +10810,18 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey"); if (pem == NULL || plen == NULL || ecc == NULL || ecc->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } if (wc_PemGetHeaderFooter(type, &header, &footer) != 0) - return WOLFSSL_FAILURE; + return 0; if (ecc->inSet == 0) { WOLFSSL_MSG("No ECC internal set, do it"); - if (SetECKeyInternal(ecc) != WOLFSSL_SUCCESS) { + if (SetECKeyInternal(ecc) != 1) { WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FAILURE; + return 0; } } @@ -9740,7 +10831,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER); if (derBuf == NULL) { WOLFSSL_MSG("malloc failed"); - return WOLFSSL_FAILURE; + return 0; } /* Key to DER */ @@ -9748,7 +10839,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, if (derSz < 0) { WOLFSSL_MSG("wc_EccKeyToDer failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); - return WOLFSSL_FAILURE; + return 0; } /* encrypt DER buffer if required */ @@ -9757,7 +10848,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, ret = EncryptDerKey(derBuf, &derSz, cipher, passwd, passwdSz, &cipherInfo, der_max_len); - if (ret != WOLFSSL_SUCCESS) { + if (ret != 1) { WOLFSSL_MSG("EncryptDerKey failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); return ret; @@ -9778,7 +10869,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); if (cipherInfo != NULL) XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - return WOLFSSL_FAILURE; + return 0; } /* DER to PEM */ @@ -9789,7 +10880,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); if (cipherInfo != NULL) XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING); - return WOLFSSL_FAILURE; + return 0; } XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); if (cipherInfo != NULL) @@ -9799,7 +10890,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, if (*pem == NULL) { WOLFSSL_MSG("malloc failed"); XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_FAILURE; + return 0; } XMEMSET(*pem, 0, (*plen)+1); @@ -9807,11 +10898,11 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, WOLFSSL_MSG("XMEMCPY failed"); XFREE(pem, NULL, DYNAMIC_TYPE_KEY); XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_FAILURE; + return 0; } XFREE(tmp, NULL, DYNAMIC_TYPE_PEM); - return WOLFSSL_SUCCESS; + return 1; #else (void)ecc; (void)cipher; @@ -9819,7 +10910,7 @@ int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* ecc, (void)passwdSz; (void)pem; (void)plen; - return WOLFSSL_FAILURE; + return 0; #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */ } @@ -9842,23 +10933,23 @@ int wolfSSL_PEM_write_ECPrivateKey(XFILE fp, WOLFSSL_EC_KEY *ecc, if (fp == XBADFILE || ecc == NULL || ecc->internal == NULL) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FAILURE; + return 0; } ret = wolfSSL_PEM_write_mem_ECPrivateKey(ecc, enc, kstr, klen, &pem, &plen); - if (ret != WOLFSSL_SUCCESS) { + if (ret != 1) { WOLFSSL_MSG("wolfSSL_PEM_write_mem_ECPrivateKey failed"); - return WOLFSSL_FAILURE; + return 0; } ret = (int)XFWRITE(pem, plen, 1, fp); if (ret != 1) { WOLFSSL_MSG("ECC private key file write failed"); - return WOLFSSL_FAILURE; + return 0; } XFREE(pem, NULL, DYNAMIC_TYPE_KEY); - return WOLFSSL_SUCCESS; + return 1; } #endif /* NO_FILESYSTEM */ @@ -9894,7 +10985,7 @@ WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio, #endif /* !NO_BIO */ -/* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ +/* return 1 if success, -1 if error */ int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, int derSz) { @@ -9913,7 +11004,7 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, if (key == NULL || key->internal == NULL || derBuf == NULL || derSz <= 0) { WOLFSSL_MSG("Bad function arguments"); - return WOLFSSL_FATAL_ERROR; + return -1; } key->pkcs8HeaderSz = 0; @@ -9928,7 +11019,7 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, else { if (ret != ASN_PARSE_E) { WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header"); - return WOLFSSL_FATAL_ERROR; + return -1; } } @@ -9947,17 +11038,17 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, else { WOLFSSL_MSG("wc_EccPublicKeyDecode failed"); } - return WOLFSSL_FATAL_ERROR; + return -1; } - if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) { + if (SetECKeyExternal(key) != 1) { WOLFSSL_MSG("SetECKeyExternal failed"); - return WOLFSSL_FATAL_ERROR; + return -1; } key->inSet = 1; - return WOLFSSL_SUCCESS; + return 1; } #endif /* OPENSSL_EXTRA */ diff --git a/src/ssl.c b/src/ssl.c index a8d61789f..7a0e15d32 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -26916,7 +26916,7 @@ int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, #endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */ #ifndef NO_BIO -static int WriteBioPUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key) +static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key) { int ret; int pemSz; @@ -27005,14 +27005,14 @@ static int WriteBioPUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key) pemSz = wc_DerToPem(derBuf, derSz, NULL, 0, PUBLICKEY_TYPE); if (pemSz < 0) { - WOLFSSL_LEAVE("WriteBioPUBKEY", pemSz); + WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER); return WOLFSSL_FAILURE; } pemBuf = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); if (pemBuf == NULL) { - WOLFSSL_LEAVE("WriteBioPUBKEY", pemSz); + WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER); return WOLFSSL_FAILURE; } @@ -27020,7 +27020,7 @@ static int WriteBioPUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key) ret = wc_DerToPem(derBuf, derSz, pemBuf, pemSz, PUBLICKEY_TYPE); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER); if (ret < 0) { - WOLFSSL_LEAVE("WriteBioPUBKEY", ret); + WOLFSSL_LEAVE("pem_write_bio_pubkey", ret); XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FAILURE; } @@ -27042,7 +27042,7 @@ int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key) { WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY"); - return WriteBioPUBKEY(bio, key); + return pem_write_bio_pubkey(bio, key); } /* Takes a private key and writes it out to a WOLFSSL_BIO @@ -33606,6 +33606,22 @@ word32 nid2oid(int nid, int grp) case NID_sha512: return SHA512h; #endif + #ifndef WOLFSSL_NOSHA3_224 + case NID_sha3_224: + return SHA3_224h; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case NID_sha3_256: + return SHA3_256h; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case NID_sha3_384: + return SHA3_384h; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case NID_sha3_512: + return SHA3_512h; + #endif } break; diff --git a/tests/api.c b/tests/api.c index 79b98d659..9df1d0e03 100644 --- a/tests/api.c +++ b/tests/api.c @@ -337,7 +337,8 @@ #if (defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)) || \ defined(HAVE_SESSION_TICKET) || (defined(OPENSSL_EXTRA) && \ - defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) + defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \ + defined(WOLFSSL_TEST_STATIC_BUILD) /* for testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT, * or for setting authKeyIdSrc in WOLFSSL_X509 */ #include "wolfssl/internal.h" @@ -2397,7 +2398,7 @@ static void test_wolfSSL_CTX_load_verify_chain_buffer_format(void) static void test_wolfSSL_CTX_add1_chain_cert(void) { #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \ - defined(KEEP_OUR_CERT) + defined(KEEP_OUR_CERT) && !defined(NO_RSA) WOLFSSL_CTX* ctx; WOLFSSL* ssl; const char *certChain[] = { @@ -29820,7 +29821,7 @@ static void test_wolfSSL_X509_NAME_print_ex(void) (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \ defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \ defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))) && \ - !defined(NO_BIO) + !defined(NO_BIO) && !defined(NO_RSA) int memSz; byte* mem = NULL; BIO* bio = NULL; @@ -31742,7 +31743,8 @@ static void test_wolfSSL_PEM_bio_RSAKey(void) /* PrivateKey */ AssertNotNull(bio = BIO_new_file(svrKeyFile, "rb")); AssertNull((rsa = PEM_read_bio_RSAPrivateKey(NULL, NULL, NULL, NULL))); - AssertNotNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL))); + AssertNotNull(PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL)); + AssertNotNull(rsa); AssertIntEQ(RSA_size(rsa), 256); AssertIntEQ(PEM_write_bio_RSAPrivateKey(NULL, NULL, NULL, NULL, 0, NULL, \ NULL), WOLFSSL_FAILURE); @@ -31807,6 +31809,11 @@ static void test_wolfSSL_PEM_RSAPrivateKey(void) AssertIntEQ(RSA_size(rsa), 256); #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) + AssertNull(rsa_dup = RSAPublicKey_dup(NULL)); + /* Test duplicating empty key. */ + rsa_dup = RSA_new(); + AssertNull(RSAPublicKey_dup(rsa_dup)); + RSA_free(rsa_dup); AssertNotNull(rsa_dup = RSAPublicKey_dup(rsa)); AssertPtrNE(rsa_dup, rsa); #endif @@ -34740,7 +34747,8 @@ static void test_wolfSSL_X509_STORE_load_locations(void) static void test_X509_STORE_get0_objects(void) { -#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && \ + !defined(NO_WOLFSSL_DIR) && !defined(NO_RSA) X509_STORE *store; X509_STORE *store_cpy; SSL_CTX *ctx; @@ -40390,7 +40398,8 @@ static void test_wolfSSL_d2i_PrivateKeys_bio(void) /* set RSA using bio*/ AssertIntGT(BIO_write(bio, client_key_der_2048, sizeof_client_key_der_2048), 0); - AssertNotNull(rsa = d2i_RSAPrivateKey_bio(bio, NULL)); + AssertNotNull(d2i_RSAPrivateKey_bio(bio, &rsa)); + AssertNotNull(rsa); AssertIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WOLFSSL_SUCCESS); @@ -40404,6 +40413,10 @@ static void test_wolfSSL_d2i_PrivateKeys_bio(void) sizeof_client_key_der_2048); AssertNotNull(bufPtr); XFREE(bufPtr, NULL, DYNAMIC_TYPE_OPENSSL); + + RSA_free(rsa); + rsa = RSA_new(); + AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 0); #endif /* USE_CERT_BUFFERS_2048 WOLFSSL_KEY_GEN */ RSA_free(rsa); } @@ -40469,7 +40482,7 @@ static void test_wolfSSL_sk_GENERAL_NAME(void) static void test_wolfSSL_GENERAL_NAME_print(void) { -#if defined(OPENSSL_ALL) && !defined(NO_BIO) +#if defined(OPENSSL_ALL) && !defined(NO_BIO) && !defined(NO_RSA) X509* x509; GENERAL_NAME* gn; @@ -40727,288 +40740,6 @@ static void test_wolfSSL_MD4(void) } -static void test_wolfSSL_RSA(void) -{ -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \ - defined(WOLFSSL_KEY_GEN) - RSA* rsa; - const BIGNUM *n; - const BIGNUM *e; - const BIGNUM *d; - const BIGNUM *p; - const BIGNUM *q; - const BIGNUM *dmp1; - const BIGNUM *dmq1; - const BIGNUM *iqmp; - - printf(testingFmt, "wolfSSL_RSA()"); - - AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); - AssertIntEQ(RSA_size(rsa), 256); - -#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \ - (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION >= 2))) && !defined(HAVE_SELFTEST) && \ - !defined(HAVE_INTEL_QA) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) - AssertIntEQ(RSA_check_key(rsa), WOLFSSL_SUCCESS); -#endif - - /* sanity check */ - AssertIntEQ(RSA_bits(NULL), 0); - - /* key */ - AssertIntEQ(RSA_bits(rsa), 2048); - RSA_get0_key(rsa, &n, &e, &d); - AssertPtrEq(rsa->n, n); - AssertPtrEq(rsa->e, e); - AssertPtrEq(rsa->d, d); - AssertNotNull(n = BN_new()); - AssertNotNull(e = BN_new()); - AssertNotNull(d = BN_new()); - AssertIntEQ(RSA_set0_key(rsa, (BIGNUM*)n, (BIGNUM*)e, (BIGNUM*)d), 1); - AssertPtrEq(rsa->n, n); - AssertPtrEq(rsa->e, e); - AssertPtrEq(rsa->d, d); - - /* crt_params */ - RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - AssertPtrEq(rsa->dmp1, dmp1); - AssertPtrEq(rsa->dmq1, dmq1); - AssertPtrEq(rsa->iqmp, iqmp); - AssertNotNull(dmp1 = BN_new()); - AssertNotNull(dmq1 = BN_new()); - AssertNotNull(iqmp = BN_new()); - AssertIntEQ(RSA_set0_crt_params(rsa, (BIGNUM*)dmp1, (BIGNUM*)dmq1, (BIGNUM*)iqmp), 1); - AssertPtrEq(rsa->dmp1, dmp1); - AssertPtrEq(rsa->dmq1, dmq1); - AssertPtrEq(rsa->iqmp, iqmp); - - /* factors */ - RSA_get0_factors(rsa, &p, &q); - AssertPtrEq(rsa->p, p); - AssertPtrEq(rsa->q, q); - AssertNotNull(p = BN_new()); - AssertNotNull(q = BN_new()); - AssertIntEQ(RSA_set0_factors(rsa, (BIGNUM*)p, (BIGNUM*)q), 1); - AssertPtrEq(rsa->p, p); - AssertPtrEq(rsa->q, q); - - AssertIntEQ(BN_hex2bn(&rsa->n, "1FFFFF"), 1); - AssertIntEQ(RSA_bits(rsa), 21); - RSA_free(rsa); - -#if !defined(USE_FAST_MATH) || (FP_MAX_BITS >= (3072*2)) - AssertNotNull(rsa = RSA_generate_key(3072, 17, NULL, NULL)); - AssertIntEQ(RSA_size(rsa), 384); - AssertIntEQ(RSA_bits(rsa), 3072); - RSA_free(rsa); -#endif - - /* remove for now with odd key size until adjusting rsa key size check with - wc_MakeRsaKey() - AssertNotNull(rsa = RSA_generate_key(2999, 65537, NULL, NULL)); - RSA_free(rsa); - */ - - AssertNull(RSA_generate_key(-1, 3, NULL, NULL)); - AssertNull(RSA_generate_key(RSA_MIN_SIZE - 1, 3, NULL, NULL)); - AssertNull(RSA_generate_key(RSA_MAX_SIZE + 1, 3, NULL, NULL)); - AssertNull(RSA_generate_key(2048, 0, NULL, NULL)); - - -#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) - { - byte buff[FOURK_BUF]; - byte der[FOURK_BUF]; - const char PrivKeyPemFile[] = "certs/client-keyEnc.pem"; - - XFILE f; - int bytes; - - /* test loading encrypted RSA private pem w/o password */ - f = XFOPEN(PrivKeyPemFile, "rb"); - AssertTrue((f != XBADFILE)); - bytes = (int)XFREAD(buff, 1, sizeof(buff), f); - XFCLOSE(f); - XMEMSET(der, 0, sizeof(der)); - /* test that error value is returned with no password */ - AssertIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der), ""), 0); - } -#endif - - printf(resultFmt, passed); -#endif -} - -static void test_wolfSSL_RSA_DER(void) -{ -#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ - !defined(NO_RSA) && !defined(HAVE_USER_RSA) && defined(OPENSSL_EXTRA) - - RSA *rsa; - int i; - unsigned char *buff = NULL; - - struct tbl_s - { - const unsigned char *der; - int sz; - } tbl[] = { - -#ifdef USE_CERT_BUFFERS_1024 - {client_key_der_1024, sizeof_client_key_der_1024}, - {server_key_der_1024, sizeof_server_key_der_1024}, -#endif -#ifdef USE_CERT_BUFFERS_2048 - {client_key_der_2048, sizeof_client_key_der_2048}, - {server_key_der_2048, sizeof_server_key_der_2048}, -#endif - {NULL, 0} - }; - - /* Public Key DER */ - struct tbl_s pub[] = { -#ifdef USE_CERT_BUFFERS_1024 - {client_keypub_der_1024, sizeof_client_keypub_der_1024}, -#endif -#ifdef USE_CERT_BUFFERS_2048 - {client_keypub_der_2048, sizeof_client_keypub_der_2048}, -#endif - {NULL, 0} - }; - - printf(testingFmt, "test_wolfSSL_RSA_DER()"); - - for (i = 0; tbl[i].der != NULL; i++) - { - AssertNotNull(d2i_RSAPublicKey(&rsa, &tbl[i].der, tbl[i].sz)); - AssertNotNull(rsa); - RSA_free(rsa); - } - for (i = 0; tbl[i].der != NULL; i++) - { - AssertNotNull(d2i_RSAPrivateKey(&rsa, &tbl[i].der, tbl[i].sz)); - AssertNotNull(rsa); - RSA_free(rsa); - } - - for (i = 0; pub[i].der != NULL; i++) - { - AssertNotNull(d2i_RSAPublicKey(&rsa, &pub[i].der, pub[i].sz)); - AssertNotNull(rsa); - AssertIntEQ(i2d_RSAPublicKey(rsa, NULL), pub[i].sz); - buff = NULL; - AssertIntEQ(i2d_RSAPublicKey(rsa, &buff), pub[i].sz); - AssertNotNull(buff); - AssertIntEQ(0, memcmp((void *)buff, (void *)pub[i].der, pub[i].sz)); - XFREE((void *)buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); - RSA_free(rsa); - } - - printf(resultFmt, passed); - -#endif -} - -static void test_wolfSSL_RSA_get0_key(void) -{ -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) - RSA *rsa = NULL; - const BIGNUM* n = NULL; - const BIGNUM* e = NULL; - const BIGNUM* d = NULL; - - const unsigned char* der; - int derSz; - -#ifdef USE_CERT_BUFFERS_1024 - der = client_key_der_1024; - derSz = sizeof_client_key_der_1024; -#elif defined(USE_CERT_BUFFERS_2048) - der = client_key_der_2048; - derSz = sizeof_client_key_der_2048; -#else - der = NULL; - derSz = 0; -#endif - - printf(testingFmt, "test_wolfSSL_RSA_get0_key()"); - - if (der != NULL) { - RSA_get0_key(NULL, NULL, NULL, NULL); - RSA_get0_key(rsa, NULL, NULL, NULL); - RSA_get0_key(NULL, &n, &e, &d); - AssertNull(n); - AssertNull(e); - AssertNull(d); - - AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, derSz)); - AssertNotNull(rsa); - - RSA_get0_key(rsa, NULL, NULL, NULL); - RSA_get0_key(rsa, &n, NULL, NULL); - AssertNotNull(n); - RSA_get0_key(rsa, NULL, &e, NULL); - AssertNotNull(e); - RSA_get0_key(rsa, NULL, NULL, &d); - AssertNotNull(d); - RSA_get0_key(rsa, &n, &e, &d); - AssertNotNull(n); - AssertNotNull(e); - AssertNotNull(d); - - RSA_free(rsa); - } - printf(resultFmt, passed); -#endif -} - -static void test_wolfSSL_RSA_meth(void) -{ -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) - RSA *rsa; - RSA_METHOD *rsa_meth; - - printf(testingFmt, "test_wolfSSL_RSA_meth"); - -#ifdef WOLFSSL_KEY_GEN - AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); - RSA_free(rsa); -#else - AssertNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); -#endif - - AssertNotNull(rsa_meth = - RSA_meth_new("placeholder RSA method", RSA_METHOD_FLAG_NO_CHECK)); - -#ifndef NO_WOLFSSL_STUB - AssertIntEQ(RSA_meth_set_pub_enc(rsa_meth, NULL), 1); - AssertIntEQ(RSA_meth_set_pub_dec(rsa_meth, NULL), 1); - AssertIntEQ(RSA_meth_set_priv_enc(rsa_meth, NULL), 1); - AssertIntEQ(RSA_meth_set_priv_dec(rsa_meth, NULL), 1); - AssertIntEQ(RSA_meth_set_init(rsa_meth, NULL), 1); - AssertIntEQ(RSA_meth_set_finish(rsa_meth, NULL), 1); - AssertIntEQ(RSA_meth_set0_app_data(rsa_meth, NULL), 1); -#endif - - AssertNotNull(rsa = RSA_new()); - AssertIntEQ(RSA_set_method(rsa, rsa_meth), 1); - AssertPtrEq(RSA_get_method(rsa), rsa_meth); - AssertIntEQ(RSA_flags(rsa), RSA_METHOD_FLAG_NO_CHECK); - RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC); - AssertIntNE(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); - AssertIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC | RSA_METHOD_FLAG_NO_CHECK); - RSA_clear_flags(rsa, RSA_FLAG_CACHE_PUBLIC); - AssertIntEQ(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); - AssertIntNE(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC); - - /* rsa_meth is freed here */ - RSA_free(rsa); - - printf(resultFmt, passed); -#endif -} - static void test_wolfSSL_verify_mode(void) { #if defined(OPENSSL_ALL) && !defined(NO_RSA) @@ -44259,14 +43990,16 @@ static void test_wolfSSL_EVP_PKEY_paramgen(void) AssertIntEQ(EVP_PKEY_paramgen(NULL, &pkey), WOLFSSL_FAILURE); AssertNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)); AssertIntEQ(EVP_PKEY_paramgen(ctx, NULL), WOLFSSL_FAILURE); - EVP_PKEY_CTX_free(ctx); + #ifndef NO_RSA + EVP_PKEY_CTX_free(ctx); /* Parameter generation for RSA not supported yet. */ AssertNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)); AssertIntEQ(EVP_PKEY_paramgen(ctx, &pkey), WOLFSSL_FAILURE); - EVP_PKEY_CTX_free(ctx); #endif +#ifdef HAVE_ECC + EVP_PKEY_CTX_free(ctx); AssertNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)); AssertIntEQ(EVP_PKEY_paramgen_init(ctx), WOLFSSL_SUCCESS); AssertIntEQ(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, @@ -44276,6 +44009,7 @@ static void test_wolfSSL_EVP_PKEY_paramgen(void) WOLFSSL_SUCCESS); AssertIntEQ(EVP_PKEY_keygen_init(ctx), WOLFSSL_SUCCESS); AssertIntEQ(EVP_PKEY_keygen(ctx, &pkey), WOLFSSL_SUCCESS); +#endif EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); @@ -45964,7 +45698,7 @@ static void test_wolfSSL_X509V3_EXT(void) { static void test_wolfSSL_X509_get_extension_flags(void) { -#ifdef OPENSSL_ALL +#if defined(OPENSSL_ALL) && !defined(NO_RSA) XFILE f; X509* x509; unsigned int extFlags; @@ -46843,59 +46577,6 @@ static void test_wolfSSL_EVP_PBE_scrypt(void) #endif /* OPENSSL_EXTRA && HAVE_SCRYPT && HAVE_PBKDF2 */ } -#ifndef NO_RSA -static void test_wolfSSL_RSA_padding_add_PKCS1_PSS(void) -{ -#if defined(OPENSSL_ALL) && defined(WC_RSA_PSS) && !defined(WC_NO_RNG) -#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) - RSA *rsa; - const unsigned char *derBuf = client_key_der_2048; - unsigned char em[256] = {0}; /* len = 2048/8 */ - /* Random data simulating a hash */ - const unsigned char mHash[WC_SHA256_DIGEST_SIZE] = { - 0x28, 0x6e, 0xfd, 0xf8, 0x76, 0xc7, 0x00, 0x3d, 0x91, 0x4e, 0x59, 0xe4, - 0x8e, 0xb7, 0x40, 0x7b, 0xd1, 0x0c, 0x98, 0x4b, 0xe3, 0x3d, 0xb3, 0xeb, - 0x6f, 0x8a, 0x3c, 0x42, 0xab, 0x21, 0xad, 0x28 - }; - - AssertNotNull(d2i_RSAPrivateKey(&rsa, &derBuf, sizeof_client_key_der_2048)); - AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), -1), 1); - AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, -1), 1); - - RSA_free(rsa); -#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ -#endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/ -} -#endif - -static void test_wolfSSL_RSA_sign_sha3(void) -{ -#if !defined(NO_RSA) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256) -#if defined(OPENSSL_ALL) && defined(WC_RSA_PSS) && !defined(WC_NO_RNG) - RSA *rsa; - const unsigned char *derBuf = client_key_der_2048; - unsigned char sigRet[256] = {0}; - unsigned int sigLen = sizeof(sigRet); - /* Random data simulating a hash */ - const unsigned char mHash[WC_SHA3_256_DIGEST_SIZE] = { - 0x28, 0x6e, 0xfd, 0xf8, 0x76, 0xc7, 0x00, 0x3d, 0x91, 0x4e, 0x59, 0xe4, - 0x8e, 0xb7, 0x40, 0x7b, 0xd1, 0x0c, 0x98, 0x4b, 0xe3, 0x3d, 0xb3, 0xeb, - 0x6f, 0x8a, 0x3c, 0x42, 0xab, 0x21, 0xad, 0x28 - }; - - printf(testingFmt, "wolfSSL_RSA_sign_sha3"); - - AssertNotNull(d2i_RSAPrivateKey(&rsa, &derBuf, sizeof_client_key_der_2048)); - AssertIntEQ(RSA_sign(NID_sha3_256, mHash, sizeof(mHash), sigRet, - &sigLen, rsa), 1); - - RSA_free(rsa); - - printf(resultFmt, passed); -#endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/ -#endif /* !NO_RSA && WOLFSSL_SHA3 && !WOLFSSL_NOSHA3_256*/ -} - static void test_wolfSSL_EC_get_builtin_curves(void) { #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) @@ -47482,7 +47163,7 @@ static void test_wolfSSL_EVP_PKEY_encrypt(void) byte* outDec = NULL; size_t outDecLen = 0; size_t rsaKeySz = 2048/8; /* Bytes */ -#ifdef WC_RSA_NO_PADDING +#if !defined(HAVE_FIPS) && defined(WC_RSA_NO_PADDING) byte* inTmp = NULL; byte* outEncTmp = NULL; byte* outDecTmp = NULL; @@ -47531,7 +47212,7 @@ static void test_wolfSSL_EVP_PKEY_encrypt(void) AssertIntEQ(XMEMCMP(in, outDec, outDecLen), 0); -#ifdef WC_RSA_NO_PADDING +#if !defined(HAVE_FIPS) && defined(WC_RSA_NO_PADDING) /* The input length must be the same size as the RSA key.*/ AssertNotNull(inTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); XMEMSET(inTmp, 9, rsaKeySz); @@ -47552,7 +47233,7 @@ static void test_wolfSSL_EVP_PKEY_encrypt(void) EVP_PKEY_CTX_free(ctx); XFREE(outEnc, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(outDec, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); -#ifdef WC_RSA_NO_PADDING +#if !defined(HAVE_FIPS) && defined(WC_RSA_NO_PADDING) XFREE(inTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(outEncTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(outDecTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -47572,6 +47253,7 @@ static void test_wolfSSL_EVP_PKEY_sign_verify(void) const char* in = "What is easy to do is easy not to do."; size_t inlen = XSTRLEN(in); byte hash[SHA256_DIGEST_LENGTH] = {0}; + byte zero[SHA256_DIGEST_LENGTH] = {0}; SHA256_CTX c; byte* sig = NULL; byte* sigVerify = NULL; @@ -47692,11 +47374,48 @@ static void test_wolfSSL_EVP_PKEY_sign_verify(void) AssertIntEQ(EVP_PKEY_verify( ctx_verify, sig, siglen, hash, SHA256_DIGEST_LENGTH), WOLFSSL_SUCCESS); - XMEMSET(hash, 0, SHA256_DIGEST_LENGTH); AssertIntEQ(EVP_PKEY_verify( - ctx_verify, sig, siglen, hash, SHA256_DIGEST_LENGTH), + ctx_verify, sig, siglen, zero, SHA256_DIGEST_LENGTH), WOLFSSL_FAILURE); - EVP_PKEY_CTX_free(ctx_verify); + +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(HAVE_FAST_RSA) && !defined(HAVE_SELFTEST) +#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) + if (encs[i] == EVP_PKEY_RSA) { + #if defined(WC_RSA_NO_PADDING) || defined(WC_RSA_DIRECT) + /* Try RSA sign/verify with no padding. */ + AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_sign(ctx, sigVerify, &siglen, sig, + siglen), WOLFSSL_SUCCESS); + AssertIntGE(siglenOnlyLen, siglen); + AssertIntEQ(EVP_PKEY_verify_init(ctx_verify), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx_verify, + RSA_NO_PADDING), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_verify(ctx_verify, sigVerify, siglen, sig, + siglen), WOLFSSL_SUCCESS); + #endif + + /* Wrong padding schemes. */ + AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, + RSA_PKCS1_OAEP_PADDING), WOLFSSL_SUCCESS); + AssertIntNE(EVP_PKEY_sign(ctx, sigVerify, &siglen, sig, + siglen), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_verify_init(ctx_verify), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx_verify, + RSA_PKCS1_OAEP_PADDING), WOLFSSL_SUCCESS); + AssertIntNE(EVP_PKEY_verify(ctx_verify, sigVerify, siglen, sig, + siglen), WOLFSSL_SUCCESS); + + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx_verify, + RSA_PKCS1_PADDING), WOLFSSL_SUCCESS); + } +#endif +#endif /* error cases */ siglen = keySz; /* Reset because sig size may vary slightly */ @@ -47712,6 +47431,7 @@ static void test_wolfSSL_EVP_PKEY_sign_verify(void) DSA_free(dsa); dsa = NULL; #endif /* !NO_DSA && !HAVE_SELFTEST && WOLFSSL_KEY_GEN */ + EVP_PKEY_CTX_free(ctx_verify); EVP_PKEY_CTX_free(ctx); } @@ -51492,25 +51212,6 @@ static void test_wolfSSL_X509_print(void) #endif } -static void test_wolfSSL_RSA_print(void) -{ -#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ - !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ - !defined(HAVE_FAST_RSA) && !defined(NO_BIO) - BIO *bio; - WOLFSSL_RSA* rsa = NULL; - printf(testingFmt, "wolfSSL_RSA_print"); - - AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); - AssertNotNull(bio = BIO_new_fd(STDOUT_FILENO, BIO_NOCLOSE)); - AssertIntEQ(RSA_print(bio, rsa, 0), SSL_SUCCESS); - - BIO_free(bio); - RSA_free(rsa); - printf(resultFmt, passed); -#endif -} - static void test_wolfSSL_BIO_get_len(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) @@ -51650,10 +51351,492 @@ static void test_wolfSSL_ASN1_get_object(void) #endif /* OPENSSL_EXTRA && HAVE_ECC && USE_CERT_BUFFERS_256 */ } +static void test_wolfSSL_RSA(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \ + defined(WOLFSSL_KEY_GEN) + RSA* rsa; + const BIGNUM *n; + const BIGNUM *e; + const BIGNUM *d; + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *dmp1; + const BIGNUM *dmq1; + const BIGNUM *iqmp; + + printf(testingFmt, "wolfSSL_RSA()"); + + AssertNotNull(rsa = RSA_new()); + AssertIntEQ(RSA_size(NULL), 0); + AssertIntEQ(RSA_size(rsa), 0); + AssertIntEQ(RSA_set0_key(rsa, NULL, NULL, NULL), 0); + AssertIntEQ(RSA_set0_crt_params(rsa, NULL, NULL, NULL), 0); + AssertIntEQ(RSA_set0_factors(rsa, NULL, NULL), 0); +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \ + (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION >= 2))) && !defined(HAVE_SELFTEST) && \ + !defined(HAVE_INTEL_QA) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) + AssertIntEQ(RSA_check_key(rsa), 0); +#endif + + RSA_free(rsa); + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + AssertIntEQ(RSA_size(rsa), 256); + +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(HAVE_FAST_RSA) && \ + (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION >= 2))) && !defined(HAVE_SELFTEST) && \ + !defined(HAVE_INTEL_QA) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) + AssertIntEQ(RSA_check_key(NULL), 0); + AssertIntEQ(RSA_check_key(rsa), 1); +#endif + + /* sanity check */ + AssertIntEQ(RSA_bits(NULL), 0); + + /* key */ + AssertIntEQ(RSA_bits(rsa), 2048); + RSA_get0_key(rsa, &n, &e, &d); + AssertPtrEq(rsa->n, n); + AssertPtrEq(rsa->e, e); + AssertPtrEq(rsa->d, d); + AssertNotNull(n = BN_new()); + AssertNotNull(e = BN_new()); + AssertNotNull(d = BN_new()); + AssertIntEQ(RSA_set0_key(rsa, (BIGNUM*)n, (BIGNUM*)e, (BIGNUM*)d), 1); + AssertPtrEq(rsa->n, n); + AssertPtrEq(rsa->e, e); + AssertPtrEq(rsa->d, d); + AssertIntEQ(RSA_set0_key(rsa, NULL, NULL, NULL), 1); + AssertIntEQ(RSA_set0_key(NULL, (BIGNUM*)n, (BIGNUM*)e, (BIGNUM*)d), 0); + + /* crt_params */ + RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); + AssertPtrEq(rsa->dmp1, dmp1); + AssertPtrEq(rsa->dmq1, dmq1); + AssertPtrEq(rsa->iqmp, iqmp); + AssertNotNull(dmp1 = BN_new()); + AssertNotNull(dmq1 = BN_new()); + AssertNotNull(iqmp = BN_new()); + AssertIntEQ(RSA_set0_crt_params(rsa, (BIGNUM*)dmp1, (BIGNUM*)dmq1, + (BIGNUM*)iqmp), 1); + AssertPtrEq(rsa->dmp1, dmp1); + AssertPtrEq(rsa->dmq1, dmq1); + AssertPtrEq(rsa->iqmp, iqmp); + AssertIntEQ(RSA_set0_crt_params(rsa, NULL, NULL, NULL), 1); + AssertIntEQ(RSA_set0_crt_params(NULL, (BIGNUM*)dmp1, (BIGNUM*)dmq1, + (BIGNUM*)iqmp), 0); + RSA_get0_crt_params(NULL, NULL, NULL, NULL); + RSA_get0_crt_params(rsa, NULL, NULL, NULL); + RSA_get0_crt_params(NULL, &dmp1, &dmq1, &iqmp); + AssertNull(dmp1); + AssertNull(dmq1); + AssertNull(iqmp); + + /* factors */ + RSA_get0_factors(rsa, NULL, NULL); + RSA_get0_factors(rsa, &p, &q); + AssertPtrEq(rsa->p, p); + AssertPtrEq(rsa->q, q); + AssertNotNull(p = BN_new()); + AssertNotNull(q = BN_new()); + AssertIntEQ(RSA_set0_factors(rsa, (BIGNUM*)p, (BIGNUM*)q), 1); + AssertPtrEq(rsa->p, p); + AssertPtrEq(rsa->q, q); + AssertIntEQ(RSA_set0_factors(rsa, NULL, NULL), 1); + AssertIntEQ(RSA_set0_factors(NULL, (BIGNUM*)p, (BIGNUM*)q), 0); + RSA_get0_factors(NULL, NULL, NULL); + RSA_get0_factors(NULL, &p, &q); + AssertNull(p); + AssertNull(q); + + AssertIntEQ(BN_hex2bn(&rsa->n, "1FFFFF"), 1); + AssertIntEQ(RSA_bits(rsa), 21); + RSA_free(rsa); + +#if !defined(USE_FAST_MATH) || (FP_MAX_BITS >= (3072*2)) + AssertNotNull(rsa = RSA_generate_key(3072, 17, NULL, NULL)); + AssertIntEQ(RSA_size(rsa), 384); + AssertIntEQ(RSA_bits(rsa), 3072); + RSA_free(rsa); +#endif + + /* remove for now with odd key size until adjusting rsa key size check with + wc_MakeRsaKey() + AssertNotNull(rsa = RSA_generate_key(2999, 65537, NULL, NULL)); + RSA_free(rsa); + */ + + AssertNull(RSA_generate_key(-1, 3, NULL, NULL)); + AssertNull(RSA_generate_key(RSA_MIN_SIZE - 1, 3, NULL, NULL)); + AssertNull(RSA_generate_key(RSA_MAX_SIZE + 1, 3, NULL, NULL)); + AssertNull(RSA_generate_key(2048, 0, NULL, NULL)); + + +#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) + { + byte buff[FOURK_BUF]; + byte der[FOURK_BUF]; + const char PrivKeyPemFile[] = "certs/client-keyEnc.pem"; + + XFILE f; + int bytes; + + /* test loading encrypted RSA private pem w/o password */ + f = XFOPEN(PrivKeyPemFile, "rb"); + AssertTrue((f != XBADFILE)); + bytes = (int)XFREAD(buff, 1, sizeof(buff), f); + XFCLOSE(f); + XMEMSET(der, 0, sizeof(der)); + /* test that error value is returned with no password */ + AssertIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der), ""), 0); + } +#endif + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_DER(void) +{ +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) && defined(OPENSSL_EXTRA) + + RSA *rsa; + int i; + const unsigned char *buff = NULL; + unsigned char *newBuff = NULL; + + struct tbl_s + { + const unsigned char *der; + int sz; + } tbl[] = { + +#ifdef USE_CERT_BUFFERS_1024 + {client_key_der_1024, sizeof_client_key_der_1024}, + {server_key_der_1024, sizeof_server_key_der_1024}, +#endif +#ifdef USE_CERT_BUFFERS_2048 + {client_key_der_2048, sizeof_client_key_der_2048}, + {server_key_der_2048, sizeof_server_key_der_2048}, +#endif + {NULL, 0} + }; + + /* Public Key DER */ + struct tbl_s pub[] = { +#ifdef USE_CERT_BUFFERS_1024 + {client_keypub_der_1024, sizeof_client_keypub_der_1024}, +#endif +#ifdef USE_CERT_BUFFERS_2048 + {client_keypub_der_2048, sizeof_client_keypub_der_2048}, +#endif + {NULL, 0} + }; + + printf(testingFmt, "test_wolfSSL_RSA_DER()"); + + AssertNull(d2i_RSAPublicKey(&rsa, NULL, pub[0].sz)); + buff = pub[0].der; + AssertNull(d2i_RSAPublicKey(&rsa, &buff, 1)); + AssertNull(d2i_RSAPrivateKey(&rsa, NULL, tbl[0].sz)); + buff = tbl[0].der; + AssertNull(d2i_RSAPrivateKey(&rsa, &buff, 1)); + + AssertIntEQ(i2d_RSAPublicKey(NULL, NULL), BAD_FUNC_ARG); + rsa = RSA_new(); + AssertIntEQ(i2d_RSAPublicKey(rsa, NULL), 0); + RSA_free(rsa); + + for (i = 0; tbl[i].der != NULL; i++) + { + /* Passing in pointer results in pointer moving. */ + buff = tbl[i].der; + AssertNotNull(d2i_RSAPublicKey(&rsa, &buff, tbl[i].sz)); + AssertNotNull(rsa); + RSA_free(rsa); + } + for (i = 0; tbl[i].der != NULL; i++) + { + /* Passing in pointer results in pointer moving. */ + buff = tbl[i].der; + AssertNotNull(d2i_RSAPrivateKey(&rsa, &buff, tbl[i].sz)); + AssertNotNull(rsa); + RSA_free(rsa); + } + + for (i = 0; pub[i].der != NULL; i++) + { + buff = pub[i].der; + AssertNotNull(d2i_RSAPublicKey(&rsa, &buff, pub[i].sz)); + AssertNotNull(rsa); + AssertIntEQ(i2d_RSAPublicKey(rsa, NULL), pub[i].sz); + newBuff = NULL; + AssertIntEQ(i2d_RSAPublicKey(rsa, &newBuff), pub[i].sz); + AssertNotNull(newBuff); + AssertIntEQ(0, memcmp((void *)newBuff, (void *)pub[i].der, pub[i].sz)); + XFREE((void *)newBuff, NULL, DYNAMIC_TYPE_TMP_BUFFER); + RSA_free(rsa); + } + + printf(resultFmt, passed); + +#endif +} + +static void test_wolfSSL_RSA_print(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ + !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(HAVE_FAST_RSA) && !defined(NO_BIO) + BIO *bio; + WOLFSSL_RSA* rsa = NULL; + printf(testingFmt, "wolfSSL_RSA_print"); + + AssertNotNull(bio = BIO_new_fd(STDOUT_FILENO, BIO_NOCLOSE)); + AssertNotNull(rsa = RSA_new()); + + AssertIntEQ(RSA_print(NULL, rsa, 0), -1); + AssertIntEQ(RSA_print_fp(XBADFILE, rsa, 0), 0); + AssertIntEQ(RSA_print(bio, NULL, 0), -1); + AssertIntEQ(RSA_print_fp(stdout, NULL, 0), 0); + /* Some very large number of indent spaces. */ + AssertIntEQ(RSA_print(bio, rsa, 128), -1); + /* RSA is empty. */ + AssertIntEQ(RSA_print(bio, rsa, 0), 0); + AssertIntEQ(RSA_print_fp(stdout, rsa, 0), 0); + + RSA_free(rsa); + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + + AssertIntEQ(RSA_print(bio, rsa, 0), 1); + AssertIntEQ(RSA_print(bio, rsa, 4), 1); + AssertIntEQ(RSA_print(bio, rsa, -1), 1); + AssertIntEQ(RSA_print_fp(stdout, rsa, 0), 1); + AssertIntEQ(RSA_print_fp(stdout, rsa, 4), 1); + AssertIntEQ(RSA_print_fp(stdout, rsa, -1), 1); + + BIO_free(bio); + RSA_free(rsa); + printf(resultFmt, passed); +#endif +} + +#ifndef NO_RSA +static void test_wolfSSL_RSA_padding_add_PKCS1_PSS(void) +{ +#if defined(OPENSSL_ALL) && defined(WC_RSA_PSS) && !defined(WC_NO_RNG) +#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) + RSA *rsa; + const unsigned char *derBuf = client_key_der_2048; + unsigned char em[256] = {0}; /* len = 2048/8 */ + /* Random data simulating a hash */ + const unsigned char mHash[WC_SHA256_DIGEST_SIZE] = { + 0x28, 0x6e, 0xfd, 0xf8, 0x76, 0xc7, 0x00, 0x3d, 0x91, 0x4e, 0x59, 0xe4, + 0x8e, 0xb7, 0x40, 0x7b, 0xd1, 0x0c, 0x98, 0x4b, 0xe3, 0x3d, 0xb3, 0xeb, + 0x6f, 0x8a, 0x3c, 0x42, 0xab, 0x21, 0xad, 0x28 + }; + + AssertNotNull(d2i_RSAPrivateKey(&rsa, &derBuf, sizeof_client_key_der_2048)); + AssertIntEQ(RSA_padding_add_PKCS1_PSS(NULL, em, mHash, EVP_sha256(), + RSA_PSS_SALTLEN_DIGEST), 0); + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, NULL, mHash, EVP_sha256(), + RSA_PSS_SALTLEN_DIGEST), 0); + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, NULL, EVP_sha256(), + RSA_PSS_SALTLEN_DIGEST), 0); + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, NULL, + RSA_PSS_SALTLEN_DIGEST), 0); + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), -5), 0); + + AssertIntEQ(RSA_verify_PKCS1_PSS(NULL, mHash, EVP_sha256(), em, + RSA_PSS_SALTLEN_MAX_SIGN), 0); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, NULL, EVP_sha256(), em, + RSA_PSS_SALTLEN_MAX_SIGN), 0); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, NULL, em, + RSA_PSS_SALTLEN_MAX_SIGN), 0); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), NULL, + RSA_PSS_SALTLEN_MAX_SIGN), 0); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, + RSA_PSS_SALTLEN_MAX_SIGN), 0); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, -5), 0); + + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), + RSA_PSS_SALTLEN_DIGEST), 1); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, + RSA_PSS_SALTLEN_DIGEST), 1); + + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), + RSA_PSS_SALTLEN_MAX_SIGN), 1); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, + RSA_PSS_SALTLEN_MAX_SIGN), 1); + + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), + RSA_PSS_SALTLEN_MAX), 1); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, + RSA_PSS_SALTLEN_MAX), 1); + + AssertIntEQ(RSA_padding_add_PKCS1_PSS(rsa, em, mHash, EVP_sha256(), 10), 1); + AssertIntEQ(RSA_verify_PKCS1_PSS(rsa, mHash, EVP_sha256(), em, 10), 1); + + RSA_free(rsa); +#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/ +} +#endif + +static void test_wolfSSL_RSA_sign_sha3(void) +{ +#if !defined(NO_RSA) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256) +#if defined(OPENSSL_ALL) && defined(WC_RSA_PSS) && !defined(WC_NO_RNG) + RSA *rsa; + const unsigned char *derBuf = client_key_der_2048; + unsigned char sigRet[256] = {0}; + unsigned int sigLen = sizeof(sigRet); + /* Random data simulating a hash */ + const unsigned char mHash[WC_SHA3_256_DIGEST_SIZE] = { + 0x28, 0x6e, 0xfd, 0xf8, 0x76, 0xc7, 0x00, 0x3d, 0x91, 0x4e, 0x59, 0xe4, + 0x8e, 0xb7, 0x40, 0x7b, 0xd1, 0x0c, 0x98, 0x4b, 0xe3, 0x3d, 0xb3, 0xeb, + 0x6f, 0x8a, 0x3c, 0x42, 0xab, 0x21, 0xad, 0x28 + }; + + printf(testingFmt, "wolfSSL_RSA_sign_sha3"); + + AssertNotNull(d2i_RSAPrivateKey(&rsa, &derBuf, sizeof_client_key_der_2048)); + AssertIntEQ(RSA_sign(NID_sha3_256, mHash, sizeof(mHash), sigRet, + &sigLen, rsa), 1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif /* OPENSSL_ALL && WC_RSA_PSS && !WC_NO_RNG*/ +#endif /* !NO_RSA && WOLFSSL_SHA3 && !WOLFSSL_NOSHA3_256*/ +} + +static void test_wolfSSL_RSA_get0_key(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) + RSA *rsa = NULL; + const BIGNUM* n = NULL; + const BIGNUM* e = NULL; + const BIGNUM* d = NULL; + + const unsigned char* der; + int derSz; + +#ifdef USE_CERT_BUFFERS_1024 + der = client_key_der_1024; + derSz = sizeof_client_key_der_1024; +#elif defined(USE_CERT_BUFFERS_2048) + der = client_key_der_2048; + derSz = sizeof_client_key_der_2048; +#else + der = NULL; + derSz = 0; +#endif + + printf(testingFmt, "test_wolfSSL_RSA_get0_key()"); + + if (der != NULL) { + RSA_get0_key(NULL, NULL, NULL, NULL); + RSA_get0_key(rsa, NULL, NULL, NULL); + RSA_get0_key(NULL, &n, &e, &d); + AssertNull(n); + AssertNull(e); + AssertNull(d); + + AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, derSz)); + AssertNotNull(rsa); + + RSA_get0_key(rsa, NULL, NULL, NULL); + RSA_get0_key(rsa, &n, NULL, NULL); + AssertNotNull(n); + RSA_get0_key(rsa, NULL, &e, NULL); + AssertNotNull(e); + RSA_get0_key(rsa, NULL, NULL, &d); + AssertNotNull(d); + RSA_get0_key(rsa, &n, &e, &d); + AssertNotNull(n); + AssertNotNull(e); + AssertNotNull(d); + + RSA_free(rsa); + } + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_meth(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA *rsa; + RSA_METHOD *rsa_meth; + + printf(testingFmt, "test_wolfSSL_RSA_meth"); + +#ifdef WOLFSSL_KEY_GEN + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + RSA_free(rsa); +#else + AssertNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); +#endif + + AssertNotNull(RSA_get_default_method()); + + wolfSSL_RSA_meth_free(NULL); + + AssertNull(wolfSSL_RSA_meth_new(NULL, 0)); + + AssertNotNull(rsa_meth = + RSA_meth_new("placeholder RSA method", RSA_METHOD_FLAG_NO_CHECK)); + +#ifndef NO_WOLFSSL_STUB + AssertIntEQ(RSA_meth_set_pub_enc(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_pub_dec(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_priv_enc(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_priv_dec(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_init(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_finish(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set0_app_data(rsa_meth, NULL), 1); +#endif + + AssertIntEQ(RSA_flags(NULL), 0); + RSA_set_flags(NULL, RSA_FLAG_CACHE_PUBLIC); + RSA_clear_flags(NULL, RSA_FLAG_CACHE_PUBLIC); + AssertIntEQ(RSA_test_flags(NULL, RSA_FLAG_CACHE_PUBLIC), 0); + + AssertNotNull(rsa = RSA_new()); + /* No method set. */ + AssertIntEQ(RSA_flags(rsa), 0); + RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + RSA_clear_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + AssertIntEQ(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); + + AssertIntEQ(RSA_set_method(NULL, rsa_meth), 1); + AssertIntEQ(RSA_set_method(rsa, rsa_meth), 1); + AssertNull(RSA_get_method(NULL)); + AssertPtrEq(RSA_get_method(rsa), rsa_meth); + AssertIntEQ(RSA_flags(rsa), RSA_METHOD_FLAG_NO_CHECK); + RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + AssertIntNE(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); + AssertIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC | + RSA_METHOD_FLAG_NO_CHECK); + RSA_clear_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + AssertIntEQ(RSA_test_flags(rsa, RSA_FLAG_CACHE_PUBLIC), 0); + AssertIntNE(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC); + + /* rsa_meth is freed here */ + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_RSA_verify(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && \ - !defined(NO_FILESYSTEM) && defined(HAVE_CRL) + !defined(NO_FILESYSTEM) #ifndef NO_BIO XFILE fp; RSA *pKey, *pubKey; @@ -51706,6 +51889,16 @@ static void test_wolfSSL_RSA_verify(void) AssertIntEQ(RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, signature, signatureLength, pubKey), SSL_SUCCESS); + AssertIntEQ(RSA_verify(NID_sha256, NULL, SHA256_DIGEST_LENGTH, NULL, + signatureLength, NULL), SSL_FAILURE); + AssertIntEQ(RSA_verify(NID_sha256, NULL, SHA256_DIGEST_LENGTH, signature, + signatureLength, pubKey), SSL_FAILURE); + AssertIntEQ(RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, NULL, + signatureLength, pubKey), SSL_FAILURE); + AssertIntEQ(RSA_verify(NID_sha256, hash, SHA256_DIGEST_LENGTH, signature, + signatureLength, NULL), SSL_FAILURE); + + RSA_free(pKey); EVP_PKEY_free(evpPkey); RSA_free(pubKey); @@ -51718,6 +51911,900 @@ static void test_wolfSSL_RSA_verify(void) #endif } +static void test_wolfSSL_RSA_sign(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA *rsa; + unsigned char hash[SHA256_DIGEST_LENGTH]; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; + const unsigned char* pubDer = client_keypub_der_1024; + size_t pubDerSz = sizeof_client_keypub_der_1024; + unsigned char signature[1024/8]; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; + const unsigned char* pubDer = client_keypub_der_2048; + size_t pubDerSz = sizeof_client_keypub_der_2048; + unsigned char signature[2048/8]; +#endif + unsigned int signatureLen; + const unsigned char* der; + + printf(testingFmt, "wolfSSL_RSA_sign"); + + XMEMSET(hash, 0, sizeof(hash)); + + der = privDer; + rsa = NULL; + AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(RSA_sign(NID_rsaEncryption, NULL, 0, NULL, NULL, NULL), 0); + AssertIntEQ(RSA_sign(NID_rsaEncryption, hash, sizeof(hash), signature, + &signatureLen, rsa), 0); + AssertIntEQ(RSA_sign(NID_sha256, NULL, sizeof(hash), signature, + &signatureLen, rsa), 0); + AssertIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), NULL, + &signatureLen, rsa), 0); + AssertIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature, + NULL, rsa), 0); + AssertIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature, + &signatureLen, NULL), 0); + + AssertIntEQ(RSA_sign(NID_sha256, hash, sizeof(hash), signature, + &signatureLen, rsa), 1); + + RSA_free(rsa); + der = pubDer; + rsa = NULL; + AssertNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz)); + + AssertIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature, + signatureLen, rsa), 1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_sign_ex(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA *rsa; + unsigned char hash[SHA256_DIGEST_LENGTH]; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; + const unsigned char* pubDer = client_keypub_der_1024; + size_t pubDerSz = sizeof_client_keypub_der_1024; + unsigned char signature[1024/8]; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; + const unsigned char* pubDer = client_keypub_der_2048; + size_t pubDerSz = sizeof_client_keypub_der_2048; + unsigned char signature[2048/8]; +#endif + unsigned int signatureLen; + const unsigned char* der; + unsigned char encodedHash[51]; + unsigned int encodedHashLen; + const unsigned char expEncHash[] = { + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20, + /* Hash data */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + printf(testingFmt, "wolfSSL_RSA_sign_ex"); + + XMEMSET(hash, 0, sizeof(hash)); + + AssertNotNull(rsa = wolfSSL_RSA_new()); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature, + &signatureLen, rsa, 1), 0); + wolfSSL_RSA_free(rsa); + + der = privDer; + rsa = NULL; + AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_rsaEncryption,NULL, 0, NULL, NULL, NULL, + -1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_rsaEncryption, hash, sizeof(hash), + signature, &signatureLen, rsa, 1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, NULL, sizeof(hash), signature, + &signatureLen, rsa, 1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), NULL, + &signatureLen, rsa, 1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature, + NULL, rsa, 1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature, + &signatureLen, NULL, 1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature, + &signatureLen, rsa, -1), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, NULL, sizeof(hash), signature, + &signatureLen, rsa, 0), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), NULL, + &signatureLen, rsa, 0), 0); + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature, + NULL, rsa, 0), 0); + + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), signature, + &signatureLen, rsa, 1), 1); + /* Test returning encoded hash. */ + AssertIntEQ(wolfSSL_RSA_sign_ex(NID_sha256, hash, sizeof(hash), encodedHash, + &encodedHashLen, rsa, 0), 1); + AssertIntEQ(encodedHashLen, sizeof(expEncHash)); + AssertIntEQ(XMEMCMP(encodedHash, expEncHash, sizeof(expEncHash)), 0); + + RSA_free(rsa); + der = pubDer; + rsa = NULL; + AssertNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz)); + + AssertIntEQ(RSA_verify(NID_sha256, hash, sizeof(hash), signature, + signatureLen, rsa), 1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + + +static void test_wolfSSL_RSA_public_decrypt(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA *rsa; + unsigned char msg[SHA256_DIGEST_LENGTH]; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* pubDer = client_keypub_der_1024; + size_t pubDerSz = sizeof_client_keypub_der_1024; + unsigned char decMsg[1024/8]; + const unsigned char encMsg[] = { + 0x45, 0x8e, 0x6e, 0x7a, 0x9c, 0xe1, 0x67, 0x36, + 0x72, 0xfc, 0x9d, 0x05, 0xdf, 0xc2, 0xaf, 0x54, + 0xc5, 0x2f, 0x94, 0xb8, 0xc7, 0x82, 0x40, 0xfa, + 0xa7, 0x8c, 0xb1, 0x89, 0x40, 0xc3, 0x59, 0x5a, + 0x77, 0x08, 0x54, 0x93, 0x43, 0x7f, 0xc4, 0xb7, + 0xc4, 0x78, 0xf1, 0xf8, 0xab, 0xbf, 0xc2, 0x81, + 0x5d, 0x97, 0xea, 0x7a, 0x60, 0x90, 0x51, 0xb7, + 0x47, 0x78, 0x48, 0x1e, 0x88, 0x6b, 0x89, 0xde, + 0xce, 0x41, 0x41, 0xae, 0x49, 0xf6, 0xfd, 0x2d, + 0x2d, 0x9c, 0x70, 0x7d, 0xf9, 0xcf, 0x77, 0x5f, + 0x06, 0xc7, 0x20, 0xe3, 0x57, 0xd4, 0xd8, 0x1a, + 0x96, 0xa2, 0x39, 0xb0, 0x6e, 0x8e, 0x68, 0xf8, + 0x57, 0x7b, 0x26, 0x88, 0x17, 0xc4, 0xb7, 0xf1, + 0x59, 0xfa, 0xb6, 0x95, 0xdd, 0x1e, 0xe8, 0xd8, + 0x4e, 0xbd, 0xcd, 0x41, 0xad, 0xc7, 0xe2, 0x39, + 0xb8, 0x00, 0xca, 0xf5, 0x59, 0xdf, 0xf8, 0x43 + }; +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \ + defined(WC_RSA_NO_PADDING) + const unsigned char encMsgNoPad[] = { + 0x0d, 0x41, 0x5a, 0xc7, 0x60, 0xd7, 0xbe, 0xb6, + 0x42, 0xd1, 0x65, 0xb1, 0x7e, 0x59, 0x54, 0xcc, + 0x76, 0x62, 0xd0, 0x2f, 0x4d, 0xe3, 0x23, 0x62, + 0xc8, 0x14, 0xfe, 0x5e, 0xa1, 0xc7, 0x05, 0xee, + 0x9e, 0x28, 0x2e, 0xf5, 0xfd, 0xa4, 0xc0, 0x43, + 0x55, 0xa2, 0x6b, 0x6b, 0x16, 0xa7, 0x63, 0x06, + 0xa7, 0x78, 0x4f, 0xda, 0xae, 0x10, 0x6d, 0xd1, + 0x2e, 0x1d, 0xbb, 0xbc, 0xc4, 0x1d, 0x82, 0xe4, + 0xc6, 0x76, 0x77, 0xa6, 0x0a, 0xef, 0xd2, 0x89, + 0xff, 0x30, 0x85, 0x22, 0xa0, 0x68, 0x88, 0x54, + 0xa3, 0xd1, 0x92, 0xd1, 0x3f, 0x57, 0xe4, 0xc7, + 0x43, 0x5a, 0x8b, 0xb3, 0x86, 0xaf, 0xd5, 0x6d, + 0x07, 0xe1, 0xa0, 0x5f, 0xe1, 0x9a, 0x06, 0xba, + 0x56, 0xd2, 0xb0, 0x73, 0xf5, 0xb3, 0xd0, 0x5f, + 0xc0, 0xbf, 0x22, 0x4c, 0x54, 0x4e, 0x11, 0xe2, + 0xc5, 0xf8, 0x66, 0x39, 0x9d, 0x70, 0x90, 0x31 + }; +#endif +#else + const unsigned char* pubDer = client_keypub_der_2048; + size_t pubDerSz = sizeof_client_keypub_der_2048; + unsigned char decMsg[2048/8]; + const unsigned char encMsg[] = { + 0x16, 0x5d, 0xbb, 0x00, 0x38, 0x73, 0x01, 0x34, + 0xca, 0x59, 0xc6, 0x8b, 0x64, 0x70, 0x89, 0xf5, + 0x50, 0x2d, 0x1d, 0x69, 0x1f, 0x07, 0x1e, 0x31, + 0xae, 0x9b, 0xa6, 0x6e, 0xee, 0x80, 0xd9, 0x9e, + 0x59, 0x33, 0x70, 0x30, 0x28, 0x42, 0x7d, 0x24, + 0x36, 0x95, 0x6b, 0xf9, 0x0a, 0x23, 0xcb, 0xce, + 0x66, 0xa5, 0x07, 0x5e, 0x11, 0xa7, 0xdc, 0xfb, + 0xd9, 0xc2, 0x51, 0xf0, 0x05, 0xc9, 0x39, 0xb3, + 0xae, 0xff, 0xfb, 0xe9, 0xb1, 0x9a, 0x54, 0xac, + 0x1d, 0xca, 0x42, 0x1a, 0xfd, 0x7c, 0x97, 0xa0, + 0x60, 0x2b, 0xcd, 0xb6, 0x36, 0x33, 0xfc, 0x44, + 0x69, 0xf7, 0x2e, 0x8c, 0x3b, 0x5f, 0xb4, 0x9f, + 0xa7, 0x02, 0x8f, 0x6d, 0x6b, 0x79, 0x10, 0x32, + 0x7d, 0xf4, 0x5d, 0xa1, 0x63, 0x22, 0x59, 0xc4, + 0x44, 0x8e, 0x44, 0x24, 0x8b, 0x14, 0x9d, 0x2b, + 0xb5, 0xd3, 0xad, 0x9a, 0x87, 0x0d, 0xe7, 0x70, + 0x6d, 0xe9, 0xae, 0xaa, 0x52, 0xbf, 0x1a, 0x9b, + 0xc8, 0x3d, 0x45, 0x7c, 0xd1, 0x90, 0xe3, 0xd9, + 0x57, 0xcf, 0xc3, 0x29, 0x69, 0x05, 0x07, 0x96, + 0x2e, 0x46, 0x74, 0x0a, 0xa7, 0x76, 0x8b, 0xc0, + 0x1c, 0x04, 0x80, 0x08, 0xa0, 0x94, 0x7e, 0xbb, + 0x2d, 0x99, 0xe9, 0xab, 0x18, 0x4d, 0x48, 0x2d, + 0x94, 0x5e, 0x50, 0x21, 0x42, 0xdf, 0xf5, 0x61, + 0x42, 0x7d, 0x86, 0x5d, 0x9e, 0x89, 0xc9, 0x5b, + 0x24, 0xab, 0xa1, 0xd8, 0x20, 0x45, 0xcb, 0x81, + 0xcf, 0xc5, 0x25, 0x7d, 0x11, 0x6e, 0xbd, 0x80, + 0xac, 0xba, 0xdc, 0xef, 0xb9, 0x05, 0x9c, 0xd5, + 0xc2, 0x26, 0x57, 0x69, 0x8b, 0x08, 0x27, 0xc7, + 0xea, 0xbe, 0xaf, 0x52, 0x21, 0x95, 0x9f, 0xa0, + 0x2f, 0x2f, 0x53, 0x7c, 0x2f, 0xa3, 0x0b, 0x79, + 0x39, 0x01, 0xa3, 0x37, 0x46, 0xa8, 0xc4, 0x34, + 0x41, 0x20, 0x7c, 0x3f, 0x70, 0x9a, 0x47, 0xe8 + }; +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \ + defined(WC_RSA_NO_PADDING) + const unsigned char encMsgNoPad[] = { + 0x79, 0x69, 0xdc, 0x0d, 0xff, 0x09, 0xeb, 0x91, + 0xbc, 0xda, 0xe4, 0xd3, 0xcd, 0xd5, 0xd3, 0x1c, + 0xb9, 0x66, 0xa8, 0x02, 0xf3, 0x75, 0x40, 0xf1, + 0x38, 0x4a, 0x37, 0x7b, 0x19, 0xc8, 0xcd, 0xea, + 0x79, 0xa8, 0x51, 0x32, 0x00, 0x3f, 0x4c, 0xde, + 0xaa, 0xe5, 0xe2, 0x7c, 0x10, 0xcd, 0x6e, 0x00, + 0xc6, 0xc4, 0x63, 0x98, 0x58, 0x9b, 0x38, 0xca, + 0xf0, 0x5d, 0xc8, 0xf0, 0x57, 0xf6, 0x21, 0x50, + 0x3f, 0x63, 0x05, 0x9f, 0xbf, 0xb6, 0x3b, 0x50, + 0x85, 0x06, 0x34, 0x08, 0x57, 0xb9, 0x44, 0xce, + 0xe4, 0x66, 0xbf, 0x0c, 0xfe, 0x36, 0xa4, 0x5b, + 0xed, 0x2d, 0x7d, 0xed, 0xf1, 0xbd, 0xda, 0x3e, + 0x19, 0x1f, 0x99, 0xc8, 0xe4, 0xc2, 0xbb, 0xb5, + 0x6c, 0x83, 0x22, 0xd1, 0xe7, 0x57, 0xcf, 0x1b, + 0x91, 0x0c, 0xa5, 0x47, 0x06, 0x71, 0x8f, 0x93, + 0xf3, 0xad, 0xdb, 0xe3, 0xf8, 0xa0, 0x0b, 0xcd, + 0x89, 0x4e, 0xa5, 0xb5, 0x03, 0x68, 0x61, 0x89, + 0x0b, 0xe2, 0x03, 0x8b, 0x1f, 0x54, 0xae, 0x0f, + 0xfa, 0xf0, 0xb7, 0x0f, 0x8c, 0x84, 0x35, 0x13, + 0x8d, 0x65, 0x1f, 0x2c, 0xd5, 0xce, 0xc4, 0x6c, + 0x98, 0x67, 0xe4, 0x1a, 0x85, 0x67, 0x69, 0x17, + 0x17, 0x5a, 0x5d, 0xfd, 0x23, 0xdd, 0x03, 0x3f, + 0x6d, 0x7a, 0xb6, 0x8b, 0x99, 0xc0, 0xb6, 0x70, + 0x86, 0xac, 0xf6, 0x02, 0xc2, 0x28, 0x42, 0xed, + 0x06, 0xcf, 0xca, 0x3d, 0x07, 0x16, 0xf0, 0x0e, + 0x04, 0x55, 0x1e, 0x59, 0x3f, 0x32, 0xc7, 0x12, + 0xc5, 0x0d, 0x9d, 0x64, 0x7d, 0x2e, 0xd4, 0xbc, + 0x8c, 0x24, 0x42, 0x94, 0x2b, 0xf6, 0x11, 0x7f, + 0xb1, 0x1c, 0x09, 0x12, 0x6f, 0x5e, 0x2e, 0x7a, + 0xc6, 0x01, 0xe0, 0x98, 0x31, 0xb7, 0x13, 0x03, + 0xce, 0x29, 0xe1, 0xef, 0x9d, 0xdf, 0x9b, 0xa5, + 0xba, 0x0b, 0xad, 0xf2, 0xeb, 0x2f, 0xf9, 0xd1 + }; +#endif +#endif + const unsigned char* der; +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \ + defined(WC_RSA_NO_PADDING) + int i; +#endif + + printf(testingFmt, "wolfSSL_RSA_public_decrypt"); + + XMEMSET(msg, 0, sizeof(msg)); + + der = pubDer; + rsa = NULL; + AssertNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz)); + + AssertIntEQ(RSA_public_decrypt(0, NULL, NULL, NULL, 0), -1); + AssertIntEQ(RSA_public_decrypt(-1, encMsg, decMsg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_decrypt(sizeof(encMsg), NULL, decMsg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, NULL, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, decMsg, NULL, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, decMsg, rsa, + RSA_PKCS1_PSS_PADDING), -1); + + AssertIntEQ(RSA_public_decrypt(sizeof(encMsg), encMsg, decMsg, rsa, + RSA_PKCS1_PADDING), 32); + AssertIntEQ(XMEMCMP(decMsg, msg, sizeof(msg)), 0); + +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && HAVE_FIPS_VERSION > 2)) && \ + defined(WC_RSA_NO_PADDING) + AssertIntEQ(RSA_public_decrypt(sizeof(encMsgNoPad), encMsgNoPad, decMsg, + rsa, RSA_NO_PADDING), sizeof(decMsg)); + /* Zeros before actual data. */ + for (i = 0; i < (int)(sizeof(decMsg) - sizeof(msg)); i += sizeof(msg)) { + AssertIntEQ(XMEMCMP(decMsg + i, msg, sizeof(msg)), 0); + } + /* Check actual data. */ + XMEMSET(msg, 0x01, sizeof(msg)); + AssertIntEQ(XMEMCMP(decMsg + i, msg, sizeof(msg)), 0); +#endif + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_private_encrypt(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA *rsa; + unsigned char msg[SHA256_DIGEST_LENGTH]; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; + unsigned char encMsg[1024/8]; + const unsigned char expEncMsg[] = { + 0x45, 0x8e, 0x6e, 0x7a, 0x9c, 0xe1, 0x67, 0x36, + 0x72, 0xfc, 0x9d, 0x05, 0xdf, 0xc2, 0xaf, 0x54, + 0xc5, 0x2f, 0x94, 0xb8, 0xc7, 0x82, 0x40, 0xfa, + 0xa7, 0x8c, 0xb1, 0x89, 0x40, 0xc3, 0x59, 0x5a, + 0x77, 0x08, 0x54, 0x93, 0x43, 0x7f, 0xc4, 0xb7, + 0xc4, 0x78, 0xf1, 0xf8, 0xab, 0xbf, 0xc2, 0x81, + 0x5d, 0x97, 0xea, 0x7a, 0x60, 0x90, 0x51, 0xb7, + 0x47, 0x78, 0x48, 0x1e, 0x88, 0x6b, 0x89, 0xde, + 0xce, 0x41, 0x41, 0xae, 0x49, 0xf6, 0xfd, 0x2d, + 0x2d, 0x9c, 0x70, 0x7d, 0xf9, 0xcf, 0x77, 0x5f, + 0x06, 0xc7, 0x20, 0xe3, 0x57, 0xd4, 0xd8, 0x1a, + 0x96, 0xa2, 0x39, 0xb0, 0x6e, 0x8e, 0x68, 0xf8, + 0x57, 0x7b, 0x26, 0x88, 0x17, 0xc4, 0xb7, 0xf1, + 0x59, 0xfa, 0xb6, 0x95, 0xdd, 0x1e, 0xe8, 0xd8, + 0x4e, 0xbd, 0xcd, 0x41, 0xad, 0xc7, 0xe2, 0x39, + 0xb8, 0x00, 0xca, 0xf5, 0x59, 0xdf, 0xf8, 0x43 + }; +#ifdef WC_RSA_NO_PADDING + const unsigned char expEncMsgNoPad[] = { + 0x0d, 0x41, 0x5a, 0xc7, 0x60, 0xd7, 0xbe, 0xb6, + 0x42, 0xd1, 0x65, 0xb1, 0x7e, 0x59, 0x54, 0xcc, + 0x76, 0x62, 0xd0, 0x2f, 0x4d, 0xe3, 0x23, 0x62, + 0xc8, 0x14, 0xfe, 0x5e, 0xa1, 0xc7, 0x05, 0xee, + 0x9e, 0x28, 0x2e, 0xf5, 0xfd, 0xa4, 0xc0, 0x43, + 0x55, 0xa2, 0x6b, 0x6b, 0x16, 0xa7, 0x63, 0x06, + 0xa7, 0x78, 0x4f, 0xda, 0xae, 0x10, 0x6d, 0xd1, + 0x2e, 0x1d, 0xbb, 0xbc, 0xc4, 0x1d, 0x82, 0xe4, + 0xc6, 0x76, 0x77, 0xa6, 0x0a, 0xef, 0xd2, 0x89, + 0xff, 0x30, 0x85, 0x22, 0xa0, 0x68, 0x88, 0x54, + 0xa3, 0xd1, 0x92, 0xd1, 0x3f, 0x57, 0xe4, 0xc7, + 0x43, 0x5a, 0x8b, 0xb3, 0x86, 0xaf, 0xd5, 0x6d, + 0x07, 0xe1, 0xa0, 0x5f, 0xe1, 0x9a, 0x06, 0xba, + 0x56, 0xd2, 0xb0, 0x73, 0xf5, 0xb3, 0xd0, 0x5f, + 0xc0, 0xbf, 0x22, 0x4c, 0x54, 0x4e, 0x11, 0xe2, + 0xc5, 0xf8, 0x66, 0x39, 0x9d, 0x70, 0x90, 0x31 + }; +#endif +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; + unsigned char encMsg[2048/8]; + const unsigned char expEncMsg[] = { + 0x16, 0x5d, 0xbb, 0x00, 0x38, 0x73, 0x01, 0x34, + 0xca, 0x59, 0xc6, 0x8b, 0x64, 0x70, 0x89, 0xf5, + 0x50, 0x2d, 0x1d, 0x69, 0x1f, 0x07, 0x1e, 0x31, + 0xae, 0x9b, 0xa6, 0x6e, 0xee, 0x80, 0xd9, 0x9e, + 0x59, 0x33, 0x70, 0x30, 0x28, 0x42, 0x7d, 0x24, + 0x36, 0x95, 0x6b, 0xf9, 0x0a, 0x23, 0xcb, 0xce, + 0x66, 0xa5, 0x07, 0x5e, 0x11, 0xa7, 0xdc, 0xfb, + 0xd9, 0xc2, 0x51, 0xf0, 0x05, 0xc9, 0x39, 0xb3, + 0xae, 0xff, 0xfb, 0xe9, 0xb1, 0x9a, 0x54, 0xac, + 0x1d, 0xca, 0x42, 0x1a, 0xfd, 0x7c, 0x97, 0xa0, + 0x60, 0x2b, 0xcd, 0xb6, 0x36, 0x33, 0xfc, 0x44, + 0x69, 0xf7, 0x2e, 0x8c, 0x3b, 0x5f, 0xb4, 0x9f, + 0xa7, 0x02, 0x8f, 0x6d, 0x6b, 0x79, 0x10, 0x32, + 0x7d, 0xf4, 0x5d, 0xa1, 0x63, 0x22, 0x59, 0xc4, + 0x44, 0x8e, 0x44, 0x24, 0x8b, 0x14, 0x9d, 0x2b, + 0xb5, 0xd3, 0xad, 0x9a, 0x87, 0x0d, 0xe7, 0x70, + 0x6d, 0xe9, 0xae, 0xaa, 0x52, 0xbf, 0x1a, 0x9b, + 0xc8, 0x3d, 0x45, 0x7c, 0xd1, 0x90, 0xe3, 0xd9, + 0x57, 0xcf, 0xc3, 0x29, 0x69, 0x05, 0x07, 0x96, + 0x2e, 0x46, 0x74, 0x0a, 0xa7, 0x76, 0x8b, 0xc0, + 0x1c, 0x04, 0x80, 0x08, 0xa0, 0x94, 0x7e, 0xbb, + 0x2d, 0x99, 0xe9, 0xab, 0x18, 0x4d, 0x48, 0x2d, + 0x94, 0x5e, 0x50, 0x21, 0x42, 0xdf, 0xf5, 0x61, + 0x42, 0x7d, 0x86, 0x5d, 0x9e, 0x89, 0xc9, 0x5b, + 0x24, 0xab, 0xa1, 0xd8, 0x20, 0x45, 0xcb, 0x81, + 0xcf, 0xc5, 0x25, 0x7d, 0x11, 0x6e, 0xbd, 0x80, + 0xac, 0xba, 0xdc, 0xef, 0xb9, 0x05, 0x9c, 0xd5, + 0xc2, 0x26, 0x57, 0x69, 0x8b, 0x08, 0x27, 0xc7, + 0xea, 0xbe, 0xaf, 0x52, 0x21, 0x95, 0x9f, 0xa0, + 0x2f, 0x2f, 0x53, 0x7c, 0x2f, 0xa3, 0x0b, 0x79, + 0x39, 0x01, 0xa3, 0x37, 0x46, 0xa8, 0xc4, 0x34, + 0x41, 0x20, 0x7c, 0x3f, 0x70, 0x9a, 0x47, 0xe8 + }; +#ifdef WC_RSA_NO_PADDING + const unsigned char expEncMsgNoPad[] = { + 0x79, 0x69, 0xdc, 0x0d, 0xff, 0x09, 0xeb, 0x91, + 0xbc, 0xda, 0xe4, 0xd3, 0xcd, 0xd5, 0xd3, 0x1c, + 0xb9, 0x66, 0xa8, 0x02, 0xf3, 0x75, 0x40, 0xf1, + 0x38, 0x4a, 0x37, 0x7b, 0x19, 0xc8, 0xcd, 0xea, + 0x79, 0xa8, 0x51, 0x32, 0x00, 0x3f, 0x4c, 0xde, + 0xaa, 0xe5, 0xe2, 0x7c, 0x10, 0xcd, 0x6e, 0x00, + 0xc6, 0xc4, 0x63, 0x98, 0x58, 0x9b, 0x38, 0xca, + 0xf0, 0x5d, 0xc8, 0xf0, 0x57, 0xf6, 0x21, 0x50, + 0x3f, 0x63, 0x05, 0x9f, 0xbf, 0xb6, 0x3b, 0x50, + 0x85, 0x06, 0x34, 0x08, 0x57, 0xb9, 0x44, 0xce, + 0xe4, 0x66, 0xbf, 0x0c, 0xfe, 0x36, 0xa4, 0x5b, + 0xed, 0x2d, 0x7d, 0xed, 0xf1, 0xbd, 0xda, 0x3e, + 0x19, 0x1f, 0x99, 0xc8, 0xe4, 0xc2, 0xbb, 0xb5, + 0x6c, 0x83, 0x22, 0xd1, 0xe7, 0x57, 0xcf, 0x1b, + 0x91, 0x0c, 0xa5, 0x47, 0x06, 0x71, 0x8f, 0x93, + 0xf3, 0xad, 0xdb, 0xe3, 0xf8, 0xa0, 0x0b, 0xcd, + 0x89, 0x4e, 0xa5, 0xb5, 0x03, 0x68, 0x61, 0x89, + 0x0b, 0xe2, 0x03, 0x8b, 0x1f, 0x54, 0xae, 0x0f, + 0xfa, 0xf0, 0xb7, 0x0f, 0x8c, 0x84, 0x35, 0x13, + 0x8d, 0x65, 0x1f, 0x2c, 0xd5, 0xce, 0xc4, 0x6c, + 0x98, 0x67, 0xe4, 0x1a, 0x85, 0x67, 0x69, 0x17, + 0x17, 0x5a, 0x5d, 0xfd, 0x23, 0xdd, 0x03, 0x3f, + 0x6d, 0x7a, 0xb6, 0x8b, 0x99, 0xc0, 0xb6, 0x70, + 0x86, 0xac, 0xf6, 0x02, 0xc2, 0x28, 0x42, 0xed, + 0x06, 0xcf, 0xca, 0x3d, 0x07, 0x16, 0xf0, 0x0e, + 0x04, 0x55, 0x1e, 0x59, 0x3f, 0x32, 0xc7, 0x12, + 0xc5, 0x0d, 0x9d, 0x64, 0x7d, 0x2e, 0xd4, 0xbc, + 0x8c, 0x24, 0x42, 0x94, 0x2b, 0xf6, 0x11, 0x7f, + 0xb1, 0x1c, 0x09, 0x12, 0x6f, 0x5e, 0x2e, 0x7a, + 0xc6, 0x01, 0xe0, 0x98, 0x31, 0xb7, 0x13, 0x03, + 0xce, 0x29, 0xe1, 0xef, 0x9d, 0xdf, 0x9b, 0xa5, + 0xba, 0x0b, 0xad, 0xf2, 0xeb, 0x2f, 0xf9, 0xd1 + }; +#endif +#endif + const unsigned char* der; + + printf(testingFmt, "wolfSSL_RSA_private_encrypt"); + + XMEMSET(msg, 0x00, sizeof(msg)); + + der = privDer; + rsa = NULL; + AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(RSA_private_encrypt(0, NULL, NULL, NULL, 0), -1); + AssertIntEQ(RSA_private_encrypt(0, msg, encMsg, rsa, RSA_PKCS1_PADDING), + -1); + AssertIntEQ(RSA_private_encrypt(sizeof(msg), NULL, encMsg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_encrypt(sizeof(msg), msg, NULL, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, NULL, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, rsa, + RSA_PKCS1_PSS_PADDING), -1); + + AssertIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, rsa, + RSA_PKCS1_PADDING), sizeof(encMsg)); + AssertIntEQ(XMEMCMP(encMsg, expEncMsg, sizeof(expEncMsg)), 0); + +#ifdef WC_RSA_NO_PADDING + /* Non-zero message. */ + XMEMSET(msg, 0x01, sizeof(msg)); + AssertIntEQ(RSA_private_encrypt(sizeof(msg), msg, encMsg, rsa, + RSA_NO_PADDING), sizeof(encMsg)); + AssertIntEQ(XMEMCMP(encMsg, expEncMsgNoPad, sizeof(expEncMsgNoPad)), 0); +#endif + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_public_encrypt(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA* rsa; + const unsigned char msg[2048/8] = { 0 }; + unsigned char encMsg[2048/8]; + + printf(testingFmt, "wolfSSL_RSA_public_decrypt"); + + AssertNotNull(rsa = RSA_new()); + + AssertIntEQ(RSA_public_encrypt(-1, msg, encMsg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_encrypt(sizeof(msg), NULL, encMsg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_encrypt(sizeof(msg), msg, NULL, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_encrypt(sizeof(msg), msg, encMsg, NULL, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_public_encrypt(sizeof(msg), msg, encMsg, rsa, + RSA_PKCS1_PSS_PADDING), -1); + /* Empty RSA key. */ + AssertIntEQ(RSA_public_encrypt(sizeof(msg), msg, encMsg, rsa, + RSA_PKCS1_PADDING), -1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_private_decrypt(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA* rsa; + unsigned char msg[2048/8]; + const unsigned char encMsg[2048/8] = { 0 }; + + printf(testingFmt, "wolfSSL_RSA_private_decrypt"); + + AssertNotNull(rsa = RSA_new()); + + AssertIntEQ(RSA_private_decrypt(-1, encMsg, msg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_decrypt(sizeof(encMsg), NULL, msg, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, NULL, rsa, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, msg, NULL, + RSA_PKCS1_PADDING), -1); + AssertIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, msg, rsa, + RSA_PKCS1_PSS_PADDING), -1); + /* Empty RSA key. */ + AssertIntEQ(RSA_private_decrypt(sizeof(encMsg), encMsg, msg, rsa, + RSA_PKCS1_PADDING), -1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_GenAdd(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) + RSA *rsa; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; + const unsigned char* pubDer = client_keypub_der_1024; + size_t pubDerSz = sizeof_client_keypub_der_1024; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; + const unsigned char* pubDer = client_keypub_der_2048; + size_t pubDerSz = sizeof_client_keypub_der_2048; +#endif + const unsigned char* der; + + printf(testingFmt, "wolfSSL_RSA_GenAdd"); + + der = privDer; + rsa = NULL; + AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(wolfSSL_RSA_GenAdd(NULL), -1); +#ifndef RSA_LOW_MEM + AssertIntEQ(wolfSSL_RSA_GenAdd(rsa), 1); +#else + /* dmp1 and dmq1 are not set (allocated) when RSA_LOW_MEM. */ + AssertIntEQ(wolfSSL_RSA_GenAdd(rsa), -1); +#endif + + RSA_free(rsa); + der = pubDer; + rsa = NULL; + AssertNotNull(d2i_RSAPublicKey(&rsa, &der, pubDerSz)); + /* Need private values. */ + AssertIntEQ(wolfSSL_RSA_GenAdd(rsa), -1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_blinding_on(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_WOLFSSL_STUB) + RSA *rsa; + WOLFSSL_BN_CTX *bnCtx; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; +#endif + const unsigned char* der; + + printf(testingFmt, "wolfSSL_RSA_blinding_on"); + + der = privDer; + rsa = NULL; + AssertNotNull(d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + AssertNotNull(bnCtx = wolfSSL_BN_CTX_new()); + + /* Does nothing so all parameters are valid. */ + AssertIntEQ(wolfSSL_RSA_blinding_on(NULL, NULL), 1); + AssertIntEQ(wolfSSL_RSA_blinding_on(rsa, NULL), 1); + AssertIntEQ(wolfSSL_RSA_blinding_on(NULL, bnCtx), 1); + AssertIntEQ(wolfSSL_RSA_blinding_on(rsa, bnCtx), 1); + + wolfSSL_BN_CTX_free(bnCtx); + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_ex_data(void) +{ +#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) + RSA* rsa; + unsigned char data[1]; + + printf(testingFmt, "wolfSSL_RSA_ex_data"); + + rsa = RSA_new(); + + AssertNull(wolfSSL_RSA_get_ex_data(NULL, 0)); + AssertNull(wolfSSL_RSA_get_ex_data(rsa, 0)); +#ifdef MAX_EX_DATA + AssertNull(wolfSSL_RSA_get_ex_data(rsa, MAX_EX_DATA)); + AssertIntEQ(wolfSSL_RSA_set_ex_data(rsa, MAX_EX_DATA, data), 0); +#endif + AssertIntEQ(wolfSSL_RSA_set_ex_data(NULL, 0, NULL), 0); + AssertIntEQ(wolfSSL_RSA_set_ex_data(NULL, 0, data), 0); + +#ifdef HAVE_EX_DATA + AssertIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, NULL), 1); + AssertIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, data), 1); + AssertPtrEq(wolfSSL_RSA_get_ex_data(rsa, 0), data); +#else + AssertIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, NULL), 0); + AssertIntEQ(wolfSSL_RSA_set_ex_data(rsa, 0, data), 0); + AssertNull(wolfSSL_RSA_get_ex_data(rsa, 0)); +#endif + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif /* !NO_RSA && OPENSSL_EXTRA */ +} + +static void test_wolfSSL_RSA_LoadDer(void) +{ +#if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || \ + defined(OPENSSL_EXTRA_X509_SMALL)) + RSA *rsa; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; +#endif + + printf(testingFmt, "wolfSSL_RSA_LoadDer"); + + AssertNotNull(rsa = RSA_new()); + + AssertIntEQ(wolfSSL_RSA_LoadDer(NULL, privDer, (int)privDerSz), -1); + AssertIntEQ(wolfSSL_RSA_LoadDer(rsa, NULL, (int)privDerSz), -1); + AssertIntEQ(wolfSSL_RSA_LoadDer(rsa, privDer, 0), -1); + + AssertIntEQ(wolfSSL_RSA_LoadDer(rsa, privDer, (int)privDerSz), 1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +/* Local API. */ +static void test_wolfSSL_RSA_To_Der(void) +{ +#ifdef WOLFSSL_TEST_STATIC_BUILD +#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && \ + defined(OPENSSL_EXTRA) && !defined(NO_RSA) + RSA* rsa; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; + const unsigned char* pubDer = client_keypub_der_1024; + size_t pubDerSz = sizeof_client_keypub_der_1024; + unsigned char out[sizeof(client_key_der_1024)]; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; + const unsigned char* pubDer = client_keypub_der_2048; + size_t pubDerSz = sizeof_client_keypub_der_2048; + unsigned char out[sizeof(client_key_der_2048)]; +#endif + const unsigned char* der; + unsigned char* outDer = NULL; + + printf(testingFmt, "wolfSSL_RSA_To_Der"); + + der = privDer; + rsa = NULL; + AssertNotNull(wolfSSL_d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(wolfSSL_RSA_To_Der(NULL, &outDer, 0, HEAP_HINT), BAD_FUNC_ARG); + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 2, HEAP_HINT), BAD_FUNC_ARG); + + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, NULL, 0, HEAP_HINT), privDerSz); + outDer = out; + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), privDerSz); + AssertIntEQ(XMEMCMP(out, privDer, privDerSz), 0); + outDer = NULL; + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), privDerSz); + AssertNotNull(outDer); + AssertIntEQ(XMEMCMP(outDer, privDer, privDerSz), 0); + XFREE(outDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER.); + + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, NULL, 1, HEAP_HINT), pubDerSz); + outDer = out; + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 1, HEAP_HINT), pubDerSz); + AssertIntEQ(XMEMCMP(out, pubDer, pubDerSz), 0); + + RSA_free(rsa); + + AssertNotNull(rsa = RSA_new()); + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), BAD_FUNC_ARG); + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 1, HEAP_HINT), BAD_FUNC_ARG); + RSA_free(rsa); + + der = pubDer; + rsa = NULL; + AssertNotNull(wolfSSL_d2i_RSAPublicKey(&rsa, &der, pubDerSz)); + AssertIntEQ(wolfSSL_RSA_To_Der(rsa, &outDer, 0, HEAP_HINT), BAD_FUNC_ARG); + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +#endif +} + +/* wolfSSL_PEM_read_RSAPublicKey is a stub function. */ +static void test_wolfSSL_PEM_read_RSAPublicKey(void) +{ +#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ + !defined(NO_WOLFSSL_STUB) + RSA* rsa = NULL; + XFILE fp; + + printf(testingFmt, "wolfSSL_PEM_read_RSAPublicKey"); + + fp = XFOPEN("./certs/client-keyPub.pem", "rb"); + + AssertNull(wolfSSL_PEM_read_RSAPublicKey(XBADFILE, NULL, NULL, NULL)); + /* Valid but stub so returns NULL. */ + AssertNull(wolfSSL_PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)); + /* Valid but stub so returns NULL. */ + AssertNull(wolfSSL_PEM_read_RSAPublicKey(fp, &rsa, NULL, NULL)); + + XFCLOSE(fp); + + printf(resultFmt, passed); +#endif +} + +/* wolfSSL_PEM_read_RSAPublicKey is a stub function. */ +static void test_wolfSSL_PEM_write_RSA_PUBKEY(void) +{ +#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ + !defined(NO_WOLFSSL_STUB) + RSA* rsa = NULL; + + printf(testingFmt, "wolfSSL_PEM_write_RSA_PUBKEY"); + + AssertIntEQ(wolfSSL_PEM_write_RSA_PUBKEY(XBADFILE, NULL), 0); + AssertIntEQ(wolfSSL_PEM_write_RSA_PUBKEY(stdout, NULL), 0); + /* Valid but stub so returns 0. */ + AssertIntEQ(wolfSSL_PEM_write_RSA_PUBKEY(stdout, rsa), 0); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_PEM_write_RSAPrivateKey(void) +{ +#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(HAVE_USER_RSA) && (defined(WOLFSSL_PEM_TO_DER) || \ + defined(WOLFSSL_DER_TO_PEM)) && !defined(NO_FILESYSTEM) + RSA* rsa; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; +#endif + const unsigned char* der; + unsigned char passwd[] = "password"; + + printf(testingFmt, "wolfSSL_PEM_write_RSAPrivateKey"); + + AssertNotNull(rsa = RSA_new()); + AssertIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, + NULL, NULL), 0); + RSA_free(rsa); + + der = privDer; + rsa = NULL; + AssertNotNull(wolfSSL_d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(wolfSSL_PEM_write_RSAPrivateKey(XBADFILE, rsa, NULL, NULL, 0, + NULL, NULL), 0); + AssertIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stdout, NULL, NULL, NULL, 0, + NULL, NULL), 0); + + AssertIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, + NULL, NULL), 1); + AssertIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stdout, rsa, EVP_aes_128_cbc(), + NULL, 0, NULL, NULL), 1); + AssertIntEQ(wolfSSL_PEM_write_RSAPrivateKey(stdout, rsa, EVP_aes_128_cbc(), + passwd, sizeof(passwd) - 1, NULL, NULL), 1); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_PEM_write_mem_RSAPrivateKey(void) +{ +#if !defined(NO_RSA) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(HAVE_USER_RSA) && (defined(WOLFSSL_PEM_TO_DER) || \ + defined(WOLFSSL_DER_TO_PEM)) + RSA* rsa; +#ifdef USE_CERT_BUFFERS_1024 + const unsigned char* privDer = client_key_der_1024; + size_t privDerSz = sizeof_client_key_der_1024; +#else + const unsigned char* privDer = client_key_der_2048; + size_t privDerSz = sizeof_client_key_der_2048; +#endif + const unsigned char* der; + unsigned char passwd[] = "password"; + unsigned char* pem; + int plen; + + printf(testingFmt, "wolfSSL_PEM_write_mem_RSAPrivateKey"); + + AssertNotNull(rsa = RSA_new()); + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, &pem, + &plen), 0); + RSA_free(rsa); + + der = privDer; + rsa = NULL; + AssertNotNull(wolfSSL_d2i_RSAPrivateKey(&rsa, &der, privDerSz)); + + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(NULL, NULL, NULL, 0, &pem, + &plen), 0); + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, NULL, + &plen), 0); + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, &pem, + NULL), 0); + + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, NULL, NULL, 0, &pem, + &plen), 1); + XFREE(pem, NULL, DYNAMIC_TYPE_KEY); + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, EVP_aes_128_cbc(), + NULL, 0, &pem, &plen), 1); + XFREE(pem, NULL, DYNAMIC_TYPE_KEY); + AssertIntEQ(wolfSSL_PEM_write_mem_RSAPrivateKey(rsa, EVP_aes_128_cbc(), + passwd, sizeof(passwd) - 1, &pem, &plen), 1); + XFREE(pem, NULL, DYNAMIC_TYPE_KEY); + + RSA_free(rsa); + + printf(resultFmt, passed); +#endif +} #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) @@ -51779,7 +52866,7 @@ static void test_openssl_generate_key_and_cert(void) AssertIntNE(BN_set_word(exponent, WC_RSA_EXPONENT), 0); #ifndef WOLFSSL_KEY_GEN - AssertIntEQ(RSA_generate_key_ex(rsa, key_length, exponent, NULL), WOLFSSL_FAILURE); + AssertIntEQ(RSA_generate_key_ex(rsa, key_length, exponent, NULL), 0); #if defined(USE_CERT_BUFFERS_1024) AssertIntNE(wolfSSL_RSA_LoadDer_ex(rsa, server_key_der_1024, @@ -51793,6 +52880,9 @@ static void test_openssl_generate_key_and_cert(void) rsa = NULL; #endif #else + AssertIntEQ(RSA_generate_key_ex(NULL, key_length, exponent, NULL), 0); + AssertIntEQ(RSA_generate_key_ex(rsa, 0, exponent, NULL), 0); + AssertIntEQ(RSA_generate_key_ex(rsa, key_length, NULL, NULL), 0); AssertIntNE(RSA_generate_key_ex(rsa, key_length, exponent, NULL), 0); #endif @@ -54624,10 +55714,6 @@ void ApiTest(void) test_wolfSSL_GENERAL_NAME_print(); test_wolfSSL_sk_DIST_POINT(); test_wolfSSL_MD4(); - test_wolfSSL_RSA(); - test_wolfSSL_RSA_DER(); - test_wolfSSL_RSA_get0_key(); - test_wolfSSL_RSA_meth(); test_wolfSSL_verify_mode(); test_wolfSSL_verify_depth(); test_wolfSSL_HMAC_CTX(); @@ -54688,10 +55774,6 @@ void ApiTest(void) test_wolfSSL_OCSP_resp_get0(); test_wolfSSL_EVP_PKEY_derive(); test_wolfSSL_EVP_PBE_scrypt(); -#ifndef NO_RSA - test_wolfSSL_RSA_padding_add_PKCS1_PSS(); -#endif - test_wolfSSL_RSA_sign_sha3(); test_CONF_modules_xxx(); test_CRYPTO_set_dynlock_xxx(); @@ -54771,7 +55853,33 @@ void ApiTest(void) test_wolfSSL_X509_print(); test_wolfSSL_BIO_get_len(); #endif + + test_wolfSSL_RSA(); + test_wolfSSL_RSA_DER(); + test_wolfSSL_RSA_print(); +#ifndef NO_RSA + test_wolfSSL_RSA_padding_add_PKCS1_PSS(); +#endif + test_wolfSSL_RSA_sign_sha3(); + test_wolfSSL_RSA_get0_key(); + test_wolfSSL_RSA_meth(); test_wolfSSL_RSA_verify(); + test_wolfSSL_RSA_sign(); + test_wolfSSL_RSA_sign_ex(); + test_wolfSSL_RSA_public_decrypt(); + test_wolfSSL_RSA_private_encrypt(); + test_wolfSSL_RSA_public_encrypt(); + test_wolfSSL_RSA_private_decrypt(); + test_wolfSSL_RSA_GenAdd(); + test_wolfSSL_RSA_blinding_on(); + test_wolfSSL_RSA_ex_data(); + test_wolfSSL_RSA_LoadDer(); + test_wolfSSL_RSA_To_Der(); + test_wolfSSL_PEM_read_RSAPublicKey(); + test_wolfSSL_PEM_write_RSA_PUBKEY(); + test_wolfSSL_PEM_write_RSAPrivateKey(); + test_wolfSSL_PEM_write_mem_RSAPrivateKey(); + test_wolfSSL_X509V3_EXT_get(); test_wolfSSL_X509V3_EXT_nconf(); test_wolfSSL_X509V3_EXT(); @@ -54787,7 +55895,6 @@ void ApiTest(void) test_wolfSSL_X509V3_EXT_print(); test_wolfSSL_X509_cmp(); #ifndef NO_BIO - test_wolfSSL_RSA_print(); test_wolfSSL_ASN1_STRING_print(); #endif test_wolfSSL_ASN1_get_object(); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 422b4b2f6..dc8923783 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1526,6 +1526,7 @@ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_E ctx->pkey = pkey; #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) ctx->padding = RSA_PKCS1_PADDING; + ctx->md = NULL; #endif #ifdef HAVE_ECC if (pkey->ecc && pkey->ecc->group) { @@ -1558,6 +1559,26 @@ int wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding) return WOLFSSL_SUCCESS; } +/* Sets the message digest type for RSA padding to use. + * + * ctx structure to set padding in. + * md Message digest + * + * returns WOLFSSL_SUCCESS on success. + */ +int wolfSSL_EVP_PKEY_CTX_set_signature_md(WOLFSSL_EVP_PKEY_CTX *ctx, + const EVP_MD* md) +{ + if (ctx == NULL) return 0; + WOLFSSL_ENTER("EVP_PKEY_CTX_set_signature_md"); +#ifndef NO_RSA + ctx->md = md; +#else + (void)md; +#endif + return WOLFSSL_SUCCESS; +} + /* create a PKEY context and return it */ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new_id(int id, WOLFSSL_ENGINE *e) { @@ -2247,10 +2268,11 @@ int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig, } /* wolfSSL_RSA_sign_generic_padding performs a check that the output * sig buffer is large enough */ - if (wolfSSL_RSA_sign_generic_padding(WC_HASH_TYPE_NONE, tbs, - (unsigned int)tbslen, sig, &usiglen, ctx->pkey->rsa, 1, ctx->padding) - != WOLFSSL_SUCCESS) + if (wolfSSL_RSA_sign_generic_padding(wolfSSL_EVP_MD_type(ctx->md), tbs, + (unsigned int)tbslen, sig, &usiglen, ctx->pkey->rsa, 1, + ctx->padding) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; + } *siglen = (size_t)usiglen; return WOLFSSL_SUCCESS; } diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 3910f546d..70c4cd8d2 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1018,6 +1018,54 @@ size_t wc_strlcat(char *dst, const char *src, size_t dstSize) } #endif /* USE_WOLF_STRLCAT */ +#ifndef SINGLE_THREADED +/* TODO: use atomic operations instead of mutex */ +void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err) +{ + int ret = wc_InitMutex(&ref->mutex); + if (ret != 0) { + WOLFSSL_MSG("Failed to create mutex for reference counting!"); + } + ref->count = 1; + + *err = ret; +} + +void wolfSSL_RefFree(wolfSSL_Ref* ref) +{ + if (wc_FreeMutex(&ref->mutex) != 0) { + WOLFSSL_MSG("Failed to free mutex of reference counting!"); + } +} + +void wolfSSL_RefInc(wolfSSL_Ref* ref, int* err) +{ + int ret = wc_LockMutex(&ref->mutex); + if (ret != 0) { + WOLFSSL_MSG("Failed to lock mutex for reference increment!"); + } + else { + ref->count++; + wc_UnLockMutex(&ref->mutex); + } + *err = ret; +} + +void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err) +{ + int ret = wc_LockMutex(&ref->mutex); + if (ret != 0) { + WOLFSSL_MSG("Failed to lock mutex for reference decrement!"); + } + else { + ref->count--; + *isZero = (ref->count == 0); + wc_UnLockMutex(&ref->mutex); + } + *err = ret; +} +#endif + #if WOLFSSL_CRYPT_HW_MUTEX /* Mutex for protection of cryptography hardware */ static wolfSSL_Mutex wcCryptHwMutex; diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 7a612f838..b058577ed 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -454,6 +454,9 @@ struct WOLFSSL_EVP_PKEY_CTX { #ifdef HAVE_ECC int curveNID; #endif +#ifndef NO_RSA + const WOLFSSL_EVP_MD* md; +#endif }; struct WOLFSSL_ASN1_PCTX { @@ -639,6 +642,8 @@ WOLFSSL_API void wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx); #endif WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_rsa_padding(WOLFSSL_EVP_PKEY_CTX *ctx, int padding); +WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_signature_md(WOLFSSL_EVP_PKEY_CTX *ctx, + const WOLFSSL_EVP_MD* md); WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(WOLFSSL_EVP_PKEY_CTX *ctx, int bits); WOLFSSL_API int wolfSSL_EVP_PKEY_derive_init(WOLFSSL_EVP_PKEY_CTX *ctx); @@ -1002,6 +1007,7 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_PKEY_CTX_free wolfSSL_EVP_PKEY_CTX_free #define EVP_PKEY_CTX_new wolfSSL_EVP_PKEY_CTX_new #define EVP_PKEY_CTX_set_rsa_padding wolfSSL_EVP_PKEY_CTX_set_rsa_padding +#define EVP_PKEY_CTX_set_signature_md wolfSSL_EVP_PKEY_CTX_set_signature_md #define EVP_PKEY_CTX_new_id wolfSSL_EVP_PKEY_CTX_new_id #define EVP_PKEY_CTX_set_rsa_keygen_bits wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits #define EVP_PKEY_derive_init wolfSSL_EVP_PKEY_derive_init diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 545cc33f6..3e2b643a5 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -59,44 +59,42 @@ #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ typedef struct WOLFSSL_RSA_METHOD { + /* Flags of RSA key implementation. */ int flags; + /* Name of RSA key implementation. */ char *name; + /* RSA method dynamically allocated. */ + word16 dynamic:1; } WOLFSSL_RSA_METHOD; #ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ #define WOLFSSL_RSA_TYPE_DEFINED +/* RSA key compatable with OpenSSL. */ typedef struct WOLFSSL_RSA { -#ifdef WC_RSA_BLINDING - WC_RNG* rng; /* for PrivateDecrypt blinding */ -#endif - WOLFSSL_BIGNUM* n; - WOLFSSL_BIGNUM* e; - WOLFSSL_BIGNUM* d; - WOLFSSL_BIGNUM* p; - WOLFSSL_BIGNUM* q; - WOLFSSL_BIGNUM* dmp1; /* dP */ - WOLFSSL_BIGNUM* dmq1; /* dQ */ - WOLFSSL_BIGNUM* iqmp; /* u */ - void* heap; - void* internal; /* our RSA */ + WOLFSSL_BIGNUM* n; /* Modulus. */ + WOLFSSL_BIGNUM* e; /* Public exponent. */ + WOLFSSL_BIGNUM* d; /* Private exponent. */ + WOLFSSL_BIGNUM* p; /* First prime. */ + WOLFSSL_BIGNUM* q; /* Second prime. */ + WOLFSSL_BIGNUM* dmp1; /* dP = d mod (p - 1) */ + WOLFSSL_BIGNUM* dmq1; /* dQ = d mod (q - 1) */ + WOLFSSL_BIGNUM* iqmp; /* u = (1 / q) mod p */ + void* heap; /* Heap used for memory allocations. */ + void* internal; /* wolfCrypt RSA key. */ #if defined(OPENSSL_EXTRA) - WOLFSSL_RSA_METHOD* meth; + const WOLFSSL_RSA_METHOD* meth; /* RSA method. */ #endif #ifdef HAVE_EX_DATA WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data */ #endif -#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* ref count mutex */ -#endif - int refCount; /* reference count */ -#endif - word16 pkcs8HeaderSz; + wolfSSL_Ref ref; /* Reference count information. */ + word16 pkcs8HeaderSz; /* Size of PKCS#8 header from decode. */ + int flags; /* Flags of implementation. */ /* bits */ - byte inSet:1; /* internal set from external ? */ - byte exSet:1; /* external set from internal ? */ - byte ownRng:1; /* flag for if the rng should be free'd */ + byte inSet:1; /* Internal set from external. */ + byte exSet:1; /* External set from internal. */ + byte ownRng:1; /* Rng needs to be free'd. */ } WOLFSSL_RSA; #endif diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 847d1433e..9561a9192 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -275,6 +275,47 @@ #endif /* USE_WINDOWS_API */ #endif /* SINGLE_THREADED */ +/* Reference counting. */ +typedef struct wolfSSL_Ref { +/* TODO: use atomic operations instead of mutex. */ +#ifndef SINGLE_THREADED + wolfSSL_Mutex mutex; +#endif + int count; +} wolfSSL_Ref; + +#ifdef SINGLE_THREADED +#define wolfSSL_RefInit(ref, err) \ + do { \ + (ref)->count = 1; \ + *(err) = 0; \ + } \ + while (0) + +#define wolfSSL_RefFree(ref) + +#define wolfSSL_RefInc(ref, err) \ + do { \ + (ref)->count++; \ + *(err) = 0; \ + } \ + while (0) + +#define wolfSSL_RefDec(ref, isZero, err) \ + do { \ + (ref)->count--; \ + *(isZero) = ((ref)->count == 0); \ + *(err) = 0; \ + } \ + while (0) +#else +WOLFSSL_LOCAL void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err); +WOLFSSL_LOCAL void wolfSSL_RefFree(wolfSSL_Ref* ref); +WOLFSSL_LOCAL void wolfSSL_RefInc(wolfSSL_Ref* ref, int* err); +WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err); +#endif + + /* Enable crypt HW mutex for Freescale MMCAU, PIC32MZ or STM32 */ #if defined(FREESCALE_MMCAU) || defined(WOLFSSL_MICROCHIP_PIC32MZ) || \ defined(STM32_CRYPTO) || defined(STM32_HASH) || defined(STM32_RNG)