Line data Source code
1 : /* crypto/rsa/rsa_chk.c -*- Mode: C; c-file-style: "eay" -*- */
2 : /* ====================================================================
3 : * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 : *
5 : * Redistribution and use in source and binary forms, with or without
6 : * modification, are permitted provided that the following conditions
7 : * are met:
8 : *
9 : * 1. Redistributions of source code must retain the above copyright
10 : * notice, this list of conditions and the following disclaimer.
11 : *
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in
14 : * the documentation and/or other materials provided with the
15 : * distribution.
16 : *
17 : * 3. All advertising materials mentioning features or use of this
18 : * software must display the following acknowledgment:
19 : * "This product includes software developed by the OpenSSL Project
20 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 : *
22 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 : * endorse or promote products derived from this software without
24 : * prior written permission. For written permission, please contact
25 : * openssl-core@OpenSSL.org.
26 : *
27 : * 5. Products derived from this software may not be called "OpenSSL"
28 : * nor may "OpenSSL" appear in their names without prior written
29 : * permission of the OpenSSL Project.
30 : *
31 : * 6. Redistributions of any form whatsoever must retain the following
32 : * acknowledgment:
33 : * "This product includes software developed by the OpenSSL Project
34 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 : *
36 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 : * OF THE POSSIBILITY OF SUCH DAMAGE.
48 : * ====================================================================
49 : */
50 :
51 : #include <openssl/bn.h>
52 : #include <openssl/err.h>
53 : #include <openssl/rsa.h>
54 :
55 3 : int RSA_check_key(const RSA *key)
56 : {
57 : BIGNUM *i, *j, *k, *l, *m;
58 : BN_CTX *ctx;
59 : int r;
60 : int ret = 1;
61 :
62 3 : if (!key->p || !key->q || !key->n || !key->e || !key->d) {
63 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING);
64 0 : return 0;
65 : }
66 :
67 3 : i = BN_new();
68 3 : j = BN_new();
69 3 : k = BN_new();
70 3 : l = BN_new();
71 3 : m = BN_new();
72 3 : ctx = BN_CTX_new();
73 3 : if (i == NULL || j == NULL || k == NULL || l == NULL ||
74 3 : m == NULL || ctx == NULL) {
75 : ret = -1;
76 0 : RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
77 0 : goto err;
78 : }
79 :
80 : /* p prime? */
81 3 : r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
82 3 : if (r != 1) {
83 : ret = r;
84 0 : if (r != 0)
85 : goto err;
86 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
87 : }
88 :
89 : /* q prime? */
90 3 : r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
91 3 : if (r != 1) {
92 : ret = r;
93 0 : if (r != 0)
94 : goto err;
95 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
96 : }
97 :
98 : /* n = p*q? */
99 3 : r = BN_mul(i, key->p, key->q, ctx);
100 3 : if (!r) {
101 : ret = -1;
102 : goto err;
103 : }
104 :
105 3 : if (BN_cmp(i, key->n) != 0) {
106 : ret = 0;
107 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
108 : }
109 :
110 : /* d*e = 1 mod lcm(p-1,q-1)? */
111 :
112 3 : r = BN_sub(i, key->p, BN_value_one());
113 3 : if (!r) {
114 : ret = -1;
115 : goto err;
116 : }
117 3 : r = BN_sub(j, key->q, BN_value_one());
118 3 : if (!r) {
119 : ret = -1;
120 : goto err;
121 : }
122 :
123 : /* now compute k = lcm(i,j) */
124 3 : r = BN_mul(l, i, j, ctx);
125 3 : if (!r) {
126 : ret = -1;
127 : goto err;
128 : }
129 3 : r = BN_gcd(m, i, j, ctx);
130 3 : if (!r) {
131 : ret = -1;
132 : goto err;
133 : }
134 3 : r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
135 3 : if (!r) {
136 : ret = -1;
137 : goto err;
138 : }
139 :
140 3 : r = BN_mod_mul(i, key->d, key->e, k, ctx);
141 3 : if (!r) {
142 : ret = -1;
143 : goto err;
144 : }
145 :
146 3 : if (!BN_is_one(i)) {
147 : ret = 0;
148 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
149 : }
150 :
151 3 : if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
152 : /* dmp1 = d mod (p-1)? */
153 3 : r = BN_sub(i, key->p, BN_value_one());
154 3 : if (!r) {
155 : ret = -1;
156 : goto err;
157 : }
158 :
159 3 : r = BN_mod(j, key->d, i, ctx);
160 3 : if (!r) {
161 : ret = -1;
162 : goto err;
163 : }
164 :
165 3 : if (BN_cmp(j, key->dmp1) != 0) {
166 : ret = 0;
167 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D);
168 : }
169 :
170 : /* dmq1 = d mod (q-1)? */
171 3 : r = BN_sub(i, key->q, BN_value_one());
172 3 : if (!r) {
173 : ret = -1;
174 : goto err;
175 : }
176 :
177 3 : r = BN_mod(j, key->d, i, ctx);
178 3 : if (!r) {
179 : ret = -1;
180 : goto err;
181 : }
182 :
183 3 : if (BN_cmp(j, key->dmq1) != 0) {
184 : ret = 0;
185 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
186 : }
187 :
188 : /* iqmp = q^-1 mod p? */
189 3 : if (!BN_mod_inverse(i, key->q, key->p, ctx)) {
190 : ret = -1;
191 : goto err;
192 : }
193 :
194 3 : if (BN_cmp(i, key->iqmp) != 0) {
195 : ret = 0;
196 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q);
197 : }
198 : }
199 :
200 : err:
201 3 : if (i != NULL)
202 3 : BN_free(i);
203 3 : if (j != NULL)
204 3 : BN_free(j);
205 3 : if (k != NULL)
206 3 : BN_free(k);
207 3 : if (l != NULL)
208 3 : BN_free(l);
209 3 : if (m != NULL)
210 3 : BN_free(m);
211 3 : if (ctx != NULL)
212 3 : BN_CTX_free(ctx);
213 3 : return (ret);
214 : }
|