* 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);
}
/*
* 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;
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;
/* 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;
}
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;
}
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)
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;
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);