xref: /onnv-gate/usr/src/common/openssl/crypto/rsa/rsa_chk.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/rsa/rsa_chk.c  -*- Mode: C; c-file-style: "eay" -*- */
20Sstevel@tonic-gate /* ====================================================================
30Sstevel@tonic-gate  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
60Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
70Sstevel@tonic-gate  * are met:
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
100Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
110Sstevel@tonic-gate  *
120Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
130Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in
140Sstevel@tonic-gate  *    the documentation and/or other materials provided with the
150Sstevel@tonic-gate  *    distribution.
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this
180Sstevel@tonic-gate  *    software must display the following acknowledgment:
190Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
200Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
230Sstevel@tonic-gate  *    endorse or promote products derived from this software without
240Sstevel@tonic-gate  *    prior written permission. For written permission, please contact
250Sstevel@tonic-gate  *    openssl-core@OpenSSL.org.
260Sstevel@tonic-gate  *
270Sstevel@tonic-gate  * 5. Products derived from this software may not be called "OpenSSL"
280Sstevel@tonic-gate  *    nor may "OpenSSL" appear in their names without prior written
290Sstevel@tonic-gate  *    permission of the OpenSSL Project.
300Sstevel@tonic-gate  *
310Sstevel@tonic-gate  * 6. Redistributions of any form whatsoever must retain the following
320Sstevel@tonic-gate  *    acknowledgment:
330Sstevel@tonic-gate  *    "This product includes software developed by the OpenSSL Project
340Sstevel@tonic-gate  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
350Sstevel@tonic-gate  *
360Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
370Sstevel@tonic-gate  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
380Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
390Sstevel@tonic-gate  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
400Sstevel@tonic-gate  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
410Sstevel@tonic-gate  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
420Sstevel@tonic-gate  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
430Sstevel@tonic-gate  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
440Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
450Sstevel@tonic-gate  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
460Sstevel@tonic-gate  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
470Sstevel@tonic-gate  * OF THE POSSIBILITY OF SUCH DAMAGE.
480Sstevel@tonic-gate  * ====================================================================
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate 
510Sstevel@tonic-gate #include <openssl/bn.h>
520Sstevel@tonic-gate #include <openssl/err.h>
530Sstevel@tonic-gate #include <openssl/rsa.h>
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 
RSA_check_key(const RSA * key)560Sstevel@tonic-gate int RSA_check_key(const RSA *key)
570Sstevel@tonic-gate 	{
580Sstevel@tonic-gate 	BIGNUM *i, *j, *k, *l, *m;
590Sstevel@tonic-gate 	BN_CTX *ctx;
600Sstevel@tonic-gate 	int r;
610Sstevel@tonic-gate 	int ret=1;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	i = BN_new();
640Sstevel@tonic-gate 	j = BN_new();
650Sstevel@tonic-gate 	k = BN_new();
660Sstevel@tonic-gate 	l = BN_new();
670Sstevel@tonic-gate 	m = BN_new();
680Sstevel@tonic-gate 	ctx = BN_CTX_new();
690Sstevel@tonic-gate 	if (i == NULL || j == NULL || k == NULL || l == NULL ||
700Sstevel@tonic-gate 		m == NULL || ctx == NULL)
710Sstevel@tonic-gate 		{
720Sstevel@tonic-gate 		ret = -1;
730Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
740Sstevel@tonic-gate 		goto err;
750Sstevel@tonic-gate 		}
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	/* p prime? */
78*2139Sjp161948 	r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
790Sstevel@tonic-gate 	if (r != 1)
800Sstevel@tonic-gate 		{
810Sstevel@tonic-gate 		ret = r;
820Sstevel@tonic-gate 		if (r != 0)
830Sstevel@tonic-gate 			goto err;
840Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
850Sstevel@tonic-gate 		}
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	/* q prime? */
88*2139Sjp161948 	r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
890Sstevel@tonic-gate 	if (r != 1)
900Sstevel@tonic-gate 		{
910Sstevel@tonic-gate 		ret = r;
920Sstevel@tonic-gate 		if (r != 0)
930Sstevel@tonic-gate 			goto err;
940Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
950Sstevel@tonic-gate 		}
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	/* n = p*q? */
980Sstevel@tonic-gate 	r = BN_mul(i, key->p, key->q, ctx);
990Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	if (BN_cmp(i, key->n) != 0)
1020Sstevel@tonic-gate 		{
1030Sstevel@tonic-gate 		ret = 0;
1040Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
1050Sstevel@tonic-gate 		}
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	/* d*e = 1  mod lcm(p-1,q-1)? */
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	r = BN_sub(i, key->p, BN_value_one());
1100Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1110Sstevel@tonic-gate 	r = BN_sub(j, key->q, BN_value_one());
1120Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 	/* now compute k = lcm(i,j) */
1150Sstevel@tonic-gate 	r = BN_mul(l, i, j, ctx);
1160Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1170Sstevel@tonic-gate 	r = BN_gcd(m, i, j, ctx);
1180Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1190Sstevel@tonic-gate 	r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
1200Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	r = BN_mod_mul(i, key->d, key->e, k, ctx);
1230Sstevel@tonic-gate 	if (!r) { ret = -1; goto err; }
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	if (!BN_is_one(i))
1260Sstevel@tonic-gate 		{
1270Sstevel@tonic-gate 		ret = 0;
1280Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1);
1290Sstevel@tonic-gate 		}
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL)
1320Sstevel@tonic-gate 		{
1330Sstevel@tonic-gate 		/* dmp1 = d mod (p-1)? */
1340Sstevel@tonic-gate 		r = BN_sub(i, key->p, BN_value_one());
1350Sstevel@tonic-gate 		if (!r) { ret = -1; goto err; }
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 		r = BN_mod(j, key->d, i, ctx);
1380Sstevel@tonic-gate 		if (!r) { ret = -1; goto err; }
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 		if (BN_cmp(j, key->dmp1) != 0)
1410Sstevel@tonic-gate 			{
1420Sstevel@tonic-gate 			ret = 0;
1430Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_CHECK_KEY,
1440Sstevel@tonic-gate 				RSA_R_DMP1_NOT_CONGRUENT_TO_D);
1450Sstevel@tonic-gate 			}
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 		/* dmq1 = d mod (q-1)? */
1480Sstevel@tonic-gate 		r = BN_sub(i, key->q, BN_value_one());
1490Sstevel@tonic-gate 		if (!r) { ret = -1; goto err; }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 		r = BN_mod(j, key->d, i, ctx);
1520Sstevel@tonic-gate 		if (!r) { ret = -1; goto err; }
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 		if (BN_cmp(j, key->dmq1) != 0)
1550Sstevel@tonic-gate 			{
1560Sstevel@tonic-gate 			ret = 0;
1570Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_CHECK_KEY,
1580Sstevel@tonic-gate 				RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
1590Sstevel@tonic-gate 			}
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 		/* iqmp = q^-1 mod p? */
1620Sstevel@tonic-gate 		if(!BN_mod_inverse(i, key->q, key->p, ctx))
1630Sstevel@tonic-gate 			{
1640Sstevel@tonic-gate 			ret = -1;
1650Sstevel@tonic-gate 			goto err;
1660Sstevel@tonic-gate 			}
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 		if (BN_cmp(i, key->iqmp) != 0)
1690Sstevel@tonic-gate 			{
1700Sstevel@tonic-gate 			ret = 0;
1710Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_CHECK_KEY,
1720Sstevel@tonic-gate 				RSA_R_IQMP_NOT_INVERSE_OF_Q);
1730Sstevel@tonic-gate 			}
1740Sstevel@tonic-gate 		}
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate  err:
1770Sstevel@tonic-gate 	if (i != NULL) BN_free(i);
1780Sstevel@tonic-gate 	if (j != NULL) BN_free(j);
1790Sstevel@tonic-gate 	if (k != NULL) BN_free(k);
1800Sstevel@tonic-gate 	if (l != NULL) BN_free(l);
1810Sstevel@tonic-gate 	if (m != NULL) BN_free(m);
1820Sstevel@tonic-gate 	if (ctx != NULL) BN_CTX_free(ctx);
1830Sstevel@tonic-gate 	return (ret);
1840Sstevel@tonic-gate 	}
185