2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/bn.h>
11 #include <openssl/err.h>
14 int RSA_check_key(const RSA
*key
)
16 return RSA_check_key_ex(key
, NULL
);
19 int RSA_check_key_ex(const RSA
*key
, BN_GENCB
*cb
)
21 BIGNUM
*i
, *j
, *k
, *l
, *m
;
25 if (key
->p
== NULL
|| key
->q
== NULL
|| key
->n
== NULL
26 || key
->e
== NULL
|| key
->d
== NULL
) {
27 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_VALUE_MISSING
);
37 if (i
== NULL
|| j
== NULL
|| k
== NULL
|| l
== NULL
38 || m
== NULL
|| ctx
== NULL
) {
40 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, ERR_R_MALLOC_FAILURE
);
44 if (BN_is_one(key
->e
)) {
46 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_BAD_E_VALUE
);
48 if (!BN_is_odd(key
->e
)) {
50 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_BAD_E_VALUE
);
54 if (BN_is_prime_ex(key
->p
, BN_prime_checks
, NULL
, cb
) != 1) {
56 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_P_NOT_PRIME
);
60 if (BN_is_prime_ex(key
->q
, BN_prime_checks
, NULL
, cb
) != 1) {
62 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_Q_NOT_PRIME
);
66 if (!BN_mul(i
, key
->p
, key
->q
, ctx
)) {
70 if (BN_cmp(i
, key
->n
) != 0) {
72 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_N_DOES_NOT_EQUAL_P_Q
);
75 /* d*e = 1 mod lcm(p-1,q-1)? */
76 if (!BN_sub(i
, key
->p
, BN_value_one())) {
80 if (!BN_sub(j
, key
->q
, BN_value_one())) {
85 /* now compute k = lcm(i,j) */
86 if (!BN_mul(l
, i
, j
, ctx
)) {
90 if (!BN_gcd(m
, i
, j
, ctx
)) {
94 if (!BN_div(k
, NULL
, l
, m
, ctx
)) { /* remainder is 0 */
98 if (!BN_mod_mul(i
, key
->d
, key
->e
, k
, ctx
)) {
105 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_D_E_NOT_CONGRUENT_TO_1
);
108 if (key
->dmp1
!= NULL
&& key
->dmq1
!= NULL
&& key
->iqmp
!= NULL
) {
109 /* dmp1 = d mod (p-1)? */
110 if (!BN_sub(i
, key
->p
, BN_value_one())) {
114 if (!BN_mod(j
, key
->d
, i
, ctx
)) {
118 if (BN_cmp(j
, key
->dmp1
) != 0) {
120 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_DMP1_NOT_CONGRUENT_TO_D
);
123 /* dmq1 = d mod (q-1)? */
124 if (!BN_sub(i
, key
->q
, BN_value_one())) {
128 if (!BN_mod(j
, key
->d
, i
, ctx
)) {
132 if (BN_cmp(j
, key
->dmq1
) != 0) {
134 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_DMQ1_NOT_CONGRUENT_TO_D
);
137 /* iqmp = q^-1 mod p? */
138 if (!BN_mod_inverse(i
, key
->q
, key
->p
, ctx
)) {
142 if (BN_cmp(i
, key
->iqmp
) != 0) {
144 RSAerr(RSA_F_RSA_CHECK_KEY_EX
, RSA_R_IQMP_NOT_INVERSE_OF_Q
);