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