1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <time.h> 12 #include "internal/cryptlib.h" 13 #include <openssl/bn.h> 14 #include "dsa_local.h" 15 16 static int dsa_builtin_keygen(DSA *dsa); 17 DSA_generate_key(DSA * dsa)18int DSA_generate_key(DSA *dsa) 19 { 20 if (dsa->meth->dsa_keygen) 21 return dsa->meth->dsa_keygen(dsa); 22 return dsa_builtin_keygen(dsa); 23 } 24 dsa_builtin_keygen(DSA * dsa)25static int dsa_builtin_keygen(DSA *dsa) 26 { 27 int ok = 0; 28 BN_CTX *ctx = NULL; 29 BIGNUM *pub_key = NULL, *priv_key = NULL; 30 31 if ((ctx = BN_CTX_new()) == NULL) 32 goto err; 33 34 if (dsa->priv_key == NULL) { 35 if ((priv_key = BN_secure_new()) == NULL) 36 goto err; 37 } else 38 priv_key = dsa->priv_key; 39 40 do 41 if (!BN_priv_rand_range(priv_key, dsa->q)) 42 goto err; 43 while (BN_is_zero(priv_key)) ; 44 45 if (dsa->pub_key == NULL) { 46 if ((pub_key = BN_new()) == NULL) 47 goto err; 48 } else 49 pub_key = dsa->pub_key; 50 51 { 52 BIGNUM *prk = BN_new(); 53 54 if (prk == NULL) 55 goto err; 56 BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); 57 58 if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) { 59 BN_free(prk); 60 goto err; 61 } 62 /* We MUST free prk before any further use of priv_key */ 63 BN_free(prk); 64 } 65 66 dsa->priv_key = priv_key; 67 dsa->pub_key = pub_key; 68 ok = 1; 69 70 err: 71 if (pub_key != dsa->pub_key) 72 BN_free(pub_key); 73 if (priv_key != dsa->priv_key) 74 BN_free(priv_key); 75 BN_CTX_free(ctx); 76 return ok; 77 } 78