Use RAND_bytes_ex in crypto/rsa
[oweals/openssl.git] / crypto / rsa / rsa_oaep.c
index 0945d4f60d2bebfa358c2499ce1135e862be6b93..ed486acbe651fb23eeb1bdad45e94295574b8ac9 100644 (file)
  * one-wayness.  For the RSA function, this is an equivalent notion.
  */
 
-#include "internal/constant_time_locl.h"
+/*
+ * RSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
+#include "internal/constant_time.h"
 
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/sha.h>
-#include "rsa_locl.h"
+#include "rsa_local.h"
 
 int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
                                const unsigned char *from, int flen,
                                const unsigned char *param, int plen)
 {
-    return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
-                                           param, plen, NULL, NULL);
+    return rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(NULL, to, tlen, from,
+                                                       flen, param, plen, NULL,
+                                                       NULL);
 }
 
 /*
@@ -45,10 +52,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
  * Step numbers are included here but not in the constant time inverse below
  * to avoid complicating an already difficult enough function.
  */
-int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
-                                    const unsigned char *from, int flen,
-                                    const unsigned char *param, int plen,
-                                    const EVP_MD *md, const EVP_MD *mgf1md)
+int rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(OPENSSL_CTX *libctx,
+                                                unsigned char *to, int tlen,
+                                                const unsigned char *from,
+                                                int flen,
+                                                const unsigned char *param,
+                                                int plen, const EVP_MD *md,
+                                                const EVP_MD *mgf1md)
 {
     int rv = 0;
     int i, emlen = tlen - 1;
@@ -57,8 +67,13 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
     unsigned char seedmask[EVP_MAX_MD_SIZE];
     int mdlen, dbmask_len = 0;
 
+#ifndef FIPS_MODE
     if (md == NULL)
         md = EVP_sha1();
+#else
+        RSAerr(0, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+#endif
     if (mgf1md == NULL)
         mgf1md = md;
 
@@ -66,14 +81,12 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
 
     /* step 2b: check KLen > nLen - 2 HLen - 2 */
     if (flen > emlen - 2 * mdlen - 1) {
-        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
-               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        RSAerr(0, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
         return 0;
     }
 
     if (emlen < 2 * mdlen + 1) {
-        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
-               RSA_R_KEY_SIZE_TOO_SMALL);
+        RSAerr(0, RSA_R_KEY_SIZE_TOO_SMALL);
         return 0;
     }
 
@@ -91,13 +104,13 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
     db[emlen - flen - mdlen - 1] = 0x01;
     memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
     /* step 3d: generate random byte string */
-    if (RAND_bytes(seed, mdlen) <= 0)
+    if (RAND_bytes_ex(libctx, seed, mdlen) <= 0)
         goto err;
 
     dbmask_len = emlen - mdlen;
     dbmask = OPENSSL_malloc(dbmask_len);
     if (dbmask == NULL) {
-        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+        RSAerr(0, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
@@ -122,6 +135,16 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
     return rv;
 }
 
+int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+                                    const unsigned char *from, int flen,
+                                    const unsigned char *param, int plen,
+                                    const EVP_MD *md, const EVP_MD *mgf1md)
+{
+    return rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(NULL, to, tlen, from,
+                                                       flen, param, plen, md,
+                                                       mgf1md);
+}
+
 int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
                                  const unsigned char *from, int flen, int num,
                                  const unsigned char *param, int plen)
@@ -147,8 +170,15 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
         phash[EVP_MAX_MD_SIZE];
     int mdlen;
 
-    if (md == NULL)
+    if (md == NULL) {
+#ifndef FIPS_MODE
         md = EVP_sha1();
+#else
+        RSAerr(0, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+#endif
+    }
+
     if (mgf1md == NULL)
         mgf1md = md;
 
@@ -272,13 +302,19 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
         to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]);
     }
 
+#ifndef FIPS_MODE
     /*
      * To avoid chosen ciphertext attacks, the error message should not
      * reveal which kind of decoding error happened.
+     *
+     * This trick doesn't work in the FIPS provider because libcrypto manages
+     * the error stack. Instead we opt not to put an error on the stack at all
+     * in case of padding failure in the FIPS provider.
      */
     RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,
            RSA_R_OAEP_DECODING_ERROR);
     err_clear_last_constant_time(1 & good);
+#endif
  cleanup:
     OPENSSL_cleanse(seed, sizeof(seed));
     OPENSSL_clear_free(db, dblen);