From 1e4884f615b20946411a74e41eb9c6aa65e2d5f3 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Thu, 24 Sep 2015 10:57:52 -0700 Subject: external/boringssl: sync with upstream. This change imports the current version of BoringSSL. The only local change now is that |BORINGSSL_201509| is defined in base.h. This allows this change to be made without (hopefully) breaking the build. This change will need https://android-review.googlesource.com/172744 to be landed afterwards to update a test. Change-Id: I6d1f463f7785a2423bd846305af91c973c326104 --- src/crypto/rsa/rsa.c | 143 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 95 insertions(+), 48 deletions(-) (limited to 'src/crypto/rsa/rsa.c') diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c index 17059b0..2f23165 100644 --- a/src/crypto/rsa/rsa.c +++ b/src/crypto/rsa/rsa.c @@ -79,7 +79,7 @@ RSA *RSA_new(void) { return RSA_new_method(NULL); } RSA *RSA_new_method(const ENGINE *engine) { RSA *rsa = (RSA *)OPENSSL_malloc(sizeof(RSA)); if (rsa == NULL) { - OPENSSL_PUT_ERROR(RSA, RSA_new_method, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -114,6 +114,18 @@ RSA *RSA_new_method(const ENGINE *engine) { return rsa; } +void RSA_additional_prime_free(RSA_additional_prime *ap) { + if (ap == NULL) { + return; + } + + BN_clear_free(ap->prime); + BN_clear_free(ap->exp); + BN_clear_free(ap->coeff); + BN_clear_free(ap->r); + OPENSSL_free(ap); +} + void RSA_free(RSA *rsa) { unsigned u; @@ -145,6 +157,10 @@ void RSA_free(RSA *rsa) { } OPENSSL_free(rsa->blindings); OPENSSL_free(rsa->blindings_inuse); + if (rsa->additional_primes != NULL) { + sk_RSA_additional_prime_pop_free(rsa->additional_primes, + RSA_additional_prime_free); + } CRYPTO_MUTEX_cleanup(&rsa->lock); OPENSSL_free(rsa); } @@ -162,6 +178,16 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { return RSA_default_method.keygen(rsa, bits, e_value, cb); } +int RSA_generate_multi_prime_key(RSA *rsa, int bits, int num_primes, + BIGNUM *e_value, BN_GENCB *cb) { + if (rsa->meth->multi_prime_keygen) { + return rsa->meth->multi_prime_keygen(rsa, bits, num_primes, e_value, cb); + } + + return RSA_default_method.multi_prime_keygen(rsa, bits, num_primes, e_value, + cb); +} + int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding) { if (rsa->meth->encrypt) { @@ -342,20 +368,15 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { }, }; -/* TODO(fork): mostly new code, needs careful review. */ - -/* pkcs1_prefixed_msg builds a PKCS#1, prefixed version of |msg| for the given - * hash function and sets |out_msg| to point to it. On successful return, - * |*out_msg| may be allocated memory and, if so, |*is_alloced| will be 1. */ -static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len, - int *is_alloced, int hash_nid, const uint8_t *msg, - size_t msg_len) { +int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, const uint8_t *msg, + size_t msg_len) { unsigned i; if (hash_nid == NID_md5_sha1) { /* Special case: SSL signature, just check the length. */ if (msg_len != SSL_SIG_LENGTH) { - OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_INVALID_MESSAGE_LENGTH); + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } @@ -378,13 +399,13 @@ static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len, signed_msg_len = prefix_len + msg_len; if (signed_msg_len < prefix_len) { - OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_TOO_LONG); + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG); return 0; } signed_msg = OPENSSL_malloc(signed_msg_len); if (!signed_msg) { - OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -398,7 +419,7 @@ static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len, return 1; } - OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_UNKNOWN_ALGORITHM_TYPE); + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } @@ -415,14 +436,14 @@ int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out, return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa); } - if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced, - hash_nid, in, in_len)) { + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, in, in_len)) { return 0; } if (rsa_size < RSA_PKCS1_PADDING_SIZE || signed_msg_len > rsa_size - RSA_PKCS1_PADDING_SIZE) { - OPENSSL_PUT_ERROR(RSA, RSA_sign, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); goto finish; } @@ -453,18 +474,18 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, } if (sig_len != rsa_size) { - OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_WRONG_SIGNATURE_LENGTH); + OPENSSL_PUT_ERROR(RSA, RSA_R_WRONG_SIGNATURE_LENGTH); return 0; } if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) { - OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_INVALID_MESSAGE_LENGTH); + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } buf = OPENSSL_malloc(rsa_size); if (!buf) { - OPENSSL_PUT_ERROR(RSA, RSA_verify, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -473,13 +494,13 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, goto out; } - if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced, - hash_nid, msg, msg_len)) { + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, msg, msg_len)) { goto out; } if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) { - OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_BAD_SIGNATURE); + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); goto out; } @@ -509,12 +530,12 @@ int RSA_check_key(const RSA *key) { } if ((key->p != NULL) != (key->q != NULL)) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); + OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); return 0; } if (!key->n || !key->e) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_VALUE_MISSING); + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } @@ -526,7 +547,7 @@ int RSA_check_key(const RSA *key) { ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -540,52 +561,74 @@ int RSA_check_key(const RSA *key) { BN_init(&dmq1); BN_init(&iqmp); - if (/* n = pq */ - !BN_mul(&n, key->p, key->q, ctx) || - /* lcm = lcm(p-1, q-1) */ + if (!BN_mul(&n, key->p, key->q, ctx) || + /* lcm = lcm(prime-1, for all primes) */ !BN_sub(&pm1, key->p, BN_value_one()) || !BN_sub(&qm1, key->q, BN_value_one()) || !BN_mul(&lcm, &pm1, &qm1, ctx) || + !BN_gcd(&gcd, &pm1, &qm1, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + size_t num_additional_primes = 0; + if (key->additional_primes != NULL) { + num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes); + } + + size_t i; + for (i = 0; i < num_additional_primes; i++) { + const RSA_additional_prime *ap = + sk_RSA_additional_prime_value(key->additional_primes, i); + if (!BN_mul(&n, &n, ap->prime, ctx) || + !BN_sub(&pm1, ap->prime, BN_value_one()) || + !BN_mul(&lcm, &lcm, &pm1, ctx) || + !BN_gcd(&gcd, &gcd, &pm1, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + } + + if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) || !BN_gcd(&gcd, &pm1, &qm1, ctx) || - !BN_div(&lcm, NULL, &lcm, &gcd, ctx) || - /* de = d*e mod lcm(p-1, q-1) */ + /* de = d*e mod lcm(prime-1, for all primes). */ !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_LIB_BN); + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } if (BN_cmp(&n, key->n) != 0) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_N_NOT_EQUAL_P_Q); + OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); goto out; } if (!BN_is_one(&de)) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_D_E_NOT_CONGRUENT_TO_1); + OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); goto out; } has_crt_values = key->dmp1 != NULL; if (has_crt_values != (key->dmq1 != NULL) || has_crt_values != (key->iqmp != NULL)) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); + OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); goto out; } - if (has_crt_values) { + if (has_crt_values && num_additional_primes == 0) { if (/* dmp1 = d mod (p-1) */ !BN_mod(&dmp1, key->d, &pm1, ctx) || /* dmq1 = d mod (q-1) */ !BN_mod(&dmq1, key->d, &qm1, ctx) || /* iqmp = q^-1 mod p */ !BN_mod_inverse(&iqmp, key->q, key->p, ctx)) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_LIB_BN); + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } if (BN_cmp(&dmp1, key->dmp1) != 0 || BN_cmp(&dmq1, key->dmq1) != 0 || BN_cmp(&iqmp, key->iqmp) != 0) { - OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_CRT_VALUES_INCORRECT); + OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT); goto out; } } @@ -613,13 +656,17 @@ int RSA_recover_crt_params(RSA *rsa) { int ok = 0; if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_EMPTY_PUBLIC_KEY); + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); return 0; } if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, - RSA_R_CRT_PARAMS_ALREADY_GIVEN); + OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN); + return 0; + } + + if (rsa->additional_primes != NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY); return 0; } @@ -628,7 +675,7 @@ int RSA_recover_crt_params(RSA *rsa) { ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } @@ -641,7 +688,7 @@ int RSA_recover_crt_params(RSA *rsa) { if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL || p_minus_q == NULL) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -669,12 +716,12 @@ int RSA_recover_crt_params(RSA *rsa) { !BN_div(multiple, NULL, totient, rsa->n, ctx) || !BN_add_word(multiple, 1) || !BN_div(totient, rem, totient, multiple, ctx)) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB); + OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } if (!BN_is_zero(rem)) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_BAD_RSA_PARAMETERS); + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); goto err; } @@ -685,7 +732,7 @@ int RSA_recover_crt_params(RSA *rsa) { rsa->iqmp = BN_new(); if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 == NULL || rsa->iqmp == NULL) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } @@ -703,12 +750,12 @@ int RSA_recover_crt_params(RSA *rsa) { !BN_rshift1(rsa->q, rsa->q) || !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) || !BN_mul(multiple, rsa->p, rsa->q, ctx)) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB); + OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } if (BN_cmp(multiple, rsa->n) != 0) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); goto err; } @@ -717,7 +764,7 @@ int RSA_recover_crt_params(RSA *rsa) { !BN_sub(rem, rsa->q, BN_value_one()) || !BN_mod(rsa->dmq1, rsa->d, rem, ctx) || !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) { - OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB); + OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } -- cgit v1.1