/src/boringssl/crypto/dsa/dsa_asn1.cc
Line | Count | Source |
1 | | // Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <openssl/dsa.h> |
16 | | |
17 | | #include <assert.h> |
18 | | |
19 | | #include <openssl/bn.h> |
20 | | #include <openssl/bytestring.h> |
21 | | #include <openssl/err.h> |
22 | | #include <openssl/mem.h> |
23 | | |
24 | | #include "../bytestring/internal.h" |
25 | | #include "../mem_internal.h" |
26 | | #include "internal.h" |
27 | | |
28 | | |
29 | | using namespace bssl; |
30 | | |
31 | | // This function is in dsa_asn1.c rather than dsa.c because it is reachable from |
32 | | // `EVP_PKEY` parsers. This makes it easier for the static linker to drop most |
33 | | // of the DSA implementation. |
34 | 4.29k | int bssl::dsa_check_key(const DSAImpl *dsa) { |
35 | 4.29k | if (!dsa->p || !dsa->q || !dsa->g) { |
36 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); |
37 | 0 | return 0; |
38 | 0 | } |
39 | | |
40 | | // Fully checking for invalid DSA groups is expensive, so security and |
41 | | // correctness of the signature scheme depend on how `dsa` was computed. I.e. |
42 | | // we leave "assurance of domain parameter validity" from FIPS 186-4 to the |
43 | | // caller. However, we check bounds on all values to avoid DoS vectors even |
44 | | // when domain parameters are invalid. In particular, signing will infinite |
45 | | // loop if `g` is zero. |
46 | 4.29k | if (BN_is_negative(dsa->p.get()) || BN_is_negative(dsa->q.get()) || |
47 | 4.29k | BN_is_zero(dsa->p.get()) || BN_is_zero(dsa->q.get()) || |
48 | 4.27k | !BN_is_odd(dsa->p.get()) || !BN_is_odd(dsa->q.get()) || |
49 | | // `q` must be a prime divisor of `p - 1`, which implies `q < p`. |
50 | 4.18k | BN_cmp(dsa->q.get(), dsa->p.get()) >= 0 || |
51 | | // `g` is in the multiplicative group of `p`. |
52 | 3.81k | BN_is_negative(dsa->g.get()) || BN_is_zero(dsa->g.get()) || |
53 | 3.72k | BN_cmp(dsa->g.get(), dsa->p.get()) >= 0) { |
54 | 1.02k | OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); |
55 | 1.02k | return 0; |
56 | 1.02k | } |
57 | | |
58 | | // FIPS 186-4 allows only three different sizes for q. |
59 | 3.26k | unsigned q_bits = BN_num_bits(dsa->q.get()); |
60 | 3.26k | if (q_bits != 160 && q_bits != 224 && q_bits != 256) { |
61 | 1.28k | OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE); |
62 | 1.28k | return 0; |
63 | 1.28k | } |
64 | | |
65 | | // Bound `dsa->p` to avoid a DoS vector. Note this limit is much larger than |
66 | | // the one in FIPS 186-4, which only allows L = 1024, 2048, and 3072. |
67 | 1.98k | if (BN_num_bits(dsa->p.get()) > OPENSSL_DSA_MAX_MODULUS_BITS) { |
68 | 16 | OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE); |
69 | 16 | return 0; |
70 | 16 | } |
71 | | |
72 | 1.96k | if (dsa->pub_key != nullptr) { |
73 | | // The public key is also in the multiplicative group of `p`. |
74 | 13 | if (BN_is_negative(dsa->pub_key.get()) || BN_is_zero(dsa->pub_key.get()) || |
75 | 12 | BN_cmp(dsa->pub_key.get(), dsa->p.get()) >= 0) { |
76 | 3 | OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); |
77 | 3 | return 0; |
78 | 3 | } |
79 | 13 | } |
80 | | |
81 | 1.96k | if (dsa->priv_key != nullptr) { |
82 | | // The private key is a non-zero element of the scalar field, determined by |
83 | | // `q`. |
84 | 930 | if (BN_is_negative(dsa->priv_key.get()) || |
85 | 930 | constant_time_declassify_int(BN_is_zero(dsa->priv_key.get())) || |
86 | 921 | constant_time_declassify_int( |
87 | 921 | BN_cmp(dsa->priv_key.get(), dsa->q.get()) >= 0)) { |
88 | 17 | OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS); |
89 | 17 | return 0; |
90 | 17 | } |
91 | 930 | } |
92 | | |
93 | 1.94k | return 1; |
94 | 1.96k | } |
95 | | |
96 | 12.1k | static int parse_integer(CBS *cbs, UniquePtr<BIGNUM> *out) { |
97 | 12.1k | assert(*out == nullptr); |
98 | 12.1k | out->reset(BN_new()); |
99 | 12.1k | if (*out == nullptr) { |
100 | 0 | return 0; |
101 | 0 | } |
102 | 12.1k | return BN_parse_asn1_unsigned(cbs, out->get()); |
103 | 12.1k | } |
104 | | |
105 | 2.78k | static int marshal_integer(CBB *cbb, BIGNUM *bn) { |
106 | 2.78k | if (bn == nullptr) { |
107 | | // A DSA object may be missing some components. |
108 | 0 | OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER); |
109 | 0 | return 0; |
110 | 0 | } |
111 | 2.78k | return BN_marshal_asn1(cbb, bn); |
112 | 2.78k | } |
113 | | |
114 | 0 | DSA_SIG *DSA_SIG_parse(CBS *cbs) { |
115 | 0 | DSA_SIG *ret = DSA_SIG_new(); |
116 | 0 | if (ret == nullptr) { |
117 | 0 | return nullptr; |
118 | 0 | } |
119 | 0 | CBS child; |
120 | 0 | UniquePtr<BIGNUM> r, s; |
121 | 0 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
122 | 0 | !parse_integer(&child, &r) || |
123 | 0 | !parse_integer(&child, &s) || |
124 | 0 | CBS_len(&child) != 0) { |
125 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); |
126 | 0 | DSA_SIG_free(ret); |
127 | 0 | return nullptr; |
128 | 0 | } |
129 | 0 | ret->r = r.release(); |
130 | 0 | ret->s = s.release(); |
131 | 0 | return ret; |
132 | 0 | } |
133 | | |
134 | 0 | int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) { |
135 | 0 | CBB child; |
136 | 0 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
137 | 0 | !marshal_integer(&child, sig->r) || |
138 | 0 | !marshal_integer(&child, sig->s) || |
139 | 0 | !CBB_flush(cbb)) { |
140 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); |
141 | 0 | return 0; |
142 | 0 | } |
143 | 0 | return 1; |
144 | 0 | } |
145 | | |
146 | 0 | DSA *DSA_parse_public_key(CBS *cbs) { |
147 | 0 | UniquePtr<DSAImpl> ret(FromOpaque(DSA_new())); |
148 | 0 | if (ret == nullptr) { |
149 | 0 | return nullptr; |
150 | 0 | } |
151 | 0 | CBS child; |
152 | 0 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
153 | 0 | !parse_integer(&child, &ret->pub_key) || |
154 | 0 | !parse_integer(&child, &ret->p) || |
155 | 0 | !parse_integer(&child, &ret->q) || |
156 | 0 | !parse_integer(&child, &ret->g) || |
157 | 0 | CBS_len(&child) != 0) { |
158 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); |
159 | 0 | return nullptr; |
160 | 0 | } |
161 | 0 | if (!dsa_check_key(ret.get())) { |
162 | 0 | return nullptr; |
163 | 0 | } |
164 | 0 | return ret.release(); |
165 | 0 | } |
166 | | |
167 | 0 | int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) { |
168 | 0 | const auto *impl = FromOpaque(dsa); |
169 | |
|
170 | 0 | CBB child; |
171 | 0 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
172 | 0 | !marshal_integer(&child, impl->pub_key.get()) || |
173 | 0 | !marshal_integer(&child, impl->p.get()) || |
174 | 0 | !marshal_integer(&child, impl->q.get()) || |
175 | 0 | !marshal_integer(&child, impl->g.get()) || !CBB_flush(cbb)) { |
176 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); |
177 | 0 | return 0; |
178 | 0 | } |
179 | 0 | return 1; |
180 | 0 | } |
181 | | |
182 | 5.90k | DSA *DSA_parse_parameters(CBS *cbs) { |
183 | 5.90k | UniquePtr<DSAImpl> ret(FromOpaque(DSA_new())); |
184 | 5.90k | if (ret == nullptr) { |
185 | 0 | return nullptr; |
186 | 0 | } |
187 | 5.90k | CBS child; |
188 | 5.90k | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
189 | 3.61k | !parse_integer(&child, &ret->p) || |
190 | 3.08k | !parse_integer(&child, &ret->q) || |
191 | 2.94k | !parse_integer(&child, &ret->g) || |
192 | 3.01k | CBS_len(&child) != 0) { |
193 | 3.01k | OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); |
194 | 3.01k | return nullptr; |
195 | 3.01k | } |
196 | 2.88k | if (!dsa_check_key(ret.get())) { |
197 | 1.85k | return nullptr; |
198 | 1.85k | } |
199 | 1.03k | return ret.release(); |
200 | 2.88k | } |
201 | | |
202 | 928 | int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) { |
203 | 928 | const auto *impl = FromOpaque(dsa); |
204 | | |
205 | 928 | CBB child; |
206 | 928 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
207 | 928 | !marshal_integer(&child, impl->p.get()) || |
208 | 928 | !marshal_integer(&child, impl->q.get()) || |
209 | 928 | !marshal_integer(&child, impl->g.get()) || !CBB_flush(cbb)) { |
210 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); |
211 | 0 | return 0; |
212 | 0 | } |
213 | 928 | return 1; |
214 | 928 | } |
215 | | |
216 | 624 | DSA *DSA_parse_private_key(CBS *cbs) { |
217 | 624 | UniquePtr<DSAImpl> ret(FromOpaque(DSA_new())); |
218 | 624 | if (ret == nullptr) { |
219 | 0 | return nullptr; |
220 | 0 | } |
221 | | |
222 | 624 | CBS child; |
223 | 624 | uint64_t version; |
224 | 624 | if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || |
225 | 624 | !CBS_get_asn1_uint64(&child, &version)) { |
226 | 2 | OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); |
227 | 2 | return nullptr; |
228 | 2 | } |
229 | | |
230 | 622 | if (version != 0) { |
231 | 126 | OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION); |
232 | 126 | return nullptr; |
233 | 126 | } |
234 | | |
235 | 496 | if (!parse_integer(&child, &ret->p) || |
236 | 493 | !parse_integer(&child, &ret->q) || |
237 | 492 | !parse_integer(&child, &ret->g) || |
238 | 491 | !parse_integer(&child, &ret->pub_key) || |
239 | 490 | !parse_integer(&child, &ret->priv_key) || |
240 | 489 | CBS_len(&child) != 0) { |
241 | 7 | OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); |
242 | 7 | return nullptr; |
243 | 7 | } |
244 | 489 | if (!dsa_check_key(ret.get())) { |
245 | 483 | return nullptr; |
246 | 483 | } |
247 | | |
248 | 6 | return ret.release(); |
249 | 489 | } |
250 | | |
251 | 0 | int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) { |
252 | 0 | const auto *impl = FromOpaque(dsa); |
253 | |
|
254 | 0 | CBB child; |
255 | 0 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || |
256 | 0 | !CBB_add_asn1_uint64(&child, 0 /* version */) || |
257 | 0 | !marshal_integer(&child, impl->p.get()) || |
258 | 0 | !marshal_integer(&child, impl->q.get()) || |
259 | 0 | !marshal_integer(&child, impl->g.get()) || |
260 | 0 | !marshal_integer(&child, impl->pub_key.get()) || |
261 | 0 | !marshal_integer(&child, impl->priv_key.get()) || !CBB_flush(cbb)) { |
262 | 0 | OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); |
263 | 0 | return 0; |
264 | 0 | } |
265 | 0 | return 1; |
266 | 0 | } |
267 | | |
268 | 0 | DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) { |
269 | 0 | return D2IFromCBS(out_sig, inp, len, DSA_SIG_parse); |
270 | 0 | } |
271 | | |
272 | 0 | int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) { |
273 | 0 | return I2DFromCBB( |
274 | 0 | /*initial_capacity=*/256, outp, |
275 | 0 | [&](CBB *cbb) -> bool { return DSA_SIG_marshal(cbb, in); }); |
276 | 0 | } |
277 | | |
278 | 0 | DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) { |
279 | 0 | return D2IFromCBS(out, inp, len, DSA_parse_public_key); |
280 | 0 | } |
281 | | |
282 | 0 | int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) { |
283 | 0 | return I2DFromCBB( |
284 | 0 | /*initial_capacity=*/256, outp, |
285 | 0 | [&](CBB *cbb) -> bool { return DSA_marshal_public_key(cbb, in); }); |
286 | 0 | } |
287 | | |
288 | 0 | DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) { |
289 | 0 | return D2IFromCBS(out, inp, len, DSA_parse_private_key); |
290 | 0 | } |
291 | | |
292 | 0 | int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) { |
293 | 0 | return I2DFromCBB( |
294 | 0 | /*initial_capacity=*/256, outp, |
295 | 0 | [&](CBB *cbb) -> bool { return DSA_marshal_private_key(cbb, in); }); |
296 | 0 | } |
297 | | |
298 | 0 | DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) { |
299 | 0 | return D2IFromCBS(out, inp, len, DSA_parse_parameters); |
300 | 0 | } |
301 | | |
302 | 0 | int i2d_DSAparams(const DSA *in, uint8_t **outp) { |
303 | 0 | return I2DFromCBB( |
304 | 0 | /*initial_capacity=*/256, outp, |
305 | 0 | [&](CBB *cbb) -> bool { return DSA_marshal_parameters(cbb, in); }); |
306 | 0 | } |