OSSL_STORE: Add reference docs for the built-in Windows store implementation
[openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2  * Copyright 2006-2021 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 /*
11  * DH & DSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <stdio.h>
17 #include "internal/cryptlib.h"
18 #include <openssl/asn1t.h>
19 #include <openssl/x509.h>
20 #include <openssl/evp.h>
21 #include "dh_local.h"
22 #include <openssl/bn.h>
23 #include <openssl/dsa.h>
24 #include <openssl/objects.h>
25 #include "crypto/evp.h"
26
27 /* DH pkey context structure */
28
29 typedef struct {
30     /* Parameter gen parameters */
31     int prime_len;
32     int generator;
33     int paramgen_type;
34     int subprime_len;
35     int pad;
36     /* message digest used for parameter generation */
37     const EVP_MD *md;
38     int param_nid;
39     /* Keygen callback info */
40     int gentmp[2];
41     /* KDF (if any) to use for DH */
42     char kdf_type;
43     /* OID to use for KDF */
44     ASN1_OBJECT *kdf_oid;
45     /* Message digest to use for key derivation */
46     const EVP_MD *kdf_md;
47     /* User key material */
48     unsigned char *kdf_ukm;
49     size_t kdf_ukmlen;
50     /* KDF output length */
51     size_t kdf_outlen;
52 } DH_PKEY_CTX;
53
54 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
55 {
56     DH_PKEY_CTX *dctx;
57
58     if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
59         ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
60         return 0;
61     }
62     dctx->prime_len = 2048;
63     dctx->subprime_len = -1;
64     dctx->generator = 2;
65     dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
66
67     ctx->data = dctx;
68     ctx->keygen_info = dctx->gentmp;
69     ctx->keygen_info_count = 2;
70
71     return 1;
72 }
73
74 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
75 {
76     DH_PKEY_CTX *dctx = ctx->data;
77
78     if (dctx != NULL) {
79         OPENSSL_free(dctx->kdf_ukm);
80         ASN1_OBJECT_free(dctx->kdf_oid);
81         OPENSSL_free(dctx);
82     }
83 }
84
85
86 static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
87 {
88     DH_PKEY_CTX *dctx, *sctx;
89
90     if (!pkey_dh_init(dst))
91         return 0;
92     sctx = src->data;
93     dctx = dst->data;
94     dctx->prime_len = sctx->prime_len;
95     dctx->subprime_len = sctx->subprime_len;
96     dctx->generator = sctx->generator;
97     dctx->paramgen_type = sctx->paramgen_type;
98     dctx->pad = sctx->pad;
99     dctx->md = sctx->md;
100     dctx->param_nid = sctx->param_nid;
101
102     dctx->kdf_type = sctx->kdf_type;
103     dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
104     if (dctx->kdf_oid == NULL)
105         return 0;
106     dctx->kdf_md = sctx->kdf_md;
107     if (sctx->kdf_ukm != NULL) {
108         dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
109         if (dctx->kdf_ukm == NULL)
110           return 0;
111         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
112     }
113     dctx->kdf_outlen = sctx->kdf_outlen;
114     return 1;
115 }
116
117 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
118 {
119     DH_PKEY_CTX *dctx = ctx->data;
120     switch (type) {
121     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
122         if (p1 < 256)
123             return -2;
124         dctx->prime_len = p1;
125         return 1;
126
127     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
128         if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
129             return -2;
130         dctx->subprime_len = p1;
131         return 1;
132
133     case EVP_PKEY_CTRL_DH_PAD:
134         dctx->pad = p1;
135         return 1;
136
137     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
138         if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
139             return -2;
140         dctx->generator = p1;
141         return 1;
142
143     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
144 #ifdef OPENSSL_NO_DSA
145         if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
146             return -2;
147 #else
148         if (p1 < 0 || p1 > 2)
149             return -2;
150 #endif
151         dctx->paramgen_type = p1;
152         return 1;
153
154     case EVP_PKEY_CTRL_DH_RFC5114:
155         if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
156             return -2;
157         dctx->param_nid = p1;
158         return 1;
159
160     case EVP_PKEY_CTRL_DH_NID:
161         if (p1 <= 0 || dctx->param_nid != NID_undef)
162             return -2;
163         dctx->param_nid = p1;
164         return 1;
165
166     case EVP_PKEY_CTRL_PEER_KEY:
167         /* Default behaviour is OK */
168         return 1;
169
170     case EVP_PKEY_CTRL_DH_KDF_TYPE:
171         if (p1 == -2)
172             return dctx->kdf_type;
173         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
174             return -2;
175         dctx->kdf_type = p1;
176         return 1;
177
178     case EVP_PKEY_CTRL_DH_KDF_MD:
179         dctx->kdf_md = p2;
180         return 1;
181
182     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
183         *(const EVP_MD **)p2 = dctx->kdf_md;
184         return 1;
185
186     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
187         if (p1 <= 0)
188             return -2;
189         dctx->kdf_outlen = (size_t)p1;
190         return 1;
191
192     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
193         *(int *)p2 = dctx->kdf_outlen;
194         return 1;
195
196     case EVP_PKEY_CTRL_DH_KDF_UKM:
197         OPENSSL_free(dctx->kdf_ukm);
198         dctx->kdf_ukm = p2;
199         if (p2)
200             dctx->kdf_ukmlen = p1;
201         else
202             dctx->kdf_ukmlen = 0;
203         return 1;
204
205     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
206         *(unsigned char **)p2 = dctx->kdf_ukm;
207         return dctx->kdf_ukmlen;
208
209     case EVP_PKEY_CTRL_DH_KDF_OID:
210         ASN1_OBJECT_free(dctx->kdf_oid);
211         dctx->kdf_oid = p2;
212         return 1;
213
214     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
215         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
216         return 1;
217
218     default:
219         return -2;
220
221     }
222 }
223
224 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
225                             const char *type, const char *value)
226 {
227     if (strcmp(type, "dh_paramgen_prime_len") == 0) {
228         int len;
229         len = atoi(value);
230         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
231     }
232     if (strcmp(type, "dh_rfc5114") == 0) {
233         DH_PKEY_CTX *dctx = ctx->data;
234         int id;
235
236         id = atoi(value);
237         if (id < 0 || id > 3)
238             return -2;
239         dctx->param_nid = id;
240         return 1;
241     }
242     if (strcmp(type, "dh_param") == 0) {
243         DH_PKEY_CTX *dctx = ctx->data;
244         int nid = OBJ_sn2nid(value);
245
246         if (nid == NID_undef) {
247             ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
248             return -2;
249         }
250         dctx->param_nid = nid;
251         return 1;
252     }
253     if (strcmp(type, "dh_paramgen_generator") == 0) {
254         int len;
255         len = atoi(value);
256         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
257     }
258     if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
259         int len;
260         len = atoi(value);
261         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
262     }
263     if (strcmp(type, "dh_paramgen_type") == 0) {
264         int typ;
265         typ = atoi(value);
266         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
267     }
268     if (strcmp(type, "dh_pad") == 0) {
269         int pad;
270         pad = atoi(value);
271         return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
272     }
273     return -2;
274 }
275
276 static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
277                                BN_GENCB *pcb)
278 {
279     DH *ret;
280     int rv = 0;
281     int res;
282     int prime_len = dctx->prime_len;
283     int subprime_len = dctx->subprime_len;
284
285     if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
286         return NULL;
287     ret = DH_new();
288     if (ret == NULL)
289         return NULL;
290
291     if (subprime_len == -1) {
292         if (prime_len >= 2048)
293             subprime_len = 256;
294         else
295             subprime_len = 160;
296     }
297
298     if (dctx->md != NULL)
299         ossl_ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL);
300
301 # ifndef FIPS_MODULE
302     if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
303         rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
304                                                 FFC_PARAM_TYPE_DH,
305                                                 prime_len, subprime_len, &res,
306                                                 pcb);
307     else
308 # endif
309     /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
310     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
311         rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
312                                                 FFC_PARAM_TYPE_DH,
313                                                 prime_len, subprime_len, &res,
314                                                 pcb);
315     if (rv <= 0) {
316         DH_free(ret);
317         return NULL;
318     }
319     return ret;
320 }
321
322 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
323                             EVP_PKEY *pkey)
324 {
325     DH *dh = NULL;
326     DH_PKEY_CTX *dctx = ctx->data;
327     BN_GENCB *pcb = NULL;
328     int ret;
329
330     /*
331      * Look for a safe prime group for key establishment. Which uses
332      * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
333      * RFC_5114 is also handled here for param_nid = (1..3)
334      */
335     if (dctx->param_nid != NID_undef) {
336         int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH;
337
338         if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
339             return 0;
340         EVP_PKEY_assign(pkey, type, dh);
341         return 1;
342     }
343
344     if (ctx->pkey_gencb != NULL) {
345         pcb = BN_GENCB_new();
346         if (pcb == NULL)
347             return 0;
348         evp_pkey_set_cb_translate(pcb, ctx);
349     }
350 # ifdef FIPS_MODULE
351     dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
352 # endif /* FIPS_MODULE */
353     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
354         dh = ffc_params_generate(NULL, dctx, pcb);
355         BN_GENCB_free(pcb);
356         if (dh == NULL)
357             return 0;
358         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
359         return 1;
360     }
361     dh = DH_new();
362     if (dh == NULL) {
363         BN_GENCB_free(pcb);
364         return 0;
365     }
366     ret = DH_generate_parameters_ex(dh,
367                                     dctx->prime_len, dctx->generator, pcb);
368     BN_GENCB_free(pcb);
369     if (ret)
370         EVP_PKEY_assign_DH(pkey, dh);
371     else
372         DH_free(dh);
373     return ret;
374 }
375
376 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
377 {
378     DH_PKEY_CTX *dctx = ctx->data;
379     DH *dh = NULL;
380
381     if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
382         ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
383         return 0;
384     }
385     if (dctx->param_nid != NID_undef)
386         dh = DH_new_by_nid(dctx->param_nid);
387     else
388         dh = DH_new();
389     if (dh == NULL)
390         return 0;
391     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
392     /* Note: if error return, pkey is freed by parent routine */
393     if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
394         return 0;
395     return DH_generate_key(pkey->pkey.dh);
396 }
397
398 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
399                           size_t *keylen)
400 {
401     int ret;
402     DH *dh;
403     const DH *dhpub;
404     DH_PKEY_CTX *dctx = ctx->data;
405     BIGNUM *dhpubbn;
406
407     if (ctx->pkey == NULL || ctx->peerkey == NULL) {
408         ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
409         return 0;
410     }
411     dh = ctx->pkey->pkey.dh;
412     dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
413     if (dhpub == NULL) {
414         ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
415         return 0;
416     }
417     dhpubbn = dhpub->pub_key;
418     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
419         if (key == NULL) {
420             *keylen = DH_size(dh);
421             return 1;
422         }
423         if (dctx->pad)
424             ret = DH_compute_key_padded(key, dhpubbn, dh);
425         else
426             ret = DH_compute_key(key, dhpubbn, dh);
427         if (ret < 0)
428             return ret;
429         *keylen = ret;
430         return 1;
431     }
432     else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
433
434         unsigned char *Z = NULL;
435         size_t Zlen = 0;
436         if (!dctx->kdf_outlen || !dctx->kdf_oid)
437             return 0;
438         if (key == NULL) {
439             *keylen = dctx->kdf_outlen;
440             return 1;
441         }
442         if (*keylen != dctx->kdf_outlen)
443             return 0;
444         ret = 0;
445         if ((Zlen = DH_size(dh)) <= 0)
446             return 0;
447         if ((Z = OPENSSL_malloc(Zlen)) == NULL) {
448             ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
449             return 0;
450         }
451         if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0)
452             goto err;
453         if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
454                           dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
455             goto err;
456         *keylen = dctx->kdf_outlen;
457         ret = 1;
458  err:
459         OPENSSL_clear_free(Z, Zlen);
460         return ret;
461     }
462     return 0;
463 }
464
465 static const EVP_PKEY_METHOD dh_pkey_meth = {
466     EVP_PKEY_DH,
467     0,
468     pkey_dh_init,
469     pkey_dh_copy,
470     pkey_dh_cleanup,
471
472     0,
473     pkey_dh_paramgen,
474
475     0,
476     pkey_dh_keygen,
477
478     0,
479     0,
480
481     0,
482     0,
483
484     0, 0,
485
486     0, 0, 0, 0,
487
488     0, 0,
489
490     0, 0,
491
492     0,
493     pkey_dh_derive,
494
495     pkey_dh_ctrl,
496     pkey_dh_ctrl_str
497 };
498
499 const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
500 {
501     return &dh_pkey_meth;
502 }
503
504 static const EVP_PKEY_METHOD dhx_pkey_meth = {
505     EVP_PKEY_DHX,
506     0,
507     pkey_dh_init,
508     pkey_dh_copy,
509     pkey_dh_cleanup,
510
511     0,
512     pkey_dh_paramgen,
513
514     0,
515     pkey_dh_keygen,
516
517     0,
518     0,
519
520     0,
521     0,
522
523     0, 0,
524
525     0, 0, 0, 0,
526
527     0, 0,
528
529     0, 0,
530
531     0,
532     pkey_dh_derive,
533
534     pkey_dh_ctrl,
535     pkey_dh_ctrl_str
536 };
537
538 const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
539 {
540     return &dhx_pkey_meth;
541 }