File openssl-switch-to-BN_bn2binpad.patch of Package compat-openssl098.16428
From ec3f996b3066ecaaec87ba5ad29c606aeac0740d Mon Sep 17 00:00:00 2001
From: Andy Polyakov <appro@openssl.org>
Date: Sun, 4 Feb 2018 15:24:54 +0100
Subject: [PATCH] rsa/*: switch to BN_bn2binpad.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6889)
(cherry picked from commit 582ad5d4d9b7703eb089016935133e3a18ea8205)
Resolved conflicts:
crypto/rsa/rsa_ossl.c
crypto/rsa/rsa_pk1.c
---
crypto/rsa/rsa_eay.c | 39 +++++++++------------------
crypto/rsa/rsa_oaep.c | 39 ++++++++++++++++-----------
crypto/rsa/rsa_pk1.c | 62 ++++++++++++++++++++++++++++++-------------
crypto/rsa/rsa_ssl.c | 8 ++++++
4 files changed, 88 insertions(+), 60 deletions(-)
Index: openssl-0.9.8j/crypto/rsa/rsa_eay.c
===================================================================
--- openssl-0.9.8j.orig/crypto/rsa/rsa_eay.c
+++ openssl-0.9.8j/crypto/rsa/rsa_eay.c
@@ -154,7 +154,7 @@ static int RSA_eay_public_encrypt(int fl
unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f,*ret;
- int i,j,k,num=0,r= -1;
+ int i, num = 0, r = -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
@@ -230,14 +230,11 @@ static int RSA_eay_public_encrypt(int fl
if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
- /* put in leading 0 bytes if the number is less than the
- * length of the modulus */
- j=BN_num_bytes(ret);
- i=BN_bn2bin(ret,&(to[num-j]));
- for (k=0; k<(num-i); k++)
- to[k]=0;
-
- r=num;
+ /*
+ * BN_bn2binpad puts in leading 0 bytes if the number is less than
+ * the length of the modulus.
+ */
+ r = bn_bn2binpad(ret, to, num);
err:
if (ctx != NULL)
{
@@ -347,7 +344,7 @@ static int RSA_eay_private_encrypt(int f
unsigned char *to, RSA *rsa, int padding)
{
BIGNUM *f, *ret, *br, *res;
- int i,j,k,num=0,r= -1;
+ int i, num = 0, r = -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
int local_blinding = 0;
@@ -453,14 +450,11 @@ static int RSA_eay_private_encrypt(int f
else
res = ret;
- /* put in leading 0 bytes if the number is less than the
- * length of the modulus */
- j=BN_num_bytes(res);
- i=BN_bn2bin(res,&(to[num-j]));
- for (k=0; k<(num-i); k++)
- to[k]=0;
-
- r=num;
+ /*
+ * BN_bn2binpad puts in leading 0 bytes if the number is less than
+ * the length of the modulus.
+ */
+ r = bn_bn2binpad(res, to, num);
err:
if (ctx != NULL)
{
@@ -480,7 +474,6 @@ static int RSA_eay_private_decrypt(int f
{
BIGNUM *f, *ret, *br;
int j,num=0,r= -1;
- unsigned char *p;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
int local_blinding = 0;
@@ -565,8 +558,7 @@ static int RSA_eay_private_decrypt(int f
if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
goto err;
- p=buf;
- j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
+ j = bn_bn2binpad(ret, buf, num);
switch (padding)
{
@@ -582,7 +574,7 @@ static int RSA_eay_private_decrypt(int f
r=RSA_padding_check_SSLv23(to,num,buf,j,num);
break;
case RSA_NO_PADDING:
- r=RSA_padding_check_none(to,num,buf,j,num);
+ memcpy(to, buf, (r = j));
break;
default:
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
@@ -611,7 +603,6 @@ static int RSA_eay_public_decrypt(int fl
{
BIGNUM *f,*ret;
int i,num=0,r= -1;
- unsigned char *p;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
@@ -675,8 +666,7 @@ static int RSA_eay_public_decrypt(int fl
if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
BN_sub(ret, rsa->n, ret);
- p=buf;
- i=BN_bn2bin(ret,p);
+ i = bn_bn2binpad(ret, buf, num);
switch (padding)
{
@@ -687,7 +677,7 @@ static int RSA_eay_public_decrypt(int fl
r=RSA_padding_check_X931(to,num,buf,i,num);
break;
case RSA_NO_PADDING:
- r=RSA_padding_check_none(to,num,buf,i,num);
+ memcpy(to, buf, (r = i));
break;
default:
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
Index: openssl-0.9.8j/crypto/rsa/rsa_oaep.c
===================================================================
--- openssl-0.9.8j.orig/crypto/rsa/rsa_oaep.c
+++ openssl-0.9.8j/crypto/rsa/rsa_oaep.c
@@ -152,33 +152,41 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(un
dblen = num - mdlen - 1;
db = OPENSSL_malloc(dblen);
- em = OPENSSL_malloc(num);
- if (db == NULL || em == NULL)
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+ if (db == NULL) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+ goto cleanup;
+ }
+
+ if (flen != num) {
+ em = OPENSSL_malloc(num);
+ if (em == NULL) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,
+ ERR_R_MALLOC_FAILURE);
goto cleanup;
- }
+ }
- /*
- * Always do this zero-padding copy (even when num == flen) to avoid
- * leaking that information. The copy still leaks some side-channel
- * information, but it's impossible to have a fixed memory access
- * pattern since we can't read out of the bounds of |from|.
- *
- * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
- */
- memset(em, 0, num);
- memcpy(em + num - flen, from, flen);
+ /*
+ * Caller is encouraged to pass zero-padded message created with
+ * BN_bn2binpad, but if it doesn't, we do this zero-padding copy
+ * to avoid leaking that information. The copy still leaks some
+ * side-channel information, but it's impossible to have a fixed
+ * memory access pattern since we can't read out of the bounds of
+ * |from|.
+ */
+ memset(em, 0, num);
+ memcpy(em + num - flen, from, flen);
+ from = em;
+ }
/*
* The first byte must be zero, however we must not leak if this is
* true. See James H. Manger, "A Chosen Ciphertext Attack on RSA
* Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
*/
- good = constant_time_is_zero(em[0]);
+ good = constant_time_is_zero(from[0]);
- maskedseed = em + 1;
- maskeddb = em + 1 + mdlen;
+ maskedseed = from + 1;
+ maskeddb = from + 1 + mdlen;
if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
goto cleanup;
Index: openssl-0.9.8j/crypto/rsa/rsa_pk1.c
===================================================================
--- openssl-0.9.8j.orig/crypto/rsa/rsa_pk1.c
+++ openssl-0.9.8j/crypto/rsa/rsa_pk1.c
@@ -97,6 +97,27 @@ int RSA_padding_check_PKCS1_type_1(unsig
const unsigned char *p;
p=from;
+
+ /*
+ * The format is
+ * 00 || 01 || PS || 00 || D
+ * PS - padding string, at least 8 bytes of FF
+ * D - data.
+ */
+
+ if (num < 11)
+ return -1;
+
+ /* Accept inputs with and without the leading 0-byte. */
+ if (num == flen) {
+ if ((*p++) != 0x00) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+ RSA_R_INVALID_PADDING);
+ return -1;
+ }
+ flen--;
+ }
+
if ((num != (flen+1)) || (*(p++) != 01))
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01);
@@ -201,36 +222,38 @@ int RSA_padding_check_PKCS1_type_2(unsig
if (num < 11)
goto err;
- em = OPENSSL_malloc(num);
- if (em == NULL)
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- memset(em, 0, num);
- /*
- * Always do this zero-padding copy (even when num == flen) to avoid
- * leaking that information. The copy still leaks some side-channel
- * information, but it's impossible to have a fixed memory access
- * pattern since we can't read out of the bounds of |from|.
- *
- * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
- */
- memcpy(em + num - flen, from, flen);
+ if (flen != num) {
+ em = OPENSSL_malloc(num);
+ if (em == NULL) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ /*
+ * Caller is encouraged to pass zero-padded message created with
+ * BN_bn2binpad, but if it doesn't, we do this zero-padding copy
+ * to avoid leaking that information. The copy still leaks some
+ * side-channel information, but it's impossible to have a fixed
+ * memory access pattern since we can't read out of the bounds of
+ * |from|.
+ */
+ memset(em, 0, num);
+ memcpy(em + num - flen, from, flen);
+ from = em;
+ }
- good = constant_time_is_zero(em[0]);
- good &= constant_time_eq(em[1], 2);
+ good = constant_time_is_zero(from[0]);
+ good &= constant_time_eq(from[1], 2);
found_zero_byte = 0;
for (i = 2; i < num; i++)
{
- unsigned int equals0 = constant_time_is_zero(em[i]);
+ unsigned int equals0 = constant_time_is_zero(from[i]);
zero_index = constant_time_select_int(~found_zero_byte & equals0, i, zero_index);
found_zero_byte |= equals0;
}
/*
- * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+ * PS must be at least 8 bytes long, and it starts two bytes into |from|.
* If we never found a 0-byte, then |zero_index| is 0 and the check
* also fails.
*/
@@ -258,7 +281,7 @@ int RSA_padding_check_PKCS1_type_2(unsig
goto err;
}
- memcpy(to, em + msg_index, mlen);
+ memcpy(to, from + msg_index, mlen);
err:
if (em != NULL)
Index: openssl-0.9.8j/crypto/rsa/rsa_ssl.c
===================================================================
--- openssl-0.9.8j.orig/crypto/rsa/rsa_ssl.c
+++ openssl-0.9.8j/crypto/rsa/rsa_ssl.c
@@ -114,6 +114,14 @@ int RSA_padding_check_SSLv23(unsigned ch
RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_DATA_TOO_SMALL);
return(-1);
}
+ /* Accept even zero-padded input */
+ if (flen == num) {
+ if (*(p++) != 0) {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02);
+ return -1;
+ }
+ flen--;
+ }
if ((num != (flen+1)) || (*(p++) != 02))
{
RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_BLOCK_TYPE_IS_NOT_02);