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