File openssl-switch-to-BN_bn2binpad.patch of Package openssl.11276

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-1.0.1i/crypto/rsa/rsa_eay.c
===================================================================
--- openssl-1.0.1i.orig/crypto/rsa/rsa_eay.c
+++ openssl-1.0.1i/crypto/rsa/rsa_eay.c
@@ -158,7 +158,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;
 
@@ -252,14 +252,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)
 		{
@@ -373,7 +370,7 @@ static int RSA_eay_private_encrypt(int f
 	     unsigned char *to, RSA *rsa, int padding)
 	{
 	BIGNUM *f, *ret, *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;
@@ -507,14 +504,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)
 		{
@@ -534,7 +528,6 @@ static int RSA_eay_private_decrypt(int f
 	{
 	BIGNUM *f, *ret;
 	int j,num=0,r= -1;
-	unsigned char *p;
 	unsigned char *buf=NULL;
 	BN_CTX *ctx=NULL;
 	int local_blinding = 0;
@@ -647,8 +640,7 @@ static int RSA_eay_private_decrypt(int f
 		if (!rsa_blinding_invert(blinding, ret, unblind, 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)
 		{
@@ -664,7 +656,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);
@@ -693,7 +685,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;
 
@@ -775,8 +766,7 @@ static int RSA_eay_public_decrypt(int fl
 	if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
 		if (!BN_sub(ret, rsa->n, ret)) goto err;
 
-	p=buf;
-	i=BN_bn2bin(ret,p);
+	i = bn_bn2binpad(ret, buf, num);
 
 	switch (padding)
 		{
@@ -787,7 +777,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-1.0.1i/crypto/rsa/rsa_oaep.c
===================================================================
--- openssl-1.0.1i.orig/crypto/rsa/rsa_oaep.c
+++ openssl-1.0.1i/crypto/rsa/rsa_oaep.c
@@ -151,33 +151,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-1.0.1i/crypto/rsa/rsa_pk1.c
===================================================================
--- openssl-1.0.1i.orig/crypto/rsa/rsa_pk1.c
+++ openssl-1.0.1i/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-1.0.1i/crypto/rsa/rsa_ssl.c
===================================================================
--- openssl-1.0.1i.orig/crypto/rsa/rsa_ssl.c
+++ openssl-1.0.1i/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);
openSUSE Build Service is sponsored by