1/* 2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18 19/* crypto/rsa/rsa_chk.c -*- Mode: C; c-file-style: "eay" -*- */ 20/* ==================================================================== 21 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 30 * 2. Redistributions in binary form must reproduce the above copyright 31 * notice, this list of conditions and the following disclaimer in 32 * the documentation and/or other materials provided with the 33 * distribution. 34 * 35 * 3. All advertising materials mentioning features or use of this 36 * software must display the following acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 39 * 40 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 41 * endorse or promote products derived from this software without 42 * prior written permission. For written permission, please contact 43 * openssl-core@OpenSSL.org. 44 * 45 * 5. Products derived from this software may not be called "OpenSSL" 46 * nor may "OpenSSL" appear in their names without prior written 47 * permission of the OpenSSL Project. 48 * 49 * 6. Redistributions of any form whatsoever must retain the following 50 * acknowledgment: 51 * "This product includes software developed by the OpenSSL Project 52 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 55 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 58 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 59 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 60 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 61 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 63 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 64 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 65 * OF THE POSSIBILITY OF SUCH DAMAGE. 66 * ==================================================================== 67 */ 68 69#include <openssl/bn.h> 70#include <openssl/err.h> 71#include <openssl/rsa.h> 72 73 74int RSA_check_key(RSA *key) 75 { 76 BIGNUM *i, *j, *k, *l, *m; 77 BN_CTX *ctx; 78 int r; 79 int ret=1; 80 81 i = BN_new(); 82 j = BN_new(); 83 k = BN_new(); 84 l = BN_new(); 85 m = BN_new(); 86 ctx = BN_CTX_new(); 87 if (i == NULL || j == NULL || k == NULL || l == NULL || 88 m == NULL || ctx == NULL) 89 { 90 ret = -1; 91 RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); 92 goto err; 93 } 94 95 /* p prime? */ 96 r = BN_is_prime(key->p, BN_prime_checks, NULL, NULL, NULL); 97 if (r != 1) 98 { 99 ret = r; 100 if (r != 0) 101 goto err; 102 RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); 103 } 104 105 /* q prime? */ 106 r = BN_is_prime(key->q, BN_prime_checks, NULL, NULL, NULL); 107 if (r != 1) 108 { 109 ret = r; 110 if (r != 0) 111 goto err; 112 RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); 113 } 114 115 /* n = p*q? */ 116 r = BN_mul(i, key->p, key->q, ctx); 117 if (!r) { ret = -1; goto err; } 118 119 if (BN_cmp(i, key->n) != 0) 120 { 121 ret = 0; 122 RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); 123 } 124 125 /* d*e = 1 mod lcm(p-1,q-1)? */ 126 127 r = BN_sub(i, key->p, BN_value_one()); 128 if (!r) { ret = -1; goto err; } 129 r = BN_sub(j, key->q, BN_value_one()); 130 if (!r) { ret = -1; goto err; } 131 132 /* now compute k = lcm(i,j) */ 133 r = BN_mul(l, i, j, ctx); 134 if (!r) { ret = -1; goto err; } 135 r = BN_gcd(m, i, j, ctx); 136 if (!r) { ret = -1; goto err; } 137 r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */ 138 if (!r) { ret = -1; goto err; } 139 140 r = BN_mod_mul(i, key->d, key->e, k, ctx); 141 if (!r) { ret = -1; goto err; } 142 143 if (!BN_is_one(i)) 144 { 145 ret = 0; 146 RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); 147 } 148 149 if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) 150 { 151 /* dmp1 = d mod (p-1)? */ 152 r = BN_sub(i, key->p, BN_value_one()); 153 if (!r) { ret = -1; goto err; } 154 155 r = BN_mod(j, key->d, i, ctx); 156 if (!r) { ret = -1; goto err; } 157 158 if (BN_cmp(j, key->dmp1) != 0) 159 { 160 ret = 0; 161 RSAerr(RSA_F_RSA_CHECK_KEY, 162 RSA_R_DMP1_NOT_CONGRUENT_TO_D); 163 } 164 165 /* dmq1 = d mod (q-1)? */ 166 r = BN_sub(i, key->q, BN_value_one()); 167 if (!r) { ret = -1; goto err; } 168 169 r = BN_mod(j, key->d, i, ctx); 170 if (!r) { ret = -1; goto err; } 171 172 if (BN_cmp(j, key->dmq1) != 0) 173 { 174 ret = 0; 175 RSAerr(RSA_F_RSA_CHECK_KEY, 176 RSA_R_DMQ1_NOT_CONGRUENT_TO_D); 177 } 178 179 /* iqmp = q^-1 mod p? */ 180 if(!BN_mod_inverse(i, key->q, key->p, ctx)) 181 { 182 ret = -1; 183 goto err; 184 } 185 186 if (BN_cmp(i, key->iqmp) != 0) 187 { 188 ret = 0; 189 RSAerr(RSA_F_RSA_CHECK_KEY, 190 RSA_R_IQMP_NOT_INVERSE_OF_Q); 191 } 192 } 193 194 err: 195 if (i != NULL) BN_free(i); 196 if (j != NULL) BN_free(j); 197 if (k != NULL) BN_free(k); 198 if (l != NULL) BN_free(l); 199 if (m != NULL) BN_free(m); 200 if (ctx != NULL) BN_CTX_free(ctx); 201 return (ret); 202 } 203