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