1 /* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL project
2 * 2006.
3 */
4 /* ====================================================================
5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * [email protected].
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * ([email protected]). This product includes software written by Tim
54 * Hudson ([email protected]). */
55
56 #include <openssl/evp.h>
57
58 #include <openssl/digest.h>
59 #include <openssl/bn.h>
60 #include <openssl/bytestring.h>
61 #include <openssl/dsa.h>
62 #include <openssl/err.h>
63
64 #include "../dsa/internal.h"
65 #include "internal.h"
66
67
dsa_pub_decode(EVP_PKEY * out,CBS * params,CBS * key)68 static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
69 // See RFC 3279, section 2.3.2.
70
71 // Parameters may or may not be present.
72 DSA *dsa;
73 if (CBS_len(params) == 0) {
74 dsa = DSA_new();
75 if (dsa == NULL) {
76 return 0;
77 }
78 } else {
79 dsa = DSA_parse_parameters(params);
80 if (dsa == NULL || CBS_len(params) != 0) {
81 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
82 goto err;
83 }
84 }
85
86 dsa->pub_key = BN_new();
87 if (dsa->pub_key == NULL) {
88 goto err;
89 }
90
91 if (!BN_parse_asn1_unsigned(key, dsa->pub_key) ||
92 CBS_len(key) != 0) {
93 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
94 goto err;
95 }
96
97 EVP_PKEY_assign_DSA(out, dsa);
98 return 1;
99
100 err:
101 DSA_free(dsa);
102 return 0;
103 }
104
dsa_pub_encode(CBB * out,const EVP_PKEY * key)105 static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
106 const DSA *dsa = key->pkey;
107 const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
108
109 // See RFC 5480, section 2.
110 CBB spki, algorithm, oid, key_bitstring;
111 if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
112 !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
113 !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
114 !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
115 (has_params &&
116 !DSA_marshal_parameters(&algorithm, dsa)) ||
117 !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
118 !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
119 !BN_marshal_asn1(&key_bitstring, dsa->pub_key) ||
120 !CBB_flush(out)) {
121 OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
122 return 0;
123 }
124
125 return 1;
126 }
127
dsa_priv_decode(EVP_PKEY * out,CBS * params,CBS * key)128 static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
129 // See PKCS#11, v2.40, section 2.5.
130
131 // Decode parameters.
132 BN_CTX *ctx = NULL;
133 DSA *dsa = DSA_parse_parameters(params);
134 if (dsa == NULL || CBS_len(params) != 0) {
135 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
136 goto err;
137 }
138
139 dsa->priv_key = BN_new();
140 if (dsa->priv_key == NULL) {
141 goto err;
142 }
143 if (!BN_parse_asn1_unsigned(key, dsa->priv_key) ||
144 CBS_len(key) != 0) {
145 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
146 goto err;
147 }
148
149 // To avoid DoS attacks when importing private keys, check bounds on |dsa|.
150 // This bounds |dsa->priv_key| against |dsa->q| and bounds |dsa->q|'s bit
151 // width.
152 if (!dsa_check_key(dsa)) {
153 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
154 goto err;
155 }
156
157 // Calculate the public key.
158 ctx = BN_CTX_new();
159 dsa->pub_key = BN_new();
160 if (ctx == NULL || dsa->pub_key == NULL ||
161 !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p,
162 ctx, NULL)) {
163 goto err;
164 }
165
166 BN_CTX_free(ctx);
167 EVP_PKEY_assign_DSA(out, dsa);
168 return 1;
169
170 err:
171 BN_CTX_free(ctx);
172 DSA_free(dsa);
173 return 0;
174 }
175
dsa_priv_encode(CBB * out,const EVP_PKEY * key)176 static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
177 const DSA *dsa = key->pkey;
178 if (dsa == NULL || dsa->priv_key == NULL) {
179 OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
180 return 0;
181 }
182
183 // See PKCS#11, v2.40, section 2.5.
184 CBB pkcs8, algorithm, oid, private_key;
185 if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
186 !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
187 !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
188 !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
189 !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
190 !DSA_marshal_parameters(&algorithm, dsa) ||
191 !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
192 !BN_marshal_asn1(&private_key, dsa->priv_key) ||
193 !CBB_flush(out)) {
194 OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
195 return 0;
196 }
197
198 return 1;
199 }
200
int_dsa_size(const EVP_PKEY * pkey)201 static int int_dsa_size(const EVP_PKEY *pkey) {
202 const DSA *dsa = pkey->pkey;
203 return DSA_size(dsa);
204 }
205
dsa_bits(const EVP_PKEY * pkey)206 static int dsa_bits(const EVP_PKEY *pkey) {
207 const DSA *dsa = pkey->pkey;
208 return BN_num_bits(DSA_get0_p(dsa));
209 }
210
dsa_missing_parameters(const EVP_PKEY * pkey)211 static int dsa_missing_parameters(const EVP_PKEY *pkey) {
212 const DSA *dsa = pkey->pkey;
213 if (DSA_get0_p(dsa) == NULL || DSA_get0_q(dsa) == NULL ||
214 DSA_get0_g(dsa) == NULL) {
215 return 1;
216 }
217 return 0;
218 }
219
dup_bn_into(BIGNUM ** out,BIGNUM * src)220 static int dup_bn_into(BIGNUM **out, BIGNUM *src) {
221 BIGNUM *a;
222
223 a = BN_dup(src);
224 if (a == NULL) {
225 return 0;
226 }
227 BN_free(*out);
228 *out = a;
229
230 return 1;
231 }
232
dsa_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)233 static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
234 DSA *to_dsa = to->pkey;
235 const DSA *from_dsa = from->pkey;
236 if (!dup_bn_into(&to_dsa->p, from_dsa->p) ||
237 !dup_bn_into(&to_dsa->q, from_dsa->q) ||
238 !dup_bn_into(&to_dsa->g, from_dsa->g)) {
239 return 0;
240 }
241
242 return 1;
243 }
244
dsa_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)245 static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
246 const DSA *a_dsa = a->pkey;
247 const DSA *b_dsa = b->pkey;
248 return BN_cmp(DSA_get0_p(a_dsa), DSA_get0_p(b_dsa)) == 0 &&
249 BN_cmp(DSA_get0_q(a_dsa), DSA_get0_q(b_dsa)) == 0 &&
250 BN_cmp(DSA_get0_g(a_dsa), DSA_get0_g(b_dsa)) == 0;
251 }
252
dsa_pub_cmp(const EVP_PKEY * a,const EVP_PKEY * b)253 static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
254 const DSA *a_dsa = a->pkey;
255 const DSA *b_dsa = b->pkey;
256 return BN_cmp(DSA_get0_pub_key(b_dsa), DSA_get0_pub_key(a_dsa)) == 0;
257 }
258
int_dsa_free(EVP_PKEY * pkey)259 static void int_dsa_free(EVP_PKEY *pkey) {
260 DSA_free(pkey->pkey);
261 pkey->pkey = NULL;
262 }
263
264 const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
265 EVP_PKEY_DSA,
266 // 1.2.840.10040.4.1
267 {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01},
268 7,
269
270 /*pkey_method=*/NULL,
271
272 dsa_pub_decode,
273 dsa_pub_encode,
274 dsa_pub_cmp,
275
276 dsa_priv_decode,
277 dsa_priv_encode,
278
279 /*set_priv_raw=*/NULL,
280 /*set_pub_raw=*/NULL,
281 /*get_priv_raw=*/NULL,
282 /*get_pub_raw=*/NULL,
283 /*set1_tls_encodedpoint=*/NULL,
284 /*get1_tls_encodedpoint=*/NULL,
285
286 /*pkey_opaque=*/NULL,
287
288 int_dsa_size,
289 dsa_bits,
290
291 dsa_missing_parameters,
292 dsa_copy_parameters,
293 dsa_cmp_parameters,
294
295 int_dsa_free,
296 };
297
EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX * ctx,int nbits)298 int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) {
299 // BoringSSL does not support DSA in |EVP_PKEY_CTX|.
300 OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
301 return 0;
302 }
303
EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX * ctx,int qbits)304 int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits) {
305 // BoringSSL does not support DSA in |EVP_PKEY_CTX|.
306 OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
307 return 0;
308 }
309
EVP_PKEY_set1_DSA(EVP_PKEY * pkey,DSA * key)310 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
311 if (EVP_PKEY_assign_DSA(pkey, key)) {
312 DSA_up_ref(key);
313 return 1;
314 }
315 return 0;
316 }
317
EVP_PKEY_assign_DSA(EVP_PKEY * pkey,DSA * key)318 int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
319 evp_pkey_set_method(pkey, &dsa_asn1_meth);
320 pkey->pkey = key;
321 return key != NULL;
322 }
323
EVP_PKEY_get0_DSA(const EVP_PKEY * pkey)324 DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) {
325 if (pkey->type != EVP_PKEY_DSA) {
326 OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
327 return NULL;
328 }
329 return pkey->pkey;
330 }
331
EVP_PKEY_get1_DSA(const EVP_PKEY * pkey)332 DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) {
333 DSA *dsa = EVP_PKEY_get0_DSA(pkey);
334 if (dsa != NULL) {
335 DSA_up_ref(dsa);
336 }
337 return dsa;
338 }
339