]>
Commit | Line | Data |
---|---|---|
f11f86f6 | 1 | /* |
38fc02a7 | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
f11f86f6 SL |
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 "internal/ffc.h" | |
11 | ||
12 | /* | |
13 | * SP800-56Ar3 5.6.1.1.4 Key pair generation by testing candidates. | |
14 | * Generates a private key in the interval [1, min(2 ^ N - 1, q - 1)]. | |
15 | * | |
16 | * ctx must be set up with a libctx (for fips mode). | |
17 | * params contains the FFC domain parameters p, q and g (for DH or DSA). | |
18 | * N is the maximum bit length of the generated private key, | |
19 | * s is the security strength. | |
20 | * priv_key is the returned private key, | |
21 | */ | |
5357c106 P |
22 | int ossl_ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params, |
23 | int N, int s, BIGNUM *priv) | |
8083fd3a | 24 | { |
55f02cb6 | 25 | int ret = 0, qbits = BN_num_bits(params->q); |
f11f86f6 SL |
26 | BIGNUM *m, *two_powN = NULL; |
27 | ||
ddb13b28 | 28 | /* Deal with the edge cases where the value of N and/or s is not set */ |
738ee181 | 29 | if (s == 0) |
ddb13b28 TM |
30 | goto err; |
31 | if (N == 0) | |
32 | N = params->keylength ? params->keylength : 2 * s; | |
738ee181 SL |
33 | |
34 | /* Step (2) : check range of N */ | |
35 | if (N < 2 * s || N > qbits) | |
36 | return 0; | |
55f02cb6 | 37 | |
f11f86f6 SL |
38 | two_powN = BN_new(); |
39 | /* 2^N */ | |
40 | if (two_powN == NULL || !BN_lshift(two_powN, BN_value_one(), N)) | |
41 | goto err; | |
42 | ||
43 | /* Step (5) : M = min(2 ^ N, q) */ | |
44 | m = (BN_cmp(two_powN, params->q) > 0) ? params->q : two_powN; | |
55f02cb6 | 45 | |
f11f86f6 SL |
46 | do { |
47 | /* Steps (3, 4 & 7) : c + 1 = 1 + random[0..2^N - 1] */ | |
5cbd2ea3 | 48 | if (!BN_priv_rand_range_ex(priv, two_powN, 0, ctx) |
f11f86f6 SL |
49 | || !BN_add_word(priv, 1)) |
50 | goto err; | |
51 | /* Step (6) : loop if c > M - 2 (i.e. c + 1 >= M) */ | |
52 | if (BN_cmp(priv, m) < 0) | |
53 | break; | |
54 | } while (1); | |
55 | ||
56 | ret = 1; | |
57 | err: | |
58 | BN_free(two_powN); | |
59 | return ret; | |
f11f86f6 | 60 | } |