Branch data 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 : :
56 : 0 : int RSA_check_key(const RSA *key)
57 : : {
58 : : BIGNUM *i, *j, *k, *l, *m;
59 : : BN_CTX *ctx;
60 : : int r;
61 : 0 : int ret=1;
62 : :
63 [ # # ][ # # ]: 0 : if (!key->p || !key->q || !key->n || !key->e || !key->d)
[ # # ][ # # ]
[ # # ]
64 : : {
65 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING);
66 : 0 : return 0;
67 : : }
68 : :
69 : 0 : i = BN_new();
70 : 0 : j = BN_new();
71 : 0 : k = BN_new();
72 : 0 : l = BN_new();
73 : 0 : m = BN_new();
74 : 0 : ctx = BN_CTX_new();
75 [ # # ][ # # ]: 0 : if (i == NULL || j == NULL || k == NULL || l == NULL ||
76 [ # # ]: 0 : m == NULL || ctx == NULL)
77 : : {
78 : 0 : ret = -1;
79 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
80 : 0 : goto err;
81 : : }
82 : :
83 : : /* p prime? */
84 : 0 : r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
85 [ # # ]: 0 : if (r != 1)
86 : : {
87 : 0 : ret = r;
88 [ # # ]: 0 : if (r != 0)
89 : : goto err;
90 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
91 : : }
92 : :
93 : : /* q prime? */
94 : 0 : r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
95 [ # # ]: 0 : if (r != 1)
96 : : {
97 : 0 : ret = r;
98 [ # # ]: 0 : if (r != 0)
99 : : goto err;
100 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
101 : : }
102 : :
103 : : /* n = p*q? */
104 : 0 : r = BN_mul(i, key->p, key->q, ctx);
105 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
106 : :
107 [ # # ]: 0 : if (BN_cmp(i, key->n) != 0)
108 : : {
109 : 0 : ret = 0;
110 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
111 : : }
112 : :
113 : : /* d*e = 1 mod lcm(p-1,q-1)? */
114 : :
115 : 0 : r = BN_sub(i, key->p, BN_value_one());
116 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
117 : 0 : r = BN_sub(j, key->q, BN_value_one());
118 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
119 : :
120 : : /* now compute k = lcm(i,j) */
121 : 0 : r = BN_mul(l, i, j, ctx);
122 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
123 : 0 : r = BN_gcd(m, i, j, ctx);
124 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
125 : 0 : r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
126 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
127 : :
128 : 0 : r = BN_mod_mul(i, key->d, key->e, k, ctx);
129 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
130 : :
131 [ # # ][ # # ]: 0 : if (!BN_is_one(i))
[ # # ]
132 : : {
133 : 0 : ret = 0;
134 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
135 : : }
136 : :
137 [ # # ][ # # ]: 0 : if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL)
[ # # ]
138 : : {
139 : : /* dmp1 = d mod (p-1)? */
140 : 0 : r = BN_sub(i, key->p, BN_value_one());
141 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
142 : :
143 : 0 : r = BN_mod(j, key->d, i, ctx);
144 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
145 : :
146 [ # # ]: 0 : if (BN_cmp(j, key->dmp1) != 0)
147 : : {
148 : 0 : ret = 0;
149 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY,
150 : : RSA_R_DMP1_NOT_CONGRUENT_TO_D);
151 : : }
152 : :
153 : : /* dmq1 = d mod (q-1)? */
154 : 0 : r = BN_sub(i, key->q, BN_value_one());
155 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
156 : :
157 : 0 : r = BN_mod(j, key->d, i, ctx);
158 [ # # ]: 0 : if (!r) { ret = -1; goto err; }
159 : :
160 [ # # ]: 0 : if (BN_cmp(j, key->dmq1) != 0)
161 : : {
162 : 0 : ret = 0;
163 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY,
164 : : RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
165 : : }
166 : :
167 : : /* iqmp = q^-1 mod p? */
168 [ # # ]: 0 : if(!BN_mod_inverse(i, key->q, key->p, ctx))
169 : : {
170 : : ret = -1;
171 : : goto err;
172 : : }
173 : :
174 [ # # ]: 0 : if (BN_cmp(i, key->iqmp) != 0)
175 : : {
176 : 0 : ret = 0;
177 : 0 : RSAerr(RSA_F_RSA_CHECK_KEY,
178 : : RSA_R_IQMP_NOT_INVERSE_OF_Q);
179 : : }
180 : : }
181 : :
182 : : err:
183 [ # # ]: 0 : if (i != NULL) BN_free(i);
184 [ # # ]: 0 : if (j != NULL) BN_free(j);
185 [ # # ]: 0 : if (k != NULL) BN_free(k);
186 [ # # ]: 0 : if (l != NULL) BN_free(l);
187 [ # # ]: 0 : if (m != NULL) BN_free(m);
188 [ # # ]: 0 : if (ctx != NULL) BN_CTX_free(ctx);
189 : 0 : return (ret);
190 : : }
|