CVE-2019-19962: Improper Verification of Cryptographic Signature (CWE-347)
value: wolfSSL before 4.3.0 mishandles calls to wc_SignatureGenerateHash, leading to fault injection in RSA cryptography.
CWE description: The product does not verify, or incorrectly verifies, the cryptographic signature for data.
CVSS v3 base score: 7.5
Published: 2019-12-25T00:15Z
Repository: https://github.com/wolfSSL/wolfssl
Language: C
Files changed: wolfcrypt/src/signature.c, wolfssl/wolfcrypt/signature.h
Commit date: 2019-11-27 10:47:03 +1000
Commit message: Change signature generation to verify by default

Diff: diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c
index 57d327570..9256eb290 100644
--- a/wolfcrypt/src/signature.c
+++ b/wolfcrypt/src/signature.c
@@ -317,10 +317,20 @@ int wc_SignatureVerify(
 int wc_SignatureGenerateHash(
     enum wc_HashType hash_type, enum wc_SignatureType sig_type,
     const byte* hash_data, word32 hash_len,
     byte* sig, word32 *sig_len,
     const void* key, word32 key_len, WC_RNG* rng)
+{
+    return wc_SignatureGenerateHash_ex(hash_type, sig_type, hash_data, hash_len,
+        sig, sig_len, key, key_len, rng, 1);
+}
+
+int wc_SignatureGenerateHash_ex(
+    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
+    const byte* hash_data, word32 hash_len,
+    byte* sig, word32 *sig_len,
+    const void* key, word32 key_len, WC_RNG* rng, int verify)
 {
     int ret;
 
     /* Suppress possible unused arg if all signature types are disabled */
     (void)rng;
@@ -391,18 +401,33 @@ int wc_SignatureGenerateHash(
         default:
             ret = BAD_FUNC_ARG;
             break;
     }
 
+    if (ret == 0 && verify) {
+        ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data, hash_len,
+            sig, *sig_len, key, key_len);
+    }
+
     return ret;
 }
 
 int wc_SignatureGenerate(
     enum wc_HashType hash_type, enum wc_SignatureType sig_type,
     const byte* data, word32 data_len,
     byte* sig, word32 *sig_len,
     const void* key, word32 key_len, WC_RNG* rng)
+{
+    return wc_SignatureGenerate_ex(hash_type, sig_type, data, data_len, sig,
+        sig_len, key, key_len, rng, 1);
+}
+
+int wc_SignatureGenerate_ex(
+    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
+    const byte* data, word32 data_len,
+    byte* sig, word32 *sig_len,
+    const void* key, word32 key_len, WC_RNG* rng, int verify)
 {
     int ret;
     word32 hash_len, hash_enc_len;
 #ifdef WOLFSSL_SMALL_STACK
     byte *hash_data;
@@ -465,10 +490,15 @@ int wc_SignatureGenerate(
             ret = wc_SignatureGenerateHash(hash_type, sig_type,
                 hash_data, hash_enc_len, sig, sig_len, key, key_len, rng);
         }
     }
 
+    if (ret == 0 && verify) {
+        ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data,
+            hash_enc_len, sig, *sig_len, key, key_len);
+    }
+
 #ifdef WOLFSSL_SMALL_STACK
     XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 #endif
 
     return ret;
diff --git a/wolfssl/wolfcrypt/signature.h b/wolfssl/wolfcrypt/signature.h
index a0cc4ea5a..fe3b6a8e1 100644
--- a/wolfssl/wolfcrypt/signature.h
+++ b/wolfssl/wolfcrypt/signature.h
@@ -60,16 +60,27 @@ WOLFSSL_API int wc_SignatureVerify(
 WOLFSSL_API int wc_SignatureGenerateHash(
     enum wc_HashType hash_type, enum wc_SignatureType sig_type,
     const byte* hash_data, word32 hash_len,
     byte* sig, word32 *sig_len,
     const void* key, word32 key_len, WC_RNG* rng);
+WOLFSSL_API int wc_SignatureGenerateHash_ex(
+    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
+    const byte* hash_data, word32 hash_len,
+    byte* sig, word32 *sig_len,
+    const void* key, word32 key_len, WC_RNG* rng, int verify);
 WOLFSSL_API int wc_SignatureGenerate(
     enum wc_HashType hash_type, enum wc_SignatureType sig_type,
     const byte* data, word32 data_len,
     byte* sig, word32 *sig_len,
     const void* key, word32 key_len,
     WC_RNG* rng);
+WOLFSSL_API int wc_SignatureGenerate_ex(
+    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
+    const byte* data, word32 data_len,
+    byte* sig, word32 *sig_len,
+    const void* key, word32 key_len,
+    WC_RNG* rng, int verify);
 
 #ifdef __cplusplus
     } /* extern "C" */
 #endif
 

Fixed code: {
    return wc_SignatureGenerateHash_ex(hash_type, sig_type, hash_data, hash_len,
        sig, sig_len, key, key_len, rng, 1);
}

int wc_SignatureGenerateHash_ex(
    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
    const byte* hash_data, word32 hash_len,
    byte* sig, word32 *sig_len,
    const void* key, word32 key_len, WC_RNG* rng, int verify)
    if (ret == 0 && verify) {
        ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data, hash_len,
            sig, *sig_len, key, key_len);
    }

{
    return wc_SignatureGenerate_ex(hash_type, sig_type, data, data_len, sig,
        sig_len, key, key_len, rng, 1);
}

int wc_SignatureGenerate_ex(
    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
    const byte* data, word32 data_len,
    byte* sig, word32 *sig_len,
    const void* key, word32 key_len, WC_RNG* rng, int verify)
    if (ret == 0 && verify) {
        ret = wc_SignatureVerifyHash(hash_type, sig_type, hash_data,
            hash_enc_len, sig, *sig_len, key, key_len);
    }

WOLFSSL_API int wc_SignatureGenerateHash_ex(
    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
    const byte* hash_data, word32 hash_len,
    byte* sig, word32 *sig_len,
    const void* key, word32 key_len, WC_RNG* rng, int verify);
WOLFSSL_API int wc_SignatureGenerate_ex(
    enum wc_HashType hash_type, enum wc_SignatureType sig_type,
    const byte* data, word32 data_len,
    byte* sig, word32 *sig_len,
    const void* key, word32 key_len,
    WC_RNG* rng, int verify);