]>
Commit | Line | Data |
---|---|---|
90d3cb57 MC |
1 | /* |
2 | * Copyright 2020 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 | #include <assert.h> | |
11 | #include <openssl/core_numbers.h> | |
12 | #include <openssl/core_names.h> | |
13 | #include <openssl/params.h> | |
14 | #include "internal/param_build.h" | |
15 | #include "crypto/ecx.h" | |
16 | #include "prov/implementations.h" | |
17 | #include "prov/providercommon.h" | |
18 | ||
19 | static OSSL_OP_keymgmt_new_fn x25519_new_key; | |
20 | static OSSL_OP_keymgmt_new_fn x448_new_key; | |
af6d8dd3 MC |
21 | static OSSL_OP_keymgmt_new_fn ed25519_new_key; |
22 | static OSSL_OP_keymgmt_new_fn ed448_new_key; | |
90d3cb57 MC |
23 | static OSSL_OP_keymgmt_get_params_fn x25519_get_params; |
24 | static OSSL_OP_keymgmt_get_params_fn x448_get_params; | |
af6d8dd3 MC |
25 | static OSSL_OP_keymgmt_get_params_fn ed25519_get_params; |
26 | static OSSL_OP_keymgmt_get_params_fn ed448_get_params; | |
90d3cb57 MC |
27 | static OSSL_OP_keymgmt_gettable_params_fn ecx_gettable_params; |
28 | static OSSL_OP_keymgmt_has_fn ecx_has; | |
29 | static OSSL_OP_keymgmt_import_fn ecx_import; | |
30 | static OSSL_OP_keymgmt_import_types_fn ecx_imexport_types; | |
31 | static OSSL_OP_keymgmt_export_fn ecx_export; | |
32 | static OSSL_OP_keymgmt_export_types_fn ecx_imexport_types; | |
33 | ||
f552d900 SL |
34 | #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR) |
35 | ||
90d3cb57 MC |
36 | static void *x25519_new_key(void *provctx) |
37 | { | |
244bc297 | 38 | return ecx_key_new(ECX_KEY_TYPE_X25519, 0); |
90d3cb57 MC |
39 | } |
40 | ||
41 | static void *x448_new_key(void *provctx) | |
42 | { | |
244bc297 | 43 | return ecx_key_new(ECX_KEY_TYPE_X448, 0); |
90d3cb57 MC |
44 | } |
45 | ||
af6d8dd3 MC |
46 | static void *ed25519_new_key(void *provctx) |
47 | { | |
244bc297 | 48 | return ecx_key_new(ECX_KEY_TYPE_ED25519, 0); |
af6d8dd3 MC |
49 | } |
50 | ||
51 | static void *ed448_new_key(void *provctx) | |
52 | { | |
244bc297 | 53 | return ecx_key_new(ECX_KEY_TYPE_ED448, 0); |
af6d8dd3 MC |
54 | } |
55 | ||
90d3cb57 MC |
56 | static int ecx_has(void *keydata, int selection) |
57 | { | |
58 | ECX_KEY *key = keydata; | |
adc9f731 | 59 | int ok = 0; |
90d3cb57 | 60 | |
adc9f731 RL |
61 | if (key != NULL) { |
62 | if ((selection & ECX_POSSIBLE_SELECTIONS) != 0) | |
63 | ok = 1; | |
90d3cb57 | 64 | |
adc9f731 RL |
65 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) |
66 | ok = ok && key->haspubkey; | |
90d3cb57 | 67 | |
adc9f731 RL |
68 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) |
69 | ok = ok && key->privkey != NULL; | |
70 | } | |
90d3cb57 MC |
71 | return ok; |
72 | } | |
73 | ||
74 | static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) | |
75 | { | |
76 | ECX_KEY *key = keydata; | |
77 | size_t privkeylen = 0, pubkeylen; | |
78 | const OSSL_PARAM *param_priv_key = NULL, *param_pub_key; | |
79 | unsigned char *pubkey; | |
90d3cb57 MC |
80 | |
81 | if (key == NULL) | |
82 | return 0; | |
83 | ||
f552d900 | 84 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0) |
90d3cb57 MC |
85 | return 0; |
86 | ||
90d3cb57 MC |
87 | param_pub_key = |
88 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); | |
89 | ||
f552d900 SL |
90 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) |
91 | param_priv_key = | |
92 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); | |
90d3cb57 MC |
93 | /* |
94 | * If a private key is present then a public key must also be present. | |
95 | * Alternatively we've just got a public key. | |
96 | */ | |
f552d900 | 97 | if (param_pub_key == NULL) |
90d3cb57 MC |
98 | return 0; |
99 | ||
100 | if (param_priv_key != NULL | |
101 | && !OSSL_PARAM_get_octet_string(param_priv_key, | |
102 | (void **)&key->privkey, key->keylen, | |
103 | &privkeylen)) | |
104 | return 0; | |
105 | ||
106 | pubkey = key->pubkey; | |
107 | if (!OSSL_PARAM_get_octet_string(param_pub_key, | |
108 | (void **)&pubkey, | |
109 | sizeof(key->pubkey), &pubkeylen)) | |
110 | return 0; | |
111 | ||
112 | if (pubkeylen != key->keylen | |
113 | || (param_priv_key != NULL && privkeylen != key->keylen)) | |
114 | return 0; | |
115 | ||
116 | key->haspubkey = 1; | |
117 | ||
118 | return 1; | |
119 | } | |
120 | ||
121 | static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl) | |
122 | { | |
123 | if (key == NULL) | |
124 | return 0; | |
125 | ||
126 | if (!ossl_param_bld_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY, | |
127 | key->pubkey, key->keylen)) | |
128 | return 0; | |
129 | ||
130 | if (key->privkey != NULL | |
131 | && !ossl_param_bld_push_octet_string(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, | |
132 | key->privkey, key->keylen)) | |
133 | return 0; | |
134 | ||
135 | return 1; | |
136 | } | |
137 | ||
138 | static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, | |
139 | void *cbarg) | |
140 | { | |
141 | ECX_KEY *key = keydata; | |
142 | OSSL_PARAM_BLD tmpl; | |
143 | OSSL_PARAM *params = NULL; | |
144 | int ret; | |
145 | ||
146 | if (key == NULL) | |
147 | return 0; | |
148 | ||
149 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 | |
150 | && !key_to_params(key, &tmpl)) | |
151 | return 0; | |
152 | ||
153 | ossl_param_bld_init(&tmpl); | |
154 | params = ossl_param_bld_to_param(&tmpl); | |
155 | if (params == NULL) { | |
156 | ossl_param_bld_free(params); | |
157 | return 0; | |
158 | } | |
159 | ||
160 | ret = param_cb(params, cbarg); | |
161 | ossl_param_bld_free(params); | |
162 | return ret; | |
163 | } | |
164 | ||
165 | static const OSSL_PARAM ecx_key_types[] = { | |
8efc4a9c MC |
166 | OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), |
167 | OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), | |
90d3cb57 MC |
168 | OSSL_PARAM_END |
169 | }; | |
170 | static const OSSL_PARAM *ecx_imexport_types(int selection) | |
171 | { | |
172 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) | |
173 | return ecx_key_types; | |
174 | return NULL; | |
175 | } | |
176 | ||
177 | static int ecx_get_params(OSSL_PARAM params[], int bits, int secbits, | |
178 | int size) | |
179 | { | |
180 | OSSL_PARAM *p; | |
181 | ||
182 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL | |
183 | && !OSSL_PARAM_set_int(p, bits)) | |
184 | return 0; | |
185 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL | |
186 | && !OSSL_PARAM_set_int(p, secbits)) | |
187 | return 0; | |
188 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL | |
189 | && !OSSL_PARAM_set_int(p, size)) | |
190 | return 0; | |
191 | return 1; | |
192 | } | |
193 | ||
194 | static int x25519_get_params(void *key, OSSL_PARAM params[]) | |
195 | { | |
196 | return ecx_get_params(params, X25519_BITS, X25519_SECURITY_BITS, X25519_KEYLEN); | |
197 | } | |
198 | ||
199 | static int x448_get_params(void *key, OSSL_PARAM params[]) | |
200 | { | |
201 | return ecx_get_params(params, X448_BITS, X448_SECURITY_BITS, X448_KEYLEN); | |
202 | } | |
203 | ||
af6d8dd3 MC |
204 | static int ed25519_get_params(void *key, OSSL_PARAM params[]) |
205 | { | |
206 | return ecx_get_params(params, ED25519_BITS, ED25519_SECURITY_BITS, ED25519_KEYLEN); | |
207 | } | |
208 | ||
209 | static int ed448_get_params(void *key, OSSL_PARAM params[]) | |
210 | { | |
211 | return ecx_get_params(params, ED448_BITS, ED448_SECURITY_BITS, ED448_KEYLEN); | |
212 | } | |
213 | ||
90d3cb57 MC |
214 | static const OSSL_PARAM ecx_params[] = { |
215 | OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), | |
216 | OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), | |
217 | OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), | |
218 | OSSL_PARAM_END | |
219 | }; | |
220 | ||
221 | static const OSSL_PARAM *ecx_gettable_params(void) | |
222 | { | |
223 | return ecx_params; | |
224 | } | |
225 | ||
af6d8dd3 MC |
226 | #define MAKE_KEYMGMT_FUNCTIONS(alg) \ |
227 | const OSSL_DISPATCH alg##_keymgmt_functions[] = { \ | |
228 | { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \ | |
229 | { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \ | |
230 | { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \ | |
231 | { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ecx_gettable_params }, \ | |
232 | { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \ | |
233 | { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \ | |
234 | { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \ | |
235 | { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \ | |
236 | { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \ | |
237 | { 0, NULL } \ | |
238 | }; | |
239 | ||
240 | MAKE_KEYMGMT_FUNCTIONS(x25519) | |
241 | MAKE_KEYMGMT_FUNCTIONS(x448) | |
242 | MAKE_KEYMGMT_FUNCTIONS(ed25519) | |
243 | MAKE_KEYMGMT_FUNCTIONS(ed448) |