Search
j0ke.net Open Build Service
>
Projects
>
home:netmax
:
monitoring
>
openssl1
> openssl-switch-to-BN_bn2binpad.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File openssl-switch-to-BN_bn2binpad.patch of Package openssl1
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);