Modify DSA and DH keys to use a shared FFC_PARAMS struct
[oweals/openssl.git] / crypto / rsa / rsa_chk.c
index 4cf682258b314622f03714ef3fc2a7ba8f3e1f2d..9d8049132b82f2e12a9cdf4c23be310fff441c91 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
  *
- * Licensed under the OpenSSL license (the "License").  You may not use
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
@@ -9,15 +9,26 @@
 
 #include <openssl/bn.h>
 #include <openssl/err.h>
-#include "rsa_locl.h"
+#include "rsa_local.h"
 
 int RSA_check_key(const RSA *key)
 {
     return RSA_check_key_ex(key, NULL);
 }
 
+/*
+ * NOTE: Key validation requires separate checks to be able to be accessed
+ *  individually. These should be visible from the PKEY API..
+ *  See rsa_sp800_56b_check_public, rsa_sp800_56b_check_private and
+ *      rsa_sp800_56b_check_keypair.
+ */
 int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
 {
+#ifdef FIPS_MODE
+    return rsa_sp800_56b_check_public(key)
+               && rsa_sp800_56b_check_private(key)
+               && rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key));
+#else
     BIGNUM *i, *j, *k, *l, *m;
     BN_CTX *ctx;
     int ret = 1, ex_primes = 0, idx;
@@ -30,10 +41,13 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
     }
 
     /* multi-prime? */
-    if (key->version == RSA_ASN1_VERSION_MULTI
-        && (ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos)) <= 0) {
-        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY);
-        return 0;
+    if (key->version == RSA_ASN1_VERSION_MULTI) {
+        ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos);
+        if (ex_primes <= 0
+                || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) {
+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY);
+            return 0;
+        }
     }
 
     i = BN_new();
@@ -59,13 +73,13 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
     }
 
     /* p prime? */
-    if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) {
+    if (BN_check_prime(key->p, NULL, cb) != 1) {
         ret = 0;
         RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME);
     }
 
     /* q prime? */
-    if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) {
+    if (BN_check_prime(key->q, NULL, cb) != 1) {
         ret = 0;
         RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME);
     }
@@ -73,7 +87,7 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
     /* r_i prime? */
     for (idx = 0; idx < ex_primes; idx++) {
         pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx);
-        if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) {
+        if (BN_check_prime(pinfo->r, NULL, cb) != 1) {
             ret = 0;
             RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME);
         }
@@ -222,4 +236,5 @@ int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
     BN_free(m);
     BN_CTX_free(ctx);
     return ret;
+#endif /* FIPS_MODE */
 }