Fix limit checks in RSA padding functions.
More signed/unsigned issues, and some other missing checks.
Change-Id: Ib64429a609ca2d64b74a4744092aac67ad0af4e5
Reviewed-on: https://boringssl-review.googlesource.com/1252
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/rsa/padding.c b/crypto/rsa/padding.c
index c09bb3c..aa0a303 100644
--- a/crypto/rsa/padding.c
+++ b/crypto/rsa/padding.c
@@ -70,7 +70,13 @@
unsigned j;
uint8_t *p;
- if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) {
+ if (tlen < RSA_PKCS1_PADDING_SIZE) {
+ OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
+ RSA_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+
+ if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
@@ -95,9 +101,9 @@
unsigned i, j;
const uint8_t *p;
- if (flen == 0) {
+ if (flen < 2) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_EMPTY_PUBLIC_KEY);
+ RSA_R_DATA_TOO_SMALL);
return -1;
}
@@ -111,8 +117,8 @@
/* scan over padding data */
j = flen - 2; /* one for leading 00, one for type. */
for (i = 0; i < j; i++) {
- if (*p != 0xff) /* should decrypt to 0xff */
- {
+ /* should decrypt to 0xff */
+ if (*p != 0xff) {
if (*p == 0) {
p++;
break;
@@ -153,7 +159,13 @@
unsigned i, j;
uint8_t *p;
- if (flen > (tlen - 11)) {
+ if (tlen < RSA_PKCS1_PADDING_SIZE) {
+ OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
+ RSA_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+
+ if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
@@ -172,12 +184,10 @@
}
for (i = 0; i < j; i++) {
- if (*p == 0) {
- do {
- if (RAND_pseudo_bytes(p, 1) <= 0) {
- return 0;
- }
- } while (*p == 0);
+ while (*p == 0) {
+ if (RAND_pseudo_bytes(p, 1) <= 0) {
+ return 0;
+ }
}
p++;
}
@@ -226,7 +236,7 @@
/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
* Standard", section 7.2.2. */
- if (flen < 11) {
+ if (flen < RSA_PKCS1_PADDING_SIZE) {
goto err;
}
@@ -296,7 +306,13 @@
unsigned i, j;
uint8_t *p;
- if (flen > (tlen - 11)) {
+ if (tlen < RSA_PKCS1_PADDING_SIZE) {
+ OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
+ RSA_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+
+ if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_add_SSLv23,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
@@ -315,11 +331,9 @@
}
for (i = 0; i < j; i++) {
- if (*p == '\0') {
- do {
- if (RAND_pseudo_bytes(p, 1) <= 0)
- return 0;
- } while (*p == '\0');
+ while (*p == '\0') {
+ if (RAND_pseudo_bytes(p, 1) <= 0)
+ return 0;
}
p++;
}
@@ -334,7 +348,8 @@
int RSA_padding_check_SSLv23(uint8_t *to, unsigned tlen, const uint8_t *from,
unsigned flen) {
- unsigned i, j, k;
+ unsigned i, j;
+ int k;
const uint8_t *p;
p = from;
@@ -356,7 +371,7 @@
}
}
- if ((i == j) || (i < 8)) {
+ if (i == j || i < 8) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_check_SSLv23,
RSA_R_NULL_BEFORE_BLOCK_MISSING);
return -1;
@@ -380,7 +395,7 @@
OPENSSL_PUT_ERROR(RSA, RSA_padding_check_SSLv23, RSA_R_DATA_TOO_LARGE);
return -1;
}
- memcpy(to, p, (unsigned int)j);
+ memcpy(to, p, j);
return j;
}
@@ -432,7 +447,7 @@
const uint8_t *from, unsigned flen,
const uint8_t *param, unsigned plen,
const EVP_MD *md, const EVP_MD *mgf1md) {
- unsigned i, emlen = tlen - 1, mdlen;
+ unsigned i, emlen, mdlen;
uint8_t *db, *seed;
uint8_t *dbmask = NULL, seedmask[SHA_DIGEST_LENGTH];
int ret = 0;
@@ -446,6 +461,13 @@
mdlen = EVP_MD_size(md);
+ if (tlen < 2 * mdlen + 2) {
+ OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
+ RSA_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+
+ emlen = tlen - 1;
if (flen > emlen - 2 * mdlen - 1) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
@@ -742,6 +764,12 @@
goto err;
}
+ if (BN_is_zero(rsa->n)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
+ RSA_R_EMPTY_PUBLIC_KEY);
+ goto err;
+ }
+
MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
emLen = RSA_size(rsa);
if (MSBits == 0) {
@@ -749,8 +777,13 @@
emLen--;
}
if (sLen == -2) {
+ if (emLen < hLen + 2) {
+ OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ goto err;
+ }
sLen = emLen - hLen - 2;
- } else if (emLen < (hLen + sLen + 2)) {
+ } else if (emLen < hLen + sLen + 2) {
OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;