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