Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@chromium.org>2015-12-02 04:32:22 +0300
committerAdam Langley <agl@google.com>2015-12-15 22:39:37 +0300
commit1634a334955ac07d4ee2c13a2efb420d4a406961 (patch)
tree926ce14ed1589f928feae6eb2919d1b8658d043d /crypto/rsa
parentb36a395a9a0bd219a7706207474ba6b7cba05a33 (diff)
Convert rsa/padding.c to constant-time helpers.
Remove the custom copy of those helpers. Change-Id: I810c3ae8dbf7bc0654d3e9fb9900c425d36f64aa Reviewed-on: https://boringssl-review.googlesource.com/6611 Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto/rsa')
-rw-r--r--crypto/rsa/padding.c65
1 files changed, 22 insertions, 43 deletions
diff --git a/crypto/rsa/padding.c b/crypto/rsa/padding.c
index 5a42e248..40542923 100644
--- a/crypto/rsa/padding.c
+++ b/crypto/rsa/padding.c
@@ -56,6 +56,7 @@
#include <openssl/rsa.h>
#include <assert.h>
+#include <limits.h>
#include <string.h>
#include <openssl/digest.h>
@@ -65,6 +66,7 @@
#include <openssl/sha.h>
#include "internal.h"
+#include "../internal.h"
/* TODO(fork): don't the check functions have to be constant time? */
@@ -191,51 +193,30 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
return 1;
}
-/* constant_time_byte_eq returns 1 if |x| == |y| and 0 otherwise. */
-static int constant_time_byte_eq(unsigned char a, unsigned char b) {
- unsigned char z = ~(a ^ b);
- z &= z >> 4;
- z &= z >> 2;
- z &= z >> 1;
-
- return z;
-}
-
-/* constant_time_select returns |x| if |v| is 1 and |y| if |v| is 0.
- * Its behavior is undefined if |v| takes any other value. */
-static int constant_time_select(int v, int x, int y) {
- return ((~(v - 1)) & x) | ((v - 1) & y);
-}
-
-/* constant_time_le returns 1 if |x| <= |y| and 0 otherwise.
- * |x| and |y| must be positive. */
-static int constant_time_le(int x, int y) {
- return ((x - y - 1) >> (sizeof(int) * 8 - 1)) & 1;
-}
-
int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
size_t *out_index) {
size_t i;
- int first_byte_is_zero, second_byte_is_two, looking_for_index;
- int valid_index, zero_index = 0;
+ unsigned first_byte_is_zero, second_byte_is_two, looking_for_index;
+ unsigned valid_index, zero_index = 0;
/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
* Standard", section 7.2.2. */
- if (from_len < RSA_PKCS1_PADDING_SIZE) {
+ if (from_len < RSA_PKCS1_PADDING_SIZE || from_len > UINT_MAX) {
/* |from| is zero-padded to the size of the RSA modulus, a public value, so
- * this can be rejected in non-constant time. */
+ * this can be rejected in non-constant time. This logic also requires
+ * |from_len| fit in an |unsigned|. */
*out_index = 0;
return 0;
}
- first_byte_is_zero = constant_time_byte_eq(from[0], 0);
- second_byte_is_two = constant_time_byte_eq(from[1], 2);
+ first_byte_is_zero = constant_time_eq(from[0], 0);
+ second_byte_is_two = constant_time_eq(from[1], 2);
- looking_for_index = 1;
+ looking_for_index = ~0u;
for (i = 2; i < from_len; i++) {
- int equals0 = constant_time_byte_eq(from[i], 0);
- zero_index =
- constant_time_select(looking_for_index & equals0, i, zero_index);
+ unsigned equals0 = constant_time_is_zero(from[i]);
+ zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i,
+ zero_index);
looking_for_index = constant_time_select(equals0, 0, looking_for_index);
}
@@ -247,13 +228,13 @@ int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
valid_index &= ~looking_for_index;
/* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
- valid_index &= constant_time_le(2 + 8, zero_index);
+ valid_index &= constant_time_ge(zero_index, 2 + 8);
/* Skip the zero byte. */
zero_index++;
*out_index = constant_time_select(valid_index, zero_index, 0);
- return valid_index;
+ return constant_time_select(valid_index, 1, 0);
}
int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
@@ -421,10 +402,9 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
const uint8_t *from, unsigned flen,
const uint8_t *param, unsigned plen,
const EVP_MD *md, const EVP_MD *mgf1md) {
- unsigned i, dblen, mlen = -1, mdlen;
+ unsigned i, dblen, mlen = -1, mdlen, bad, looking_for_one_byte, one_index;
const uint8_t *maskeddb, *maskedseed;
uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
- int bad, looking_for_one_byte, one_index = 0;
if (md == NULL) {
md = EVP_sha1();
@@ -472,15 +452,14 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
goto err;
}
- bad = CRYPTO_memcmp(db, phash, mdlen);
- bad |= from[0];
+ bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
+ bad |= ~constant_time_is_zero(from[0]);
- looking_for_one_byte = 1;
+ looking_for_one_byte = ~0u;
for (i = mdlen; i < dblen; i++) {
- int equals1 = constant_time_byte_eq(db[i], 1);
- int equals0 = constant_time_byte_eq(db[i], 0);
- one_index =
- constant_time_select(looking_for_one_byte & equals1, i, one_index);
+ unsigned equals1 = constant_time_eq(db[i], 1);
+ unsigned equals0 = constant_time_eq(db[i], 0);
+ one_index = constant_time_select(looking_for_one_byte & equals1, i, one_index);
looking_for_one_byte =
constant_time_select(equals1, 0, looking_for_one_byte);
bad |= looking_for_one_byte & ~equals0;