diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index ef92b00ef..507f212b0 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3254,7 +3254,7 @@ int wc_ecc_sig_size(ecc_key* key) if (sz <= 0) return sz; - return sz * 2 + SIG_HEADER_SZ + 4; /* (4) worst case estimate */ + return (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ; } diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index b8339eec0..36271c3cc 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -361,6 +361,9 @@ const char* wc_GetErrorString(int error) case WC_INIT_E: return "wolfCrypt Initialize Failure error"; + case SIG_VERIFY_E: + return "Signature verify error"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 95a54f7be..86dd1953d 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -41,9 +41,9 @@ /* Get Hash digest size */ -word32 wc_HashGetDigestSize(enum wc_HashType hash_type) +int wc_HashGetDigestSize(enum wc_HashType hash_type) { - word32 dig_size = 0; + int dig_size = BAD_FUNC_ARG; switch(hash_type) { #ifdef WOLFSSL_MD2 @@ -93,7 +93,7 @@ word32 wc_HashGetDigestSize(enum wc_HashType hash_type) int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len) { - int ret = 0; + int ret = BAD_FUNC_ARG; word32 dig_size; /* Validate hash buffer size */ @@ -142,6 +142,7 @@ int wc_Hash(enum wc_HashType hash_type, const byte* data, case WC_HASH_TYPE_NONE: default: + WOLFSSL_MSG("wc_Hash: Bad hash type"); break; } return ret; diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index d3a5799fa..d069e3491 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_ECC #include @@ -34,29 +35,34 @@ #include #endif +#ifndef NO_SIG_WRAPPER -word32 wc_SignatureGetSize(enum wc_SignatureType sig_type, +int wc_SignatureGetSize(enum wc_SignatureType sig_type, const void* key, word32 key_len) { - word32 sig_len = 0; + int sig_len = BAD_FUNC_ARG; switch(sig_type) { #ifdef HAVE_ECC case WC_SIGNATURE_TYPE_ECC: { - if (key_len < sizeof(ecc_key)) { - return BAD_FUNC_ARG; + if (key_len >= sizeof(ecc_key)) { + sig_len = wc_ecc_sig_size((ecc_key*)key); + } + else { + WOLFSSL_MSG("wc_SignatureGetSize: Invalid ECC key size"); } - sig_len = wc_ecc_sig_size((ecc_key*)key); break; } #endif #ifndef NO_RSA case WC_SIGNATURE_TYPE_RSA: - if (key_len < sizeof(RsaKey)) { - return BAD_FUNC_ARG; + if (key_len >= sizeof(RsaKey)) { + sig_len = wc_RsaEncryptSize((RsaKey*)key); + } + else { + WOLFSSL_MSG("wc_SignatureGetSize: Invalid RsaKey key size"); } - sig_len = wc_RsaEncryptSize((RsaKey*)key); break; #endif @@ -76,9 +82,22 @@ int wc_SignatureVerify( int ret, hash_len; byte *hash_data = NULL; + /* Check arguments */ + if (data == NULL || data_len <= 0 || sig == NULL || sig_len <= 0 || + key == NULL || key_len <= 0) { + return BAD_FUNC_ARG; + } + + /* Validate signature len (1 to max is okay) */ + if ((int)sig_len > wc_SignatureGetSize(sig_type, key, key_len)) { + WOLFSSL_MSG("wc_SignatureVerify: Invalid sig type/len"); + return BAD_FUNC_ARG; + } + /* Validate hash size */ hash_len = wc_HashGetDigestSize(hash_type); if (hash_len <= 0) { + WOLFSSL_MSG("wc_SignatureVerify: Invalid hash type/len"); return BAD_FUNC_ARG; } @@ -90,49 +109,55 @@ int wc_SignatureVerify( /* Perform hash of data */ ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); - if(ret != 0) { - goto exit; - } + if(ret == 0) { + /* Default to bad argument */ + ret = BAD_FUNC_ARG; - /* Verify signature using hash as data */ - switch(sig_type) { + /* Verify signature using hash as data */ + switch(sig_type) { #ifdef HAVE_ECC - case WC_SIGNATURE_TYPE_ECC: - { - int is_valid_sig = -1; + case WC_SIGNATURE_TYPE_ECC: + { - /* Validate key size */ - if (key_len < sizeof(ecc_key)) { - return BAD_FUNC_ARG; + int is_valid_sig = 0; + + /* Perform verification of signature using provided ECC key */ + ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, &is_valid_sig, (ecc_key*)key); + if (ret != 0 || is_valid_sig != 1) { + ret = SIG_VERIFY_E; + } + break; } - /* Perform verification of signature using provided ECC key */ - ret = wc_ecc_verify_hash(sig, sig_len, hash_data, hash_len, &is_valid_sig, (ecc_key*)key); - if (ret != 0 || is_valid_sig != 1) { - ret = -1; - } - break; - } #endif #ifndef NO_RSA - case WC_SIGNATURE_TYPE_RSA: - /* Validate key size */ - if (key_len < sizeof(ecc_key)) { - return BAD_FUNC_ARG; + case WC_SIGNATURE_TYPE_RSA: + { + byte *plain_data = XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (plain_data) { + /* Perform verification of signature using provided RSA key */ + ret = wc_RsaSSL_Verify(sig, sig_len, plain_data, hash_len, (RsaKey*)key); + if (ret != hash_len || XMEMCMP(plain_data, hash_data, hash_len) != 0) { + ret = SIG_VERIFY_E; + } + XFREE(plain_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + ret = MEMORY_E; + } + break; } - /* Perform verification of signature using provided RSA key */ - ret = wc_RsaSSL_Verify(sig, sig_len, hash_data, hash_len, (RsaKey*)key); - break; #endif - case WC_SIGNATURE_TYPE_NONE: - default: - break; + case WC_SIGNATURE_TYPE_NONE: + default: + break; + } } -exit: if (hash_data) { XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); } + return ret; } @@ -145,9 +170,22 @@ int wc_SignatureGenerate( int ret, hash_len; byte *hash_data = NULL; + /* Check arguments */ + if (data == NULL || data_len <= 0 || sig == NULL || sig_len == NULL || + *sig_len <= 0 || key == NULL || key_len <= 0) { + return BAD_FUNC_ARG; + } + + /* Validate signature len (needs to be at least max) */ + if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { + WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); + return BAD_FUNC_ARG; + } + /* Validate hash size */ hash_len = wc_HashGetDigestSize(hash_type); if (hash_len <= 0) { + WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); return BAD_FUNC_ARG; } @@ -159,46 +197,41 @@ int wc_SignatureGenerate( /* Perform hash of data */ ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); - if (ret != 0) { - goto exit; - } + if (ret == 0) { + /* Default to bad argument */ + ret = BAD_FUNC_ARG; - /* Create signature using hash as data */ - switch(sig_type) { + /* Create signature using hash as data */ + switch(sig_type) { #ifdef HAVE_ECC - case WC_SIGNATURE_TYPE_ECC: - { - /* Validate key size */ - if (key_len < sizeof(ecc_key)) { - return BAD_FUNC_ARG; + case WC_SIGNATURE_TYPE_ECC: + { + /* Create signature using provided ECC key */ + ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, rng, (ecc_key*)key); + break; } - /* Create signature using provided ECC key */ - ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, rng, (ecc_key*)key); - break; - } #endif #ifndef NO_RSA - case WC_SIGNATURE_TYPE_RSA: - /* Validate key size */ - if (key_len < sizeof(RsaKey)) { - return BAD_FUNC_ARG; - } - /* Create signature using provided RSA key */ - ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, (RsaKey*)key, rng); - if (ret > 0) { - *sig_len = ret; - } - break; + case WC_SIGNATURE_TYPE_RSA: + /* Create signature using provided RSA key */ + ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, (RsaKey*)key, rng); + if (ret > 0) { + *sig_len = ret; + } + break; #endif - case WC_SIGNATURE_TYPE_NONE: - default: - break; + case WC_SIGNATURE_TYPE_NONE: + default: + break; + } } -exit: if (hash_data) { XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); } + return ret; } + +#endif /* NO_SIG_WRAPPER */ diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 6abbf38c7..880b36237 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -41,7 +41,8 @@ enum { ECC_BUFSIZE = 256, /* for exported keys temp buffer */ ECC_MINSIZE = 20, /* MIN Private Key size */ ECC_MAXSIZE = 66, /* MAX Private Key size */ - ECC_MAXSIZE_GEN = 74 /* MAX Buffer size required when generating ECC keys*/ + ECC_MAXSIZE_GEN = 74, /* MAX Buffer size required when generating ECC keys*/ + ECC_MAX_PAD_SZ = 4 /* ECC maximum padding size */ }; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index b26f6c3f7..adf2d96b3 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -162,6 +162,7 @@ enum { CERTPOLICIES_E = -227, /* setting Certificate Policies error */ WC_INIT_E = -228, /* wolfcrypt failed to initialize */ + SIG_VERIFY_E = -229, /* wolfcrypt signature verify error */ MIN_CODE_E = -300 /* errors -101 - -299 */ }; diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index c25faf313..2a96f4e55 100755 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -54,7 +54,7 @@ enum wc_HashType { #endif /* WOLFSSL_SHA512 */ }; -WOLFSSL_API word32 wc_HashGetDigestSize(enum wc_HashType hash_type); +WOLFSSL_API int wc_HashGetDigestSize(enum wc_HashType hash_type); WOLFSSL_API int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len); diff --git a/wolfssl/wolfcrypt/signature.h b/wolfssl/wolfcrypt/signature.h index f3bb30352..24d2b3a67 100644 --- a/wolfssl/wolfcrypt/signature.h +++ b/wolfssl/wolfcrypt/signature.h @@ -40,7 +40,7 @@ enum wc_SignatureType { #endif }; -WOLFSSL_API word32 wc_SignatureGetSize(enum wc_SignatureType sig_type, +WOLFSSL_API int wc_SignatureGetSize(enum wc_SignatureType sig_type, const void* key, word32 key_len); WOLFSSL_API int wc_SignatureVerify(