1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/dsa/dsa_gen.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * All rights reserved. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This package is an SSL implementation written 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * by Eric Young (eay@cryptsoft.com). 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The implementation was written so as to conform with Netscapes SSL. 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This library is free for commercial and non-commercial use as long as 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the following conditions are aheared to. The following conditions 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA, 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * included with this distribution is covered by the same copyright terms 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the code are not to be removed. 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * If this package is used in a product, Eric Young should be given attribution 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as the author of the parts of the library used. 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This can be in the form of a textual message at program startup or 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in documentation (online or textual) provided with the package. 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the copyright 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in the 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * documentation and/or other materials provided with the distribution. 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this software 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * must display the following acknowledgement: 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes cryptographic software written by 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Eric Young (eay@cryptsoft.com)" 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The word 'cryptographic' can be left out if the rouines from the library 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * being used are not cryptographic related :-). 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the apps directory (application code) you must include an acknowledgement: 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SUCH DAMAGE. 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The licence and distribution terms for any publically available version or 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * derivative of this code cannot be changed. i.e. this code cannot simply be 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * copied and put under another distribution licence 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * [including the GNU Public Licence.] 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#undef GENUINE_DSA 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef GENUINE_DSA 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Parameter generation follows the original release of FIPS PUB 186, 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */ 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define HASH EVP_sha() 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else 66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, 67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in 68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FIPS PUB 180-1) */ 69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define HASH EVP_sha1() 70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */ 73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef OPENSSL_NO_SHA 75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h> 77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h" 78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/evp.h> 79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/bn.h> 80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/rand.h> 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/sha.h> 82480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#include "dsa_locl.h" 83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef OPENSSL_FIPS 852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#include <openssl/fips.h> 862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint DSA_generate_parameters_ex(DSA *ret, int bits, 89480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const unsigned char *seed_in, int seed_len, 90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) 91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef OPENSSL_FIPS 932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) 942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) 952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); 972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(ret->meth->dsa_paramgen) 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org counter_ret, h_ret, cb); 1032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef OPENSSL_FIPS 1042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else if (FIPS_mode()) 1052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 1062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return FIPS_dsa_generate_parameters_ex(ret, bits, 1072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org seed_in, seed_len, 1082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org counter_ret, h_ret, cb); 1092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 1102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const EVP_MD *evpmd; 114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org size_t qbits = bits >= 2048 ? 256 : 160; 115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (bits >= 2048) 117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org qbits = 256; 119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org evpmd = EVP_sha256(); 120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org else 122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org qbits = 160; 124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org evpmd = EVP_sha1(); 125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return dsa_builtin_paramgen(ret, bits, qbits, evpmd, 1282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org seed_in, seed_len, NULL, counter_ret, h_ret, cb); 129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, 133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, 1342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org unsigned char *seed_out, 135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ok=0; 138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char seed[SHA256_DIGEST_LENGTH]; 139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char md[SHA256_DIGEST_LENGTH]; 140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH]; 141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIGNUM *r0,*W,*X,*c,*test; 142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIGNUM *g=NULL,*q=NULL,*p=NULL; 143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_MONT_CTX *mont=NULL; 144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int i, k, n=0, m=0, qsize = qbits >> 3; 145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int counter=0; 146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int r=0; 147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX *ctx=NULL; 148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned int h=2; 149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && 151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org qsize != SHA256_DIGEST_LENGTH) 152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* invalid q size */ 153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (evpmd == NULL) 156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* use SHA1 as default */ 157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org evpmd = EVP_sha1(); 158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (bits < 512) 160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org bits = 512; 161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org bits = (bits+63)/64*64; 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* NB: seed_len == 0 is special case: copy generated seed to 165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * seed_in if it is not NULL. 166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (seed_len && (seed_len < (size_t)qsize)) 168480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org seed_in = NULL; /* seed buffer too small -- ignore */ 169480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (seed_len > (size_t)qsize) 170480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED, 171480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * but our internal buffers are restricted to 160 bits*/ 172480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (seed_in != NULL) 173480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(seed, seed_in, seed_len); 174480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 175480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ((ctx=BN_CTX_new()) == NULL) 176480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 178480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ((mont=BN_MONT_CTX_new()) == NULL) 179480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX_start(ctx); 182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org r0 = BN_CTX_get(ctx); 183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org g = BN_CTX_get(ctx); 184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org W = BN_CTX_get(ctx); 185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org q = BN_CTX_get(ctx); 186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X = BN_CTX_get(ctx); 187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org c = BN_CTX_get(ctx); 188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p = BN_CTX_get(ctx); 189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org test = BN_CTX_get(ctx); 190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_lshift(test,BN_value_one(),bits-1)) 192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) 195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) /* find q */ 197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int seed_is_random; 199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 1 */ 201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!BN_GENCB_call(cb, 0, m++)) 202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!seed_len) 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 206480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org RAND_pseudo_bytes(seed, qsize); 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org seed_is_random = 1; 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org seed_is_random = 0; 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ 213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 214480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(buf , seed, qsize); 215480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org memcpy(buf2, seed, qsize); 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* precompute "SEED + 1" for step 7: */ 217480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = qsize-1; i >= 0; i--) 218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org buf[i]++; 220480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (buf[i] != 0) 221480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 2 */ 2252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) 2262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 2272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) 2282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = 0; i < qsize; i++) 230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org md[i]^=buf2[i]; 231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 3 */ 233480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org md[0] |= 0x80; 234480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org md[qsize-1] |= 0x01; 235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!BN_bin2bn(md, qsize, q)) 236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 4 */ 239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, 240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org seed_is_random, cb); 241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r > 0) 242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r != 0) 244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* do a callback call */ 247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 5 */ 248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!BN_GENCB_call(cb, 2, 0)) goto err; 251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!BN_GENCB_call(cb, 3, 0)) goto err; 252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 6 */ 254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org counter=0; 255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* "offset = 2" */ 256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org n=(bits-1)/160; 258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) 260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) 262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 7 */ 265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_zero(W); 266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* now 'buf' contains "SEED + offset - 1" */ 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (k=0; k<=n; k++) 268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* obtain "SEED + offset + k" by incrementing: */ 270480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org for (i = qsize-1; i >= 0; i--) 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org buf[i]++; 273480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (buf[i] != 0) 274480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org break; 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 2772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EVP_Digest(buf, qsize, md ,NULL, evpmd, 2782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org NULL)) 2792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 8 */ 282480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!BN_bin2bn(md, qsize, r0)) 283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err; 285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_add(W,W,r0)) goto err; 286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* more of step 8 */ 289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_mask_bits(W,bits-1)) goto err; 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_copy(X,W)) goto err; 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_add(X,X,test)) goto err; 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 9 */ 294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_lshift1(r0,q)) goto err; 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_mod(c,X,r0,ctx)) goto err; 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_sub(r0,c,BN_value_one())) goto err; 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_sub(p,X,r0)) goto err; 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 10 */ 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BN_cmp(p,test) >= 0) 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 11 */ 303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, 304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ctx, 1, cb); 305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r > 0) 306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto end; /* found it */ 307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r != 0) 308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 13 */ 312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org counter++; 313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* "offset = offset + n + 1" */ 314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* step 14 */ 316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (counter >= 4096) break; 317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgend: 320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!BN_GENCB_call(cb, 2, 1)) 321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* We now need to generate g */ 324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Set r0=(p-1)/q */ 325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_sub(test,p,BN_value_one())) goto err; 326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_div(r0,NULL,test,q,ctx)) goto err; 327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_set_word(test,h)) goto err; 329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; 330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (;;) 332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* g=test^r0%p */ 334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; 335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_is_one(g)) break; 336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_add(test,test,BN_value_one())) goto err; 337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org h++; 338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!BN_GENCB_call(cb, 3, 1)) 341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ok=1; 344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 345c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ok) 346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(ret->p) BN_free(ret->p); 348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(ret->q) BN_free(ret->q); 349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(ret->g) BN_free(ret->g); 350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->p=BN_dup(p); 351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->q=BN_dup(q); 352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->g=BN_dup(g); 353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret->p == NULL || ret->q == NULL || ret->g == NULL) 354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ok=0; 356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (counter_ret != NULL) *counter_ret=counter; 359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (h_ret != NULL) *h_ret=h; 3602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (seed_out) 3612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org memcpy(seed_out, seed, qsize); 362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(ctx) 364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX_end(ctx); 366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX_free(ctx); 367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (mont != NULL) BN_MONT_CTX_free(mont); 369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ok; 370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 372