summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/freebl/rsapkcs.c
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-12-17 14:12:04 +0100
committerwolfbeast <mcwerewolf@gmail.com>2018-12-17 14:12:04 +0100
commit51b821b3fdc5a7eab2369cb6a6680598a6264b08 (patch)
treef3608a518bbb9e31b0a42b9a10742fb11ef5b39b /security/nss/lib/freebl/rsapkcs.c
parent8e44bbb43789e585fab9fc1ce8becc94b45d566c (diff)
parent680c3eadb6aaec1f3653636db081a519e0f62ef5 (diff)
downloadUXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar
UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar.gz
UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar.lz
UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar.xz
UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.zip
Merge branch 'master' into Sync-weave
Diffstat (limited to 'security/nss/lib/freebl/rsapkcs.c')
-rw-r--r--security/nss/lib/freebl/rsapkcs.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/security/nss/lib/freebl/rsapkcs.c b/security/nss/lib/freebl/rsapkcs.c
index ad18c8b73..875e4e28d 100644
--- a/security/nss/lib/freebl/rsapkcs.c
+++ b/security/nss/lib/freebl/rsapkcs.c
@@ -938,48 +938,56 @@ RSA_DecryptBlock(RSAPrivateKey *key,
const unsigned char *input,
unsigned int inputLen)
{
- SECStatus rv;
+ PRInt8 rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
- unsigned char *buffer;
+ unsigned char *buffer = NULL;
+ unsigned int outLen = 0;
+ unsigned int copyOutLen = modulusLen - 11;
- if (inputLen != modulusLen)
- goto failure;
+ if (inputLen != modulusLen || modulusLen < 10) {
+ return SECFailure;
+ }
- buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
- if (!buffer)
- goto failure;
+ if (copyOutLen > maxOutputLen) {
+ copyOutLen = maxOutputLen;
+ }
- rv = RSA_PrivateKeyOp(key, buffer, input);
- if (rv != SECSuccess)
- goto loser;
+ // Allocate enough space to decrypt + copyOutLen to allow copying outLen later.
+ buffer = PORT_ZAlloc(modulusLen + 1 + copyOutLen);
+ if (!buffer) {
+ return SECFailure;
+ }
- /* XXX(rsleevi): Constant time */
- if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
- buffer[1] != (unsigned char)RSA_BlockPublic) {
- goto loser;
+ // rv is 0 if everything is going well and 1 if an error occurs.
+ rv = RSA_PrivateKeyOp(key, buffer, input) != SECSuccess;
+ rv |= (buffer[0] != RSA_BLOCK_FIRST_OCTET) |
+ (buffer[1] != (unsigned char)RSA_BlockPublic);
+
+ // There have to be at least 8 bytes of padding.
+ for (i = 2; i < 10; i++) {
+ rv |= buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET;
}
- *outputLen = 0;
- for (i = 2; i < modulusLen; i++) {
- if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
- *outputLen = modulusLen - i - 1;
- break;
- }
+
+ for (i = 10; i < modulusLen; i++) {
+ unsigned int newLen = modulusLen - i - 1;
+ unsigned int c = (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) & (outLen == 0);
+ outLen = constantTimeCondition(c, newLen, outLen);
}
- if (*outputLen == 0)
- goto loser;
- if (*outputLen > maxOutputLen)
- goto loser;
+ rv |= outLen == 0;
+ rv |= outLen > maxOutputLen;
- PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen);
+ // Note that output is set even if SECFailure is returned.
+ PORT_Memcpy(output, buffer + modulusLen - outLen, copyOutLen);
+ *outputLen = constantTimeCondition(outLen > maxOutputLen, maxOutputLen,
+ outLen);
PORT_Free(buffer);
- return SECSuccess;
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
+ for (i = 1; i < sizeof(rv) * 8; i <<= 1) {
+ rv |= rv << i;
+ }
+ return (SECStatus)rv;
}
/*