2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 * DH low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
16 #include <openssl/crypto.h>
17 #include <openssl/core_dispatch.h>
18 #include <openssl/core_names.h>
19 #include <openssl/dh.h>
20 #include <openssl/params.h>
21 #include "prov/implementations.h"
22 #include "prov/provider_ctx.h"
23 #include "crypto/dh.h"
25 static OSSL_FUNC_keyexch_newctx_fn dh_newctx
;
26 static OSSL_FUNC_keyexch_init_fn dh_init
;
27 static OSSL_FUNC_keyexch_set_peer_fn dh_set_peer
;
28 static OSSL_FUNC_keyexch_derive_fn dh_derive
;
29 static OSSL_FUNC_keyexch_freectx_fn dh_freectx
;
30 static OSSL_FUNC_keyexch_dupctx_fn dh_dupctx
;
31 static OSSL_FUNC_keyexch_set_ctx_params_fn dh_set_ctx_params
;
32 static OSSL_FUNC_keyexch_settable_ctx_params_fn dh_settable_ctx_params
;
35 * What's passed as an actual key is defined by the KEYMGMT interface.
36 * We happen to know that our KEYMGMT simply passes DH structures, so
37 * we use that here too.
47 static void *dh_newctx(void *provctx
)
49 PROV_DH_CTX
*pdhctx
= OPENSSL_zalloc(sizeof(PROV_DH_CTX
));
53 pdhctx
->libctx
= PROV_LIBRARY_CONTEXT_OF(provctx
);
57 static int dh_init(void *vpdhctx
, void *vdh
)
59 PROV_DH_CTX
*pdhctx
= (PROV_DH_CTX
*)vpdhctx
;
61 if (pdhctx
== NULL
|| vdh
== NULL
|| !DH_up_ref(vdh
))
68 static int dh_set_peer(void *vpdhctx
, void *vdh
)
70 PROV_DH_CTX
*pdhctx
= (PROV_DH_CTX
*)vpdhctx
;
72 if (pdhctx
== NULL
|| vdh
== NULL
|| !DH_up_ref(vdh
))
74 DH_free(pdhctx
->dhpeer
);
79 static int dh_derive(void *vpdhctx
, unsigned char *secret
, size_t *secretlen
,
82 PROV_DH_CTX
*pdhctx
= (PROV_DH_CTX
*)vpdhctx
;
85 const BIGNUM
*pub_key
= NULL
;
87 /* TODO(3.0): Add errors to stack */
88 if (pdhctx
->dh
== NULL
|| pdhctx
->dhpeer
== NULL
)
91 dhsize
= (size_t)DH_size(pdhctx
->dh
);
99 DH_get0_key(pdhctx
->dhpeer
, &pub_key
, NULL
);
101 ret
= DH_compute_key_padded(secret
, pub_key
, pdhctx
->dh
);
103 ret
= DH_compute_key(secret
, pub_key
, pdhctx
->dh
);
111 static void dh_freectx(void *vpdhctx
)
113 PROV_DH_CTX
*pdhctx
= (PROV_DH_CTX
*)vpdhctx
;
116 DH_free(pdhctx
->dhpeer
);
118 OPENSSL_free(pdhctx
);
121 static void *dh_dupctx(void *vpdhctx
)
123 PROV_DH_CTX
*srcctx
= (PROV_DH_CTX
*)vpdhctx
;
126 dstctx
= OPENSSL_zalloc(sizeof(*srcctx
));
131 if (dstctx
->dh
!= NULL
&& !DH_up_ref(dstctx
->dh
)) {
132 OPENSSL_free(dstctx
);
136 if (dstctx
->dhpeer
!= NULL
&& !DH_up_ref(dstctx
->dhpeer
)) {
138 OPENSSL_free(dstctx
);
145 static int dh_set_ctx_params(void *vpdhctx
, const OSSL_PARAM params
[])
147 PROV_DH_CTX
*pdhctx
= (PROV_DH_CTX
*)vpdhctx
;
151 if (pdhctx
== NULL
|| params
== NULL
)
154 p
= OSSL_PARAM_locate_const(params
, OSSL_EXCHANGE_PARAM_PAD
);
155 if (p
== NULL
|| !OSSL_PARAM_get_uint(p
, &pad
))
157 pdhctx
->pad
= pad
? 1 : 0;
161 static const OSSL_PARAM known_settable_ctx_params
[] = {
162 OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD
, NULL
),
166 static const OSSL_PARAM
*dh_settable_ctx_params(void)
168 return known_settable_ctx_params
;
171 const OSSL_DISPATCH dh_keyexch_functions
[] = {
172 { OSSL_FUNC_KEYEXCH_NEWCTX
, (void (*)(void))dh_newctx
},
173 { OSSL_FUNC_KEYEXCH_INIT
, (void (*)(void))dh_init
},
174 { OSSL_FUNC_KEYEXCH_DERIVE
, (void (*)(void))dh_derive
},
175 { OSSL_FUNC_KEYEXCH_SET_PEER
, (void (*)(void))dh_set_peer
},
176 { OSSL_FUNC_KEYEXCH_FREECTX
, (void (*)(void))dh_freectx
},
177 { OSSL_FUNC_KEYEXCH_DUPCTX
, (void (*)(void))dh_dupctx
},
178 { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS
, (void (*)(void))dh_set_ctx_params
},
179 { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS
,
180 (void (*)(void))dh_settable_ctx_params
},