Fix NULL deference when validating FFC public key.
authorslontis <shane.lontis@oracle.com>
Wed, 11 Jan 2023 01:05:04 +0000 (11:05 +1000)
committerTomas Mraz <tomas@openssl.org>
Fri, 3 Feb 2023 11:38:44 +0000 (12:38 +0100)
Fixes CVE-2023-0217

When attempting to do a BN_Copy of params->p there was no NULL check.
Since BN_copy does not check for NULL this is a NULL reference.

As an aside BN_cmp() does do a NULL check, so there are other checks
that fail because a NULL is passed. A more general check for NULL params
has been added for both FFC public and private key validation instead.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
crypto/ffc/ffc_key_validate.c
include/internal/ffc.h
test/ffc_internal_test.c

index 9f6525a2c87c198119a2e2c05f30019db5197781..442303e4b334f7abd4b70e97cd50c71471f64efd 100644 (file)
@@ -24,6 +24,11 @@ int ossl_ffc_validate_public_key_partial(const FFC_PARAMS *params,
     BN_CTX *ctx = NULL;
 
     *ret = 0;
+    if (params == NULL || pub_key == NULL || params->p == NULL) {
+        *ret = FFC_ERROR_PASSED_NULL_PARAM;
+        return 0;
+    }
+
     ctx = BN_CTX_new_ex(NULL);
     if (ctx == NULL)
         goto err;
@@ -107,6 +112,10 @@ int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv,
 
     *ret = 0;
 
+    if (priv == NULL || upper == NULL) {
+        *ret = FFC_ERROR_PASSED_NULL_PARAM;
+        goto err;
+    }
     if (BN_cmp(priv, BN_value_one()) < 0) {
         *ret |= FFC_ERROR_PRIVKEY_TOO_SMALL;
         goto err;
index 732514a6c254c836f460f4fb9fe5b974d18b001b..b8b71408571177d710a7f634ce292ac28c8f884e 100644 (file)
@@ -76,6 +76,7 @@
 # define FFC_ERROR_NOT_SUITABLE_GENERATOR 0x08
 # define FFC_ERROR_PRIVKEY_TOO_SMALL      0x10
 # define FFC_ERROR_PRIVKEY_TOO_LARGE      0x20
+# define FFC_ERROR_PASSED_NULL_PARAM      0x40
 
 /*
  * Finite field cryptography (FFC) domain parameters are used by DH and DSA.
index 2c9729357398b11e75d5cdccdd45b5456da7e75c..9f67bd29b917f7cbee984800ab5633c70bf5104e 100644 (file)
@@ -510,6 +510,27 @@ static int ffc_public_validate_test(void)
     if (!TEST_true(ossl_ffc_validate_public_key(params, pub, &res)))
         goto err;
 
+    /* Fail if params is NULL */
+    if (!TEST_false(ossl_ffc_validate_public_key(NULL, pub, &res)))
+        goto err;
+    if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+        goto err;
+    res = -1;
+    /* Fail if pubkey is NULL */
+    if (!TEST_false(ossl_ffc_validate_public_key(params, NULL, &res)))
+        goto err;
+    if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+        goto err;
+    res = -1;
+
+    BN_free(params->p);
+    params->p = NULL;
+    /* Fail if params->p is NULL */
+    if (!TEST_false(ossl_ffc_validate_public_key(params, pub, &res)))
+        goto err;
+    if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+        goto err;
+
     ret = 1;
 err:
     DH_free(dh);
@@ -567,6 +588,16 @@ static int ffc_private_validate_test(void)
     if (!TEST_true(ossl_ffc_validate_private_key(params->q, priv, &res)))
         goto err;
 
+    if (!TEST_false(ossl_ffc_validate_private_key(NULL, priv, &res)))
+        goto err;
+    if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+        goto err;
+    res = -1;
+    if (!TEST_false(ossl_ffc_validate_private_key(params->q, NULL, &res)))
+        goto err;
+    if (!TEST_int_eq(FFC_ERROR_PASSED_NULL_PARAM, res))
+        goto err;
+
     ret = 1;
 err:
     DH_free(dh);