1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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
16static int dsa_builtin_keygen(DSA *dsa);
17
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
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 dsa->dirty_cnt++;
69 ok = 1;
70
71 err:
72 if (pub_key != dsa->pub_key)
73 BN_free(pub_key);
74 if (priv_key != dsa->priv_key)
75 BN_free(priv_key);
76 BN_CTX_free(ctx);
77 return ok;
78}
79