rsa_chk.c revision 225736
1255767Sdes/* crypto/rsa/rsa_chk.c  -*- Mode: C; c-file-style: "eay" -*- */
269587Sgreen/* ====================================================================
369587Sgreen * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
469587Sgreen *
569587Sgreen * Redistribution and use in source and binary forms, with or without
669587Sgreen * modification, are permitted provided that the following conditions
769587Sgreen * are met:
869587Sgreen *
969587Sgreen * 1. Redistributions of source code must retain the above copyright
1069587Sgreen *    notice, this list of conditions and the following disclaimer.
1169587Sgreen *
1269587Sgreen * 2. Redistributions in binary form must reproduce the above copyright
1369587Sgreen *    notice, this list of conditions and the following disclaimer in
1469587Sgreen *    the documentation and/or other materials provided with the
1569587Sgreen *    distribution.
1669587Sgreen *
1769587Sgreen * 3. All advertising materials mentioning features or use of this
1869587Sgreen *    software must display the following acknowledgment:
1969587Sgreen *    "This product includes software developed by the OpenSSL Project
2069587Sgreen *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2169587Sgreen *
2269587Sgreen * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2369587Sgreen *    endorse or promote products derived from this software without
2469587Sgreen *    prior written permission. For written permission, please contact
2569587Sgreen *    openssl-core@OpenSSL.org.
2669587Sgreen *
2769587Sgreen * 5. Products derived from this software may not be called "OpenSSL"
28162852Sdes *    nor may "OpenSSL" appear in their names without prior written
2969587Sgreen *    permission of the OpenSSL Project.
3069587Sgreen *
3169587Sgreen * 6. Redistributions of any form whatsoever must retain the following
3269587Sgreen *    acknowledgment:
33162852Sdes *    "This product includes software developed by the OpenSSL Project
34162852Sdes *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35162852Sdes *
36162852Sdes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37162852Sdes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3869587Sgreen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3976259Sgreen * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4076259Sgreen * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4176259Sgreen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4269587Sgreen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4392555Sdes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4469587Sgreen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4569587Sgreen * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4669587Sgreen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4769587Sgreen * OF THE POSSIBILITY OF SUCH DAMAGE.
48162852Sdes * ====================================================================
49181111Sdes */
5069587Sgreen
51255767Sdes#include <openssl/bn.h>
5269587Sgreen#include <openssl/err.h>
53162852Sdes#include <openssl/rsa.h>
54162852Sdes
5569587Sgreen
5669587Sgreenint RSA_check_key(const RSA *key)
5769587Sgreen	{
58106121Sdes	BIGNUM *i, *j, *k, *l, *m;
5969587Sgreen	BN_CTX *ctx;
6069587Sgreen	int r;
6169587Sgreen	int ret=1;
6269587Sgreen
63255767Sdes	i = BN_new();
6469587Sgreen	j = BN_new();
6569587Sgreen	k = BN_new();
66255767Sdes	l = BN_new();
67181111Sdes	m = BN_new();
68181111Sdes	ctx = BN_CTX_new();
69255767Sdes	if (i == NULL || j == NULL || k == NULL || l == NULL ||
70255767Sdes		m == NULL || ctx == NULL)
71181111Sdes		{
72255767Sdes		ret = -1;
7369587Sgreen		RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
7469587Sgreen		goto err;
75255767Sdes		}
76181111Sdes
77181111Sdes	/* p prime? */
78181111Sdes	r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
79255767Sdes	if (r != 1)
80255767Sdes		{
81181111Sdes		ret = r;
82255767Sdes		if (r != 0)
8369587Sgreen			goto err;
8469587Sgreen		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
85255767Sdes		}
86181111Sdes
87255767Sdes	/* q prime? */
88255767Sdes	r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
89181111Sdes	if (r != 1)
90255767Sdes		{
9169587Sgreen		ret = r;
9269587Sgreen		if (r != 0)
93204917Sdes			goto err;
94255767Sdes		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
95255767Sdes		}
9669587Sgreen
97255767Sdes	/* n = p*q? */
9876259Sgreen	r = BN_mul(i, key->p, key->q, ctx);
9976259Sgreen	if (!r) { ret = -1; goto err; }
10069587Sgreen
10169587Sgreen	if (BN_cmp(i, key->n) != 0)
102255767Sdes		{
10369587Sgreen		ret = 0;
104255767Sdes		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
105255767Sdes		}
106255767Sdes
10769587Sgreen	/* d*e = 1  mod lcm(p-1,q-1)? */
108255767Sdes
10969587Sgreen	r = BN_sub(i, key->p, BN_value_one());
11092555Sdes	if (!r) { ret = -1; goto err; }
11192555Sdes	r = BN_sub(j, key->q, BN_value_one());
11292555Sdes	if (!r) { ret = -1; goto err; }
11392555Sdes
114255767Sdes	/* now compute k = lcm(i,j) */
115255767Sdes	r = BN_mul(l, i, j, ctx);
116255767Sdes	if (!r) { ret = -1; goto err; }
117255767Sdes	r = BN_gcd(m, i, j, ctx);
118255767Sdes	if (!r) { ret = -1; goto err; }
119255767Sdes	r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
120255767Sdes	if (!r) { ret = -1; goto err; }
121255767Sdes
122255767Sdes	r = BN_mod_mul(i, key->d, key->e, k, ctx);
123255767Sdes	if (!r) { ret = -1; goto err; }
124255767Sdes
125255767Sdes	if (!BN_is_one(i))
126255767Sdes		{
127255767Sdes		ret = 0;
128255767Sdes		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
129255767Sdes		}
130255767Sdes
13169587Sgreen	if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL)
132255767Sdes		{
13376259Sgreen		/* dmp1 = d mod (p-1)? */
13469587Sgreen		r = BN_sub(i, key->p, BN_value_one());
135255767Sdes		if (!r) { ret = -1; goto err; }
136255767Sdes
137255767Sdes		r = BN_mod(j, key->d, i, ctx);
138255767Sdes		if (!r) { ret = -1; goto err; }
139255767Sdes
14076259Sgreen		if (BN_cmp(j, key->dmp1) != 0)
141255767Sdes			{
14269587Sgreen			ret = 0;
14369587Sgreen			RSAerr(RSA_F_RSA_CHECK_KEY,
14469587Sgreen				RSA_R_DMP1_NOT_CONGRUENT_TO_D);
14576259Sgreen			}
14669587Sgreen
14769587Sgreen		/* dmq1 = d mod (q-1)? */
148128456Sdes		r = BN_sub(i, key->q, BN_value_one());
14969587Sgreen		if (!r) { ret = -1; goto err; }
15069587Sgreen
15169587Sgreen		r = BN_mod(j, key->d, i, ctx);
15269587Sgreen		if (!r) { ret = -1; goto err; }
15392555Sdes
15492555Sdes		if (BN_cmp(j, key->dmq1) != 0)
155137015Sdes			{
156137015Sdes			ret = 0;
157137015Sdes			RSAerr(RSA_F_RSA_CHECK_KEY,
15869587Sgreen				RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
15969587Sgreen			}
16069587Sgreen
16169587Sgreen		/* iqmp = q^-1 mod p? */
16269587Sgreen		if(!BN_mod_inverse(i, key->q, key->p, ctx))
16369587Sgreen			{
16469587Sgreen			ret = -1;
16569587Sgreen			goto err;
16692555Sdes			}
16792555Sdes
16869587Sgreen		if (BN_cmp(i, key->iqmp) != 0)
16976259Sgreen			{
17076259Sgreen			ret = 0;
17176259Sgreen			RSAerr(RSA_F_RSA_CHECK_KEY,
17276259Sgreen				RSA_R_IQMP_NOT_INVERSE_OF_Q);
17376259Sgreen			}
17469587Sgreen		}
17569587Sgreen
17669587Sgreen err:
17769587Sgreen	if (i != NULL) BN_free(i);
17869587Sgreen	if (j != NULL) BN_free(j);
17969587Sgreen	if (k != NULL) BN_free(k);
18092555Sdes	if (l != NULL) BN_free(l);
18169587Sgreen	if (m != NULL) BN_free(m);
18269587Sgreen	if (ctx != NULL) BN_CTX_free(ctx);
18392555Sdes	return (ret);
184124208Sdes	}
185137015Sdes