]>
Commit | Line | Data |
---|---|---|
8083fd3a | 1 | /* |
da1c088f | 2 | * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. |
8083fd3a 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 | * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Partial public key validation. | |
14 | * To only be used with ephemeral FFC public keys generated using the approved | |
15 | * safe-prime groups. (Checks that the public key is in the range [2, p - 1] | |
16 | * | |
17 | * ret contains 0 on success, or error flags (see FFC_ERROR_PUBKEY_TOO_SMALL) | |
18 | */ | |
5357c106 P |
19 | int ossl_ffc_validate_public_key_partial(const FFC_PARAMS *params, |
20 | const BIGNUM *pub_key, int *ret) | |
8083fd3a SL |
21 | { |
22 | int ok = 0; | |
23 | BIGNUM *tmp = NULL; | |
24 | BN_CTX *ctx = NULL; | |
25 | ||
26 | *ret = 0; | |
bcec03c3 | 27 | if (params == NULL || pub_key == NULL || params->p == NULL) { |
28 | *ret = FFC_ERROR_PASSED_NULL_PARAM; | |
29 | return 0; | |
30 | } | |
31 | ||
8083fd3a SL |
32 | ctx = BN_CTX_new_ex(NULL); |
33 | if (ctx == NULL) | |
34 | goto err; | |
35 | ||
36 | BN_CTX_start(ctx); | |
37 | tmp = BN_CTX_get(ctx); | |
38 | /* Step(1): Verify pub_key >= 2 */ | |
39 | if (tmp == NULL | |
40 | || !BN_set_word(tmp, 1)) | |
41 | goto err; | |
42 | if (BN_cmp(pub_key, tmp) <= 0) { | |
43 | *ret |= FFC_ERROR_PUBKEY_TOO_SMALL; | |
44 | goto err; | |
45 | } | |
46 | /* Step(1): Verify pub_key <= p-2 */ | |
47 | if (BN_copy(tmp, params->p) == NULL | |
48 | || !BN_sub_word(tmp, 1)) | |
49 | goto err; | |
50 | if (BN_cmp(pub_key, tmp) >= 0) { | |
51 | *ret |= FFC_ERROR_PUBKEY_TOO_LARGE; | |
52 | goto err; | |
53 | } | |
54 | ok = 1; | |
55 | err: | |
56 | if (ctx != NULL) { | |
57 | BN_CTX_end(ctx); | |
58 | BN_CTX_free(ctx); | |
59 | } | |
60 | return ok; | |
61 | } | |
62 | ||
63 | /* | |
64 | * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. | |
65 | */ | |
5357c106 P |
66 | int ossl_ffc_validate_public_key(const FFC_PARAMS *params, |
67 | const BIGNUM *pub_key, int *ret) | |
8083fd3a SL |
68 | { |
69 | int ok = 0; | |
70 | BIGNUM *tmp = NULL; | |
71 | BN_CTX *ctx = NULL; | |
72 | ||
5357c106 | 73 | if (!ossl_ffc_validate_public_key_partial(params, pub_key, ret)) |
8083fd3a SL |
74 | return 0; |
75 | ||
76 | if (params->q != NULL) { | |
77 | ctx = BN_CTX_new_ex(NULL); | |
78 | if (ctx == NULL) | |
79 | goto err; | |
80 | BN_CTX_start(ctx); | |
81 | tmp = BN_CTX_get(ctx); | |
82 | ||
83 | /* Check pub_key^q == 1 mod p */ | |
84 | if (tmp == NULL | |
85 | || !BN_mod_exp(tmp, pub_key, params->q, params->p, ctx)) | |
86 | goto err; | |
87 | if (!BN_is_one(tmp)) { | |
88 | *ret |= FFC_ERROR_PUBKEY_INVALID; | |
89 | goto err; | |
90 | } | |
91 | } | |
92 | ||
93 | ok = 1; | |
94 | err: | |
95 | if (ctx != NULL) { | |
96 | BN_CTX_end(ctx); | |
97 | BN_CTX_free(ctx); | |
98 | } | |
99 | return ok; | |
100 | } | |
101 | ||
102 | /* | |
103 | * See SP800-56Ar3 Section 5.6.2.1.2: Owner assurance of Private key validity. | |
104 | * Verifies priv_key is in the range [1..upper-1]. The passed in value of upper | |
105 | * is normally params->q but can be 2^N for approved safe prime groups. | |
106 | * Note: This assumes that the domain parameters are valid. | |
107 | */ | |
5357c106 P |
108 | int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv, |
109 | int *ret) | |
8083fd3a SL |
110 | { |
111 | int ok = 0; | |
112 | ||
113 | *ret = 0; | |
114 | ||
bcec03c3 | 115 | if (priv == NULL || upper == NULL) { |
116 | *ret = FFC_ERROR_PASSED_NULL_PARAM; | |
117 | goto err; | |
118 | } | |
8083fd3a SL |
119 | if (BN_cmp(priv, BN_value_one()) < 0) { |
120 | *ret |= FFC_ERROR_PRIVKEY_TOO_SMALL; | |
121 | goto err; | |
122 | } | |
123 | if (BN_cmp(priv, upper) >= 0) { | |
124 | *ret |= FFC_ERROR_PRIVKEY_TOO_LARGE; | |
125 | goto err; | |
126 | } | |
127 | ok = 1; | |
128 | err: | |
129 | return ok; | |
130 | } |