summaryrefslogtreecommitdiffstats
path: root/src/crypto/rsa/rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/rsa/rsa.c')
-rw-r--r--src/crypto/rsa/rsa.c143
1 files changed, 95 insertions, 48 deletions
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;
}