]>
Commit | Line | Data |
---|---|---|
0c13cdf8 | 1 | /* |
fecb3aae | 2 | * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. |
0c13cdf8 MC |
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 <string.h> | |
11 | #include <openssl/core_names.h> | |
23c48d94 | 12 | #include <openssl/core_dispatch.h> |
0c13cdf8 MC |
13 | #include <openssl/rand.h> |
14 | #include <openssl/params.h> | |
ee58915c MB |
15 | #include <openssl/err.h> |
16 | #include <openssl/proverr.h> | |
17 | #include <openssl/pkcs12.h> | |
18 | #include <openssl/provider.h> | |
19 | #include <assert.h> | |
20 | #include <openssl/asn1.h> | |
21 | #include <openssl/asn1t.h> | |
22 | #include <openssl/core_object.h> | |
23 | #include "internal/asn1.h" | |
0c13cdf8 MC |
24 | /* For TLS1_3_VERSION */ |
25 | #include <openssl/ssl.h> | |
449bdf37 | 26 | #include "internal/nelem.h" |
ee58915c MB |
27 | #include "internal/refcount.h" |
28 | ||
29 | /* error codes */ | |
30 | ||
31 | /* xorprovider error codes */ | |
32 | #define XORPROV_R_INVALID_DIGEST 1 | |
33 | #define XORPROV_R_INVALID_SIZE 2 | |
34 | #define XORPROV_R_INVALID_KEY 3 | |
35 | #define XORPROV_R_UNSUPPORTED 4 | |
36 | #define XORPROV_R_MISSING_OID 5 | |
37 | #define XORPROV_R_OBJ_CREATE_ERR 6 | |
38 | #define XORPROV_R_INVALID_ENCODING 7 | |
39 | #define XORPROV_R_SIGN_ERROR 8 | |
40 | #define XORPROV_R_LIB_CREATE_ERR 9 | |
41 | #define XORPROV_R_NO_PRIVATE_KEY 10 | |
42 | #define XORPROV_R_BUFFER_LENGTH_WRONG 11 | |
43 | #define XORPROV_R_SIGNING_FAILED 12 | |
44 | #define XORPROV_R_WRONG_PARAMETERS 13 | |
45 | #define XORPROV_R_VERIFY_ERROR 14 | |
46 | #define XORPROV_R_EVPINFO_MISSING 15 | |
0c13cdf8 | 47 | |
2b248f4e P |
48 | static OSSL_FUNC_keymgmt_import_fn xor_import; |
49 | static OSSL_FUNC_keymgmt_import_types_fn xor_import_types; | |
50 | static OSSL_FUNC_keymgmt_export_fn xor_export; | |
51 | static OSSL_FUNC_keymgmt_export_types_fn xor_export_types; | |
52 | ||
0c13cdf8 MC |
53 | int tls_provider_init(const OSSL_CORE_HANDLE *handle, |
54 | const OSSL_DISPATCH *in, | |
55 | const OSSL_DISPATCH **out, | |
56 | void **provctx); | |
57 | ||
58 | #define XOR_KEY_SIZE 32 | |
59 | ||
60 | /* | |
61 | * Top secret. This algorithm only works if no one knows what this number is. | |
62 | * Please don't tell anyone what it is. | |
63 | * | |
64 | * This algorithm is for testing only - don't really use it! | |
65 | */ | |
66 | static const unsigned char private_constant[XOR_KEY_SIZE] = { | |
67 | 0xd3, 0x6b, 0x54, 0xec, 0x5b, 0xac, 0x89, 0x96, 0x8c, 0x2c, 0x66, 0xa5, | |
68 | 0x67, 0x0d, 0xe3, 0xdd, 0x43, 0x69, 0xbc, 0x83, 0x3d, 0x60, 0xc7, 0xb8, | |
69 | 0x2b, 0x1c, 0x5a, 0xfd, 0xb5, 0xcd, 0xd0, 0xf8 | |
70 | }; | |
71 | ||
72 | typedef struct xorkey_st { | |
73 | unsigned char privkey[XOR_KEY_SIZE]; | |
74 | unsigned char pubkey[XOR_KEY_SIZE]; | |
75 | int hasprivkey; | |
76 | int haspubkey; | |
ee58915c MB |
77 | char *tls_name; |
78 | CRYPTO_REF_COUNT references; | |
79 | CRYPTO_RWLOCK *lock; | |
0c13cdf8 MC |
80 | } XORKEY; |
81 | ||
ee58915c | 82 | /* Key Management for the dummy XOR KEX, KEM and signature algorithms */ |
5b70206c | 83 | |
ee58915c MB |
84 | static OSSL_FUNC_keymgmt_new_fn xor_newkey; |
85 | static OSSL_FUNC_keymgmt_free_fn xor_freekey; | |
5b70206c | 86 | static OSSL_FUNC_keymgmt_has_fn xor_has; |
85fcc3fb | 87 | static OSSL_FUNC_keymgmt_dup_fn xor_dup; |
5b70206c NT |
88 | static OSSL_FUNC_keymgmt_gen_init_fn xor_gen_init; |
89 | static OSSL_FUNC_keymgmt_gen_set_params_fn xor_gen_set_params; | |
90 | static OSSL_FUNC_keymgmt_gen_settable_params_fn xor_gen_settable_params; | |
91 | static OSSL_FUNC_keymgmt_gen_fn xor_gen; | |
92 | static OSSL_FUNC_keymgmt_gen_cleanup_fn xor_gen_cleanup; | |
ee58915c | 93 | static OSSL_FUNC_keymgmt_load_fn xor_load; |
5b70206c NT |
94 | static OSSL_FUNC_keymgmt_get_params_fn xor_get_params; |
95 | static OSSL_FUNC_keymgmt_gettable_params_fn xor_gettable_params; | |
96 | static OSSL_FUNC_keymgmt_set_params_fn xor_set_params; | |
97 | static OSSL_FUNC_keymgmt_settable_params_fn xor_settable_params; | |
98 | ||
99 | /* | |
100 | * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys | |
101 | * together. Don't use this! | |
102 | */ | |
103 | ||
ee58915c | 104 | static OSSL_FUNC_keyexch_newctx_fn xor_newkemkexctx; |
5b70206c NT |
105 | static OSSL_FUNC_keyexch_init_fn xor_init; |
106 | static OSSL_FUNC_keyexch_set_peer_fn xor_set_peer; | |
107 | static OSSL_FUNC_keyexch_derive_fn xor_derive; | |
108 | static OSSL_FUNC_keyexch_freectx_fn xor_freectx; | |
109 | static OSSL_FUNC_keyexch_dupctx_fn xor_dupctx; | |
110 | ||
111 | /* | |
112 | * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX. | |
113 | * Don't use this! | |
114 | */ | |
115 | ||
ee58915c | 116 | static OSSL_FUNC_kem_newctx_fn xor_newkemkexctx; |
5b70206c NT |
117 | static OSSL_FUNC_kem_freectx_fn xor_freectx; |
118 | static OSSL_FUNC_kem_dupctx_fn xor_dupctx; | |
119 | static OSSL_FUNC_kem_encapsulate_init_fn xor_init; | |
120 | static OSSL_FUNC_kem_encapsulate_fn xor_encapsulate; | |
121 | static OSSL_FUNC_kem_decapsulate_init_fn xor_init; | |
122 | static OSSL_FUNC_kem_decapsulate_fn xor_decapsulate; | |
123 | ||
ee58915c MB |
124 | /* |
125 | * Common key management table access functions | |
126 | */ | |
127 | static OSSL_FUNC_keymgmt_new_fn * | |
128 | xor_prov_get_keymgmt_new(const OSSL_DISPATCH *fns) | |
129 | { | |
130 | /* Pilfer the keymgmt dispatch table */ | |
131 | for (; fns->function_id != 0; fns++) | |
132 | if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW) | |
133 | return OSSL_FUNC_keymgmt_new(fns); | |
134 | ||
135 | return NULL; | |
136 | } | |
137 | ||
138 | static OSSL_FUNC_keymgmt_free_fn * | |
139 | xor_prov_get_keymgmt_free(const OSSL_DISPATCH *fns) | |
140 | { | |
141 | /* Pilfer the keymgmt dispatch table */ | |
142 | for (; fns->function_id != 0; fns++) | |
143 | if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE) | |
144 | return OSSL_FUNC_keymgmt_free(fns); | |
145 | ||
146 | return NULL; | |
147 | } | |
148 | ||
149 | static OSSL_FUNC_keymgmt_import_fn * | |
150 | xor_prov_get_keymgmt_import(const OSSL_DISPATCH *fns) | |
151 | { | |
152 | /* Pilfer the keymgmt dispatch table */ | |
153 | for (; fns->function_id != 0; fns++) | |
154 | if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT) | |
155 | return OSSL_FUNC_keymgmt_import(fns); | |
156 | ||
157 | return NULL; | |
158 | } | |
159 | ||
160 | static OSSL_FUNC_keymgmt_export_fn * | |
161 | xor_prov_get_keymgmt_export(const OSSL_DISPATCH *fns) | |
162 | { | |
163 | /* Pilfer the keymgmt dispatch table */ | |
164 | for (; fns->function_id != 0; fns++) | |
165 | if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT) | |
166 | return OSSL_FUNC_keymgmt_export(fns); | |
167 | ||
168 | return NULL; | |
169 | } | |
170 | ||
171 | static void *xor_prov_import_key(const OSSL_DISPATCH *fns, void *provctx, | |
172 | int selection, const OSSL_PARAM params[]) | |
173 | { | |
174 | OSSL_FUNC_keymgmt_new_fn *kmgmt_new = xor_prov_get_keymgmt_new(fns); | |
175 | OSSL_FUNC_keymgmt_free_fn *kmgmt_free = xor_prov_get_keymgmt_free(fns); | |
176 | OSSL_FUNC_keymgmt_import_fn *kmgmt_import = | |
177 | xor_prov_get_keymgmt_import(fns); | |
178 | void *key = NULL; | |
179 | ||
180 | if (kmgmt_new != NULL && kmgmt_import != NULL && kmgmt_free != NULL) { | |
181 | if ((key = kmgmt_new(provctx)) == NULL | |
182 | || !kmgmt_import(key, selection, params)) { | |
183 | kmgmt_free(key); | |
184 | key = NULL; | |
185 | } | |
186 | } | |
187 | return key; | |
188 | } | |
189 | ||
190 | static void xor_prov_free_key(const OSSL_DISPATCH *fns, void *key) | |
191 | { | |
192 | OSSL_FUNC_keymgmt_free_fn *kmgmt_free = xor_prov_get_keymgmt_free(fns); | |
193 | ||
194 | if (kmgmt_free != NULL) | |
195 | kmgmt_free(key); | |
196 | } | |
5b70206c NT |
197 | |
198 | /* | |
199 | * We define 2 dummy TLS groups called "xorgroup" and "xorkemgroup" for test | |
200 | * purposes | |
201 | */ | |
32fea070 NT |
202 | struct tls_group_st { |
203 | unsigned int group_id; /* for "tls-group-id", see provider-base(7) */ | |
204 | unsigned int secbits; | |
205 | unsigned int mintls; | |
206 | unsigned int maxtls; | |
207 | unsigned int mindtls; | |
208 | unsigned int maxdtls; | |
c1a74f59 | 209 | unsigned int is_kem; /* boolean */ |
32fea070 | 210 | }; |
0c13cdf8 | 211 | |
32fea070 NT |
212 | #define XORGROUP_NAME "xorgroup" |
213 | #define XORGROUP_NAME_INTERNAL "xorgroup-int" | |
214 | static struct tls_group_st xor_group = { | |
ee58915c | 215 | 0, /* group_id, set by randomize_tls_alg_id() */ |
32fea070 NT |
216 | 128, /* secbits */ |
217 | TLS1_3_VERSION, /* mintls */ | |
218 | 0, /* maxtls */ | |
219 | -1, /* mindtls */ | |
c1a74f59 NT |
220 | -1, /* maxdtls */ |
221 | 0 /* is_kem */ | |
32fea070 | 222 | }; |
0c13cdf8 | 223 | |
ecff43e0 NT |
224 | #define XORKEMGROUP_NAME "xorkemgroup" |
225 | #define XORKEMGROUP_NAME_INTERNAL "xorkemgroup-int" | |
226 | static struct tls_group_st xor_kemgroup = { | |
ee58915c | 227 | 0, /* group_id, set by randomize_tls_alg_id() */ |
ecff43e0 NT |
228 | 128, /* secbits */ |
229 | TLS1_3_VERSION, /* mintls */ | |
230 | 0, /* maxtls */ | |
231 | -1, /* mindtls */ | |
c1a74f59 NT |
232 | -1, /* maxdtls */ |
233 | 1 /* is_kem */ | |
ecff43e0 NT |
234 | }; |
235 | ||
0c13cdf8 MC |
236 | #define ALGORITHM "XOR" |
237 | ||
238 | static const OSSL_PARAM xor_group_params[] = { | |
239 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, | |
32fea070 | 240 | XORGROUP_NAME, sizeof(XORGROUP_NAME)), |
0c13cdf8 | 241 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, |
32fea070 NT |
242 | XORGROUP_NAME_INTERNAL, |
243 | sizeof(XORGROUP_NAME_INTERNAL)), | |
0c13cdf8 MC |
244 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM, |
245 | sizeof(ALGORITHM)), | |
32fea070 NT |
246 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &xor_group.group_id), |
247 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, | |
248 | &xor_group.secbits), | |
249 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &xor_group.mintls), | |
250 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_group.maxtls), | |
251 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_group.mindtls), | |
252 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_group.maxdtls), | |
c1a74f59 | 253 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_group.is_kem), |
0c13cdf8 MC |
254 | OSSL_PARAM_END |
255 | }; | |
256 | ||
ecff43e0 NT |
257 | static const OSSL_PARAM xor_kemgroup_params[] = { |
258 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, | |
259 | XORKEMGROUP_NAME, sizeof(XORKEMGROUP_NAME)), | |
260 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, | |
261 | XORKEMGROUP_NAME_INTERNAL, | |
262 | sizeof(XORKEMGROUP_NAME_INTERNAL)), | |
263 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM, | |
264 | sizeof(ALGORITHM)), | |
265 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &xor_kemgroup.group_id), | |
266 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, | |
267 | &xor_kemgroup.secbits), | |
268 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &xor_kemgroup.mintls), | |
269 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_kemgroup.maxtls), | |
270 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_kemgroup.mindtls), | |
271 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_kemgroup.maxdtls), | |
c1a74f59 | 272 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_kemgroup.is_kem), |
ecff43e0 NT |
273 | OSSL_PARAM_END |
274 | }; | |
275 | ||
57e7401f MC |
276 | #define NUM_DUMMY_GROUPS 50 |
277 | static char *dummy_group_names[NUM_DUMMY_GROUPS]; | |
ecff43e0 | 278 | |
ee58915c MB |
279 | /* |
280 | * We define a dummy TLS sigalg called for test purposes | |
281 | */ | |
282 | struct tls_sigalg_st { | |
283 | unsigned int code_point; /* for "tls-sigalg-alg", see provider-base(7) */ | |
284 | unsigned int secbits; | |
285 | unsigned int mintls; | |
286 | unsigned int maxtls; | |
287 | }; | |
288 | ||
289 | #define XORSIGALG_NAME "xorhmacsig" | |
290 | #define XORSIGALG_OID "1.3.6.1.4.1.16604.998888.1" | |
291 | #define XORSIGALG_HASH_NAME "xorhmacsha2sig" | |
292 | #define XORSIGALG_HASH "SHA256" | |
293 | #define XORSIGALG_HASH_OID "1.3.6.1.4.1.16604.998888.2" | |
294 | #define XORSIGALG12_NAME "xorhmacsig12" | |
295 | #define XORSIGALG12_OID "1.3.6.1.4.1.16604.998888.3" | |
296 | ||
297 | static struct tls_sigalg_st xor_sigalg = { | |
298 | 0, /* alg id, set by randomize_tls_alg_id() */ | |
299 | 128, /* secbits */ | |
300 | TLS1_3_VERSION, /* mintls */ | |
301 | 0, /* maxtls */ | |
302 | }; | |
303 | ||
304 | static struct tls_sigalg_st xor_sigalg_hash = { | |
305 | 0, /* alg id, set by randomize_tls_alg_id() */ | |
306 | 128, /* secbits */ | |
307 | TLS1_3_VERSION, /* mintls */ | |
308 | 0, /* maxtls */ | |
309 | }; | |
310 | ||
311 | static struct tls_sigalg_st xor_sigalg12 = { | |
312 | 0, /* alg id, set by randomize_tls_alg_id() */ | |
313 | 128, /* secbits */ | |
314 | TLS1_2_VERSION, /* mintls */ | |
315 | TLS1_2_VERSION, /* maxtls */ | |
316 | }; | |
317 | ||
318 | static const OSSL_PARAM xor_sig_nohash_params[] = { | |
319 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME, | |
320 | XORSIGALG_NAME, sizeof(XORSIGALG_NAME)), | |
321 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_NAME, | |
322 | XORSIGALG_NAME, | |
323 | sizeof(XORSIGALG_NAME)), | |
324 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_OID, | |
325 | XORSIGALG_OID, sizeof(XORSIGALG_OID)), | |
326 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT, | |
327 | &xor_sigalg.code_point), | |
328 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS, | |
329 | &xor_sigalg.secbits), | |
330 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS, | |
331 | &xor_sigalg.mintls), | |
332 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, | |
333 | &xor_sigalg.maxtls), | |
334 | OSSL_PARAM_END | |
335 | }; | |
336 | ||
337 | static const OSSL_PARAM xor_sig_hash_params[] = { | |
338 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME, | |
339 | XORSIGALG_HASH_NAME, sizeof(XORSIGALG_HASH_NAME)), | |
340 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_NAME, | |
341 | XORSIGALG_HASH_NAME, | |
342 | sizeof(XORSIGALG_HASH_NAME)), | |
343 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_HASH_NAME, | |
344 | XORSIGALG_HASH, sizeof(XORSIGALG_HASH)), | |
345 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_OID, | |
346 | XORSIGALG_HASH_OID, sizeof(XORSIGALG_HASH_OID)), | |
347 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT, | |
348 | &xor_sigalg_hash.code_point), | |
349 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS, | |
350 | &xor_sigalg_hash.secbits), | |
351 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS, | |
352 | &xor_sigalg_hash.mintls), | |
353 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, | |
354 | &xor_sigalg_hash.maxtls), | |
355 | OSSL_PARAM_END | |
356 | }; | |
357 | ||
358 | static const OSSL_PARAM xor_sig_12_params[] = { | |
359 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME, | |
360 | XORSIGALG12_NAME, sizeof(XORSIGALG12_NAME)), | |
361 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_NAME, | |
362 | XORSIGALG12_NAME, | |
363 | sizeof(XORSIGALG12_NAME)), | |
364 | OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_OID, | |
365 | XORSIGALG12_OID, sizeof(XORSIGALG12_OID)), | |
366 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT, | |
367 | &xor_sigalg12.code_point), | |
368 | OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS, | |
369 | &xor_sigalg12.secbits), | |
370 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS, | |
371 | &xor_sigalg12.mintls), | |
372 | OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, | |
373 | &xor_sigalg12.maxtls), | |
374 | OSSL_PARAM_END | |
375 | }; | |
376 | ||
0c13cdf8 MC |
377 | static int tls_prov_get_capabilities(void *provctx, const char *capability, |
378 | OSSL_CALLBACK *cb, void *arg) | |
379 | { | |
ee58915c | 380 | int ret = 0; |
57e7401f MC |
381 | int i; |
382 | const char *dummy_base = "dummy"; | |
383 | const size_t dummy_name_max_size = strlen(dummy_base) + 3; | |
384 | ||
ee58915c MB |
385 | if (strcmp(capability, "TLS-GROUP") == 0) { |
386 | /* Register our 2 groups */ | |
387 | ret = cb(xor_group_params, arg); | |
388 | ret &= cb(xor_kemgroup_params, arg); | |
57e7401f | 389 | |
ee58915c MB |
390 | /* |
391 | * Now register some dummy groups > GROUPLIST_INCREMENT (== 40) as defined | |
392 | * in ssl/t1_lib.c, to make sure we exercise the code paths for registering | |
393 | * large numbers of groups. | |
394 | */ | |
57e7401f | 395 | |
ee58915c MB |
396 | for (i = 0; i < NUM_DUMMY_GROUPS; i++) { |
397 | OSSL_PARAM dummygroup[OSSL_NELEM(xor_group_params)]; | |
57e7401f | 398 | |
ee58915c | 399 | memcpy(dummygroup, xor_group_params, sizeof(xor_group_params)); |
0c13cdf8 | 400 | |
ee58915c MB |
401 | /* Give the dummy group a unique name */ |
402 | if (dummy_group_names[i] == NULL) { | |
403 | dummy_group_names[i] = OPENSSL_zalloc(dummy_name_max_size); | |
404 | if (dummy_group_names[i] == NULL) | |
405 | return 0; | |
406 | BIO_snprintf(dummy_group_names[i], | |
57e7401f MC |
407 | dummy_name_max_size, |
408 | "%s%d", dummy_base, i); | |
ee58915c MB |
409 | } |
410 | dummygroup[0].data = dummy_group_names[i]; | |
411 | dummygroup[0].data_size = strlen(dummy_group_names[i]) + 1; | |
412 | ret &= cb(dummygroup, arg); | |
57e7401f | 413 | } |
57e7401f MC |
414 | } |
415 | ||
ee58915c MB |
416 | if (strcmp(capability, "TLS-SIGALG") == 0) { |
417 | ret = cb(xor_sig_nohash_params, arg); | |
418 | ret &= cb(xor_sig_hash_params, arg); | |
419 | ret &= cb(xor_sig_12_params, arg); | |
420 | } | |
57e7401f | 421 | return ret; |
0c13cdf8 MC |
422 | } |
423 | ||
ee58915c MB |
424 | typedef struct { |
425 | OSSL_LIB_CTX *libctx; | |
426 | } PROV_XOR_CTX; | |
427 | ||
428 | static PROV_XOR_CTX *xor_newprovctx(OSSL_LIB_CTX *libctx) | |
429 | { | |
430 | PROV_XOR_CTX* prov_ctx = OPENSSL_malloc(sizeof(PROV_XOR_CTX)); | |
431 | ||
432 | if (prov_ctx == NULL) | |
433 | return NULL; | |
434 | ||
435 | if (libctx == NULL) { | |
436 | OPENSSL_free(prov_ctx); | |
437 | return NULL; | |
438 | } | |
439 | prov_ctx->libctx = libctx; | |
440 | return prov_ctx; | |
441 | } | |
442 | ||
443 | ||
444 | ||
445 | #define PROV_XOR_LIBCTX_OF(provctx) (((PROV_XOR_CTX *)provctx)->libctx) | |
446 | ||
0c13cdf8 | 447 | /* |
ee58915c MB |
448 | * Dummy "XOR" Key Exchange and signature algorithm. We just xor the |
449 | * private and public keys together. Don't use this! | |
0c13cdf8 MC |
450 | */ |
451 | ||
0c13cdf8 MC |
452 | typedef struct { |
453 | XORKEY *key; | |
454 | XORKEY *peerkey; | |
5b70206c | 455 | void *provctx; |
ee58915c | 456 | } PROV_XORKEMKEX_CTX; |
0c13cdf8 | 457 | |
ee58915c | 458 | static void *xor_newkemkexctx(void *provctx) |
0c13cdf8 | 459 | { |
ee58915c | 460 | PROV_XORKEMKEX_CTX *pxorctx = OPENSSL_zalloc(sizeof(PROV_XORKEMKEX_CTX)); |
0c13cdf8 MC |
461 | |
462 | if (pxorctx == NULL) | |
463 | return NULL; | |
464 | ||
5b70206c NT |
465 | pxorctx->provctx = provctx; |
466 | ||
0c13cdf8 MC |
467 | return pxorctx; |
468 | } | |
469 | ||
af6171b3 P |
470 | static int xor_init(void *vpxorctx, void *vkey, |
471 | ossl_unused const OSSL_PARAM params[]) | |
0c13cdf8 | 472 | { |
ee58915c | 473 | PROV_XORKEMKEX_CTX *pxorctx = (PROV_XORKEMKEX_CTX *)vpxorctx; |
0c13cdf8 MC |
474 | |
475 | if (pxorctx == NULL || vkey == NULL) | |
476 | return 0; | |
477 | pxorctx->key = vkey; | |
478 | return 1; | |
479 | } | |
480 | ||
481 | static int xor_set_peer(void *vpxorctx, void *vpeerkey) | |
482 | { | |
ee58915c | 483 | PROV_XORKEMKEX_CTX *pxorctx = (PROV_XORKEMKEX_CTX *)vpxorctx; |
0c13cdf8 MC |
484 | |
485 | if (pxorctx == NULL || vpeerkey == NULL) | |
486 | return 0; | |
487 | pxorctx->peerkey = vpeerkey; | |
488 | return 1; | |
489 | } | |
490 | ||
491 | static int xor_derive(void *vpxorctx, unsigned char *secret, size_t *secretlen, | |
492 | size_t outlen) | |
493 | { | |
ee58915c | 494 | PROV_XORKEMKEX_CTX *pxorctx = (PROV_XORKEMKEX_CTX *)vpxorctx; |
0c13cdf8 MC |
495 | int i; |
496 | ||
497 | if (pxorctx->key == NULL || pxorctx->peerkey == NULL) | |
498 | return 0; | |
499 | ||
500 | *secretlen = XOR_KEY_SIZE; | |
501 | if (secret == NULL) | |
502 | return 1; | |
503 | ||
504 | if (outlen < XOR_KEY_SIZE) | |
505 | return 0; | |
506 | ||
507 | for (i = 0; i < XOR_KEY_SIZE; i++) | |
508 | secret[i] = pxorctx->key->privkey[i] ^ pxorctx->peerkey->pubkey[i]; | |
509 | ||
510 | return 1; | |
511 | } | |
512 | ||
513 | static void xor_freectx(void *pxorctx) | |
514 | { | |
515 | OPENSSL_free(pxorctx); | |
516 | } | |
517 | ||
518 | static void *xor_dupctx(void *vpxorctx) | |
519 | { | |
ee58915c MB |
520 | PROV_XORKEMKEX_CTX *srcctx = (PROV_XORKEMKEX_CTX *)vpxorctx; |
521 | PROV_XORKEMKEX_CTX *dstctx; | |
0c13cdf8 MC |
522 | |
523 | dstctx = OPENSSL_zalloc(sizeof(*srcctx)); | |
524 | if (dstctx == NULL) | |
525 | return NULL; | |
526 | ||
527 | *dstctx = *srcctx; | |
528 | ||
529 | return dstctx; | |
530 | } | |
531 | ||
532 | static const OSSL_DISPATCH xor_keyexch_functions[] = { | |
ee58915c | 533 | { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))xor_newkemkexctx }, |
0c13cdf8 MC |
534 | { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))xor_init }, |
535 | { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))xor_derive }, | |
536 | { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))xor_set_peer }, | |
537 | { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))xor_freectx }, | |
538 | { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))xor_dupctx }, | |
539 | { 0, NULL } | |
540 | }; | |
541 | ||
542 | static const OSSL_ALGORITHM tls_prov_keyexch[] = { | |
bfa6aaab | 543 | /* |
e304aa87 | 544 | * Obviously this is not FIPS approved, but in order to test in conjunction |
bfa6aaab MC |
545 | * with the FIPS provider we pretend that it is. |
546 | */ | |
547 | { "XOR", "provider=tls-provider,fips=yes", xor_keyexch_functions }, | |
0c13cdf8 MC |
548 | { NULL, NULL, NULL } |
549 | }; | |
550 | ||
5b70206c NT |
551 | /* |
552 | * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX. | |
553 | * Don't use this! | |
554 | */ | |
0c13cdf8 | 555 | |
5b70206c NT |
556 | static int xor_encapsulate(void *vpxorctx, |
557 | unsigned char *ct, size_t *ctlen, | |
558 | unsigned char *ss, size_t *sslen) | |
559 | { | |
560 | /* | |
561 | * We are building this around a KEX: | |
562 | * | |
563 | * 1. we generate ephemeral keypair | |
564 | * 2. we encode our ephemeral pubkey as the outgoing ct | |
565 | * 3. we derive using our ephemeral privkey in combination with the peer | |
566 | * pubkey from the ctx; the result is our ss. | |
567 | */ | |
568 | int rv = 0; | |
569 | void *genctx = NULL, *derivectx = NULL; | |
570 | XORKEY *ourkey = NULL; | |
ee58915c | 571 | PROV_XORKEMKEX_CTX *pxorctx = vpxorctx; |
5b70206c NT |
572 | |
573 | if (ct == NULL || ss == NULL) { | |
574 | /* Just return sizes */ | |
575 | ||
576 | if (ctlen == NULL && sslen == NULL) | |
577 | return 0; | |
578 | if (ctlen != NULL) | |
579 | *ctlen = XOR_KEY_SIZE; | |
580 | if (sslen != NULL) | |
581 | *sslen = XOR_KEY_SIZE; | |
582 | return 1; | |
583 | } | |
584 | ||
585 | /* 1. Generate keypair */ | |
10ffdda4 | 586 | genctx = xor_gen_init(pxorctx->provctx, OSSL_KEYMGMT_SELECT_KEYPAIR, NULL); |
5b70206c NT |
587 | if (genctx == NULL) |
588 | goto end; | |
589 | ourkey = xor_gen(genctx, NULL, NULL); | |
590 | if (ourkey == NULL) | |
591 | goto end; | |
592 | ||
593 | /* 2. Encode ephemeral pubkey as ct */ | |
594 | memcpy(ct, ourkey->pubkey, XOR_KEY_SIZE); | |
595 | *ctlen = XOR_KEY_SIZE; | |
596 | ||
597 | /* 3. Derive ss via KEX */ | |
ee58915c | 598 | derivectx = xor_newkemkexctx(pxorctx->provctx); |
5b70206c | 599 | if (derivectx == NULL |
af6171b3 | 600 | || !xor_init(derivectx, ourkey, NULL) |
5b70206c NT |
601 | || !xor_set_peer(derivectx, pxorctx->key) |
602 | || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE)) | |
603 | goto end; | |
604 | ||
605 | rv = 1; | |
606 | ||
607 | end: | |
608 | xor_gen_cleanup(genctx); | |
ee58915c | 609 | xor_freekey(ourkey); |
5b70206c NT |
610 | xor_freectx(derivectx); |
611 | return rv; | |
612 | } | |
613 | ||
614 | static int xor_decapsulate(void *vpxorctx, | |
615 | unsigned char *ss, size_t *sslen, | |
616 | const unsigned char *ct, size_t ctlen) | |
617 | { | |
618 | /* | |
619 | * We are building this around a KEX: | |
620 | * | |
621 | * - ct is our peer's pubkey | |
622 | * - decapsulate is just derive. | |
623 | */ | |
624 | int rv = 0; | |
625 | void *derivectx = NULL; | |
626 | XORKEY *peerkey = NULL; | |
ee58915c | 627 | PROV_XORKEMKEX_CTX *pxorctx = vpxorctx; |
5b70206c NT |
628 | |
629 | if (ss == NULL) { | |
630 | /* Just return size */ | |
631 | if (sslen == NULL) | |
632 | return 0; | |
633 | *sslen = XOR_KEY_SIZE; | |
634 | return 1; | |
635 | } | |
636 | ||
637 | if (ctlen != XOR_KEY_SIZE) | |
638 | return 0; | |
ee58915c | 639 | peerkey = xor_newkey(pxorctx->provctx); |
5b70206c NT |
640 | if (peerkey == NULL) |
641 | goto end; | |
642 | memcpy(peerkey->pubkey, ct, XOR_KEY_SIZE); | |
643 | ||
644 | /* Derive ss via KEX */ | |
ee58915c | 645 | derivectx = xor_newkemkexctx(pxorctx->provctx); |
5b70206c | 646 | if (derivectx == NULL |
af6171b3 | 647 | || !xor_init(derivectx, pxorctx->key, NULL) |
5b70206c NT |
648 | || !xor_set_peer(derivectx, peerkey) |
649 | || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE)) | |
650 | goto end; | |
651 | ||
652 | rv = 1; | |
653 | ||
654 | end: | |
ee58915c | 655 | xor_freekey(peerkey); |
5b70206c NT |
656 | xor_freectx(derivectx); |
657 | return rv; | |
658 | } | |
659 | ||
660 | static const OSSL_DISPATCH xor_kem_functions[] = { | |
ee58915c | 661 | { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))xor_newkemkexctx }, |
5b70206c NT |
662 | { OSSL_FUNC_KEM_FREECTX, (void (*)(void))xor_freectx }, |
663 | { OSSL_FUNC_KEM_DUPCTX, (void (*)(void))xor_dupctx }, | |
664 | { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))xor_init }, | |
665 | { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))xor_encapsulate }, | |
666 | { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))xor_init }, | |
667 | { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))xor_decapsulate }, | |
668 | { 0, NULL } | |
669 | }; | |
670 | ||
671 | static const OSSL_ALGORITHM tls_prov_kem[] = { | |
672 | /* | |
e304aa87 | 673 | * Obviously this is not FIPS approved, but in order to test in conjunction |
5b70206c NT |
674 | * with the FIPS provider we pretend that it is. |
675 | */ | |
676 | { "XOR", "provider=tls-provider,fips=yes", xor_kem_functions }, | |
677 | { NULL, NULL, NULL } | |
678 | }; | |
679 | ||
680 | /* Key Management for the dummy XOR key exchange algorithm */ | |
0c13cdf8 | 681 | |
ee58915c MB |
682 | static void *xor_newkey(void *provctx) |
683 | { | |
684 | XORKEY *ret = OPENSSL_zalloc(sizeof(XORKEY)); | |
685 | ||
686 | if (ret == NULL) | |
687 | return NULL; | |
688 | ||
689 | ret->references = 1; | |
690 | ret->lock = CRYPTO_THREAD_lock_new(); | |
691 | if (ret->lock == NULL) { | |
692 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
693 | OPENSSL_free(ret); | |
694 | return NULL; | |
695 | } | |
696 | ||
697 | return ret; | |
698 | } | |
699 | ||
700 | static void xor_freekey(void *keydata) | |
0c13cdf8 | 701 | { |
ee58915c MB |
702 | XORKEY* key = (XORKEY *)keydata; |
703 | int refcnt; | |
704 | ||
705 | if (key == NULL) | |
706 | return; | |
707 | ||
708 | if (CRYPTO_DOWN_REF(&key->references, &refcnt, key->lock) <= 0) | |
709 | return; | |
710 | ||
711 | if (refcnt > 0) | |
712 | return; | |
713 | assert(refcnt == 0); | |
714 | ||
715 | if (key != NULL) { | |
716 | OPENSSL_free(key->tls_name); | |
717 | key->tls_name = NULL; | |
718 | } | |
719 | CRYPTO_THREAD_lock_free(key->lock); | |
720 | OPENSSL_free(key); | |
0c13cdf8 MC |
721 | } |
722 | ||
ee58915c | 723 | static int xor_key_up_ref(XORKEY *key) |
0c13cdf8 | 724 | { |
ee58915c MB |
725 | int refcnt; |
726 | ||
727 | if (CRYPTO_UP_REF(&key->references, &refcnt, key->lock) <= 0) | |
728 | return 0; | |
729 | ||
730 | assert(refcnt > 1); | |
731 | return (refcnt > 1); | |
0c13cdf8 MC |
732 | } |
733 | ||
3d914185 | 734 | static int xor_has(const void *vkey, int selection) |
0c13cdf8 | 735 | { |
3d914185 | 736 | const XORKEY *key = vkey; |
0c13cdf8 MC |
737 | int ok = 0; |
738 | ||
739 | if (key != NULL) { | |
740 | ok = 1; | |
741 | ||
742 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) | |
743 | ok = ok && key->haspubkey; | |
744 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) | |
745 | ok = ok && key->hasprivkey; | |
746 | } | |
747 | return ok; | |
748 | } | |
749 | ||
85fcc3fb | 750 | static void *xor_dup(const void *vfromkey, int selection) |
0c13cdf8 | 751 | { |
ee58915c | 752 | XORKEY *tokey = xor_newkey(NULL); |
0c13cdf8 MC |
753 | const XORKEY *fromkey = vfromkey; |
754 | int ok = 0; | |
755 | ||
756 | if (tokey != NULL && fromkey != NULL) { | |
757 | ok = 1; | |
758 | ||
759 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { | |
760 | if (fromkey->haspubkey) { | |
761 | memcpy(tokey->pubkey, fromkey->pubkey, XOR_KEY_SIZE); | |
762 | tokey->haspubkey = 1; | |
763 | } else { | |
764 | tokey->haspubkey = 0; | |
765 | } | |
766 | } | |
767 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { | |
768 | if (fromkey->hasprivkey) { | |
769 | memcpy(tokey->privkey, fromkey->privkey, XOR_KEY_SIZE); | |
770 | tokey->hasprivkey = 1; | |
771 | } else { | |
772 | tokey->hasprivkey = 0; | |
773 | } | |
774 | } | |
ee58915c MB |
775 | if (fromkey->tls_name != NULL) |
776 | tokey->tls_name = OPENSSL_strdup(fromkey->tls_name); | |
0c13cdf8 | 777 | } |
85fcc3fb | 778 | if (!ok) { |
ee58915c | 779 | xor_freekey(tokey); |
85fcc3fb TM |
780 | tokey = NULL; |
781 | } | |
782 | return tokey; | |
0c13cdf8 MC |
783 | } |
784 | ||
785 | static ossl_inline int xor_get_params(void *vkey, OSSL_PARAM params[]) | |
786 | { | |
787 | XORKEY *key = vkey; | |
788 | OSSL_PARAM *p; | |
789 | ||
790 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL | |
791 | && !OSSL_PARAM_set_int(p, XOR_KEY_SIZE)) | |
792 | return 0; | |
793 | ||
794 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL | |
32fea070 | 795 | && !OSSL_PARAM_set_int(p, xor_group.secbits)) |
0c13cdf8 MC |
796 | return 0; |
797 | ||
5ac8fb58 MC |
798 | if ((p = OSSL_PARAM_locate(params, |
799 | OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) { | |
0c13cdf8 MC |
800 | if (p->data_type != OSSL_PARAM_OCTET_STRING) |
801 | return 0; | |
802 | p->return_size = XOR_KEY_SIZE; | |
803 | if (p->data != NULL && p->data_size >= XOR_KEY_SIZE) | |
804 | memcpy(p->data, key->pubkey, XOR_KEY_SIZE); | |
805 | } | |
806 | ||
807 | return 1; | |
808 | } | |
809 | ||
810 | static const OSSL_PARAM xor_params[] = { | |
811 | OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), | |
812 | OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), | |
5ac8fb58 | 813 | OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), |
0c13cdf8 MC |
814 | OSSL_PARAM_END |
815 | }; | |
816 | ||
132b6160 | 817 | static const OSSL_PARAM *xor_gettable_params(void *provctx) |
0c13cdf8 MC |
818 | { |
819 | return xor_params; | |
820 | } | |
821 | ||
822 | static int xor_set_params(void *vkey, const OSSL_PARAM params[]) | |
823 | { | |
824 | XORKEY *key = vkey; | |
825 | const OSSL_PARAM *p; | |
826 | ||
5ac8fb58 | 827 | p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); |
0c13cdf8 MC |
828 | if (p != NULL) { |
829 | if (p->data_type != OSSL_PARAM_OCTET_STRING | |
830 | || p->data_size != XOR_KEY_SIZE) | |
831 | return 0; | |
832 | memcpy(key->pubkey, p->data, XOR_KEY_SIZE); | |
833 | key->haspubkey = 1; | |
834 | } | |
835 | ||
836 | return 1; | |
837 | } | |
838 | ||
839 | static const OSSL_PARAM xor_known_settable_params[] = { | |
5ac8fb58 | 840 | OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), |
0c13cdf8 MC |
841 | OSSL_PARAM_END |
842 | }; | |
843 | ||
ee58915c MB |
844 | static void *xor_load(const void *reference, size_t reference_sz) |
845 | { | |
846 | XORKEY *key = NULL; | |
847 | ||
848 | if (reference_sz == sizeof(key)) { | |
849 | /* The contents of the reference is the address to our object */ | |
850 | key = *(XORKEY **)reference; | |
851 | /* We grabbed, so we detach it */ | |
852 | *(XORKEY **)reference = NULL; | |
853 | return key; | |
854 | } | |
855 | return NULL; | |
856 | } | |
857 | ||
858 | /* check one key is the "XOR complement" of the other */ | |
859 | static int xor_recreate(const unsigned char *kd1, const unsigned char *kd2) { | |
860 | int i; | |
861 | ||
862 | for (i = 0; i < XOR_KEY_SIZE; i++) { | |
863 | if ((kd1[i] & 0xff) != ((kd2[i] ^ private_constant[i]) & 0xff)) | |
864 | return 0; | |
865 | } | |
866 | return 1; | |
867 | } | |
868 | ||
869 | static int xor_match(const void *keydata1, const void *keydata2, int selection) | |
870 | { | |
871 | const XORKEY *key1 = keydata1; | |
872 | const XORKEY *key2 = keydata2; | |
873 | int ok = 1; | |
874 | ||
875 | if (key1->tls_name != NULL && key2->tls_name != NULL) | |
876 | ok = ok & (strcmp(key1->tls_name, key2->tls_name) == 0); | |
877 | ||
878 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { | |
879 | if (key1->hasprivkey) { | |
880 | if (key2->hasprivkey) | |
881 | ok = ok & (CRYPTO_memcmp(key1->privkey, key2->privkey, | |
882 | XOR_KEY_SIZE) == 0); | |
883 | else | |
884 | ok = ok & xor_recreate(key1->privkey, key2->pubkey); | |
885 | } else { | |
886 | if (key2->hasprivkey) | |
887 | ok = ok & xor_recreate(key2->privkey, key1->pubkey); | |
888 | else | |
889 | ok = 0; | |
890 | } | |
891 | } | |
892 | ||
893 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { | |
894 | if (key1->haspubkey) { | |
895 | if (key2->haspubkey) | |
896 | ok = ok & (CRYPTO_memcmp(key1->pubkey, key2->pubkey, XOR_KEY_SIZE) == 0); | |
897 | else | |
898 | ok = ok & xor_recreate(key1->pubkey, key2->privkey); | |
899 | } else { | |
900 | if (key2->haspubkey) | |
901 | ok = ok & xor_recreate(key2->pubkey, key1->privkey); | |
902 | else | |
903 | ok = 0; | |
904 | } | |
905 | } | |
906 | ||
907 | return ok; | |
908 | } | |
909 | ||
132b6160 | 910 | static const OSSL_PARAM *xor_settable_params(void *provctx) |
0c13cdf8 MC |
911 | { |
912 | return xor_known_settable_params; | |
913 | } | |
914 | ||
915 | struct xor_gen_ctx { | |
916 | int selection; | |
b4250010 | 917 | OSSL_LIB_CTX *libctx; |
0c13cdf8 MC |
918 | }; |
919 | ||
10ffdda4 P |
920 | static void *xor_gen_init(void *provctx, int selection, |
921 | const OSSL_PARAM params[]) | |
0c13cdf8 MC |
922 | { |
923 | struct xor_gen_ctx *gctx = NULL; | |
924 | ||
925 | if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR | |
926 | | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0) | |
927 | return NULL; | |
928 | ||
929 | if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) | |
930 | gctx->selection = selection; | |
931 | ||
ee58915c | 932 | gctx->libctx = PROV_XOR_LIBCTX_OF(provctx); |
0c13cdf8 | 933 | |
10ffdda4 P |
934 | if (!xor_gen_set_params(gctx, params)) { |
935 | OPENSSL_free(gctx); | |
936 | return NULL; | |
937 | } | |
0c13cdf8 MC |
938 | return gctx; |
939 | } | |
940 | ||
941 | static int xor_gen_set_params(void *genctx, const OSSL_PARAM params[]) | |
942 | { | |
943 | struct xor_gen_ctx *gctx = genctx; | |
944 | const OSSL_PARAM *p; | |
945 | ||
946 | if (gctx == NULL) | |
947 | return 0; | |
948 | ||
949 | p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); | |
950 | if (p != NULL) { | |
951 | if (p->data_type != OSSL_PARAM_UTF8_STRING | |
ecff43e0 NT |
952 | || (strcmp(p->data, XORGROUP_NAME_INTERNAL) != 0 |
953 | && strcmp(p->data, XORKEMGROUP_NAME_INTERNAL) != 0)) | |
0c13cdf8 MC |
954 | return 0; |
955 | } | |
956 | ||
957 | return 1; | |
958 | } | |
959 | ||
fb67126e TM |
960 | static const OSSL_PARAM *xor_gen_settable_params(ossl_unused void *genctx, |
961 | ossl_unused void *provctx) | |
0c13cdf8 MC |
962 | { |
963 | static OSSL_PARAM settable[] = { | |
964 | OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), | |
965 | OSSL_PARAM_END | |
966 | }; | |
967 | return settable; | |
968 | } | |
969 | ||
970 | static void *xor_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) | |
971 | { | |
972 | struct xor_gen_ctx *gctx = genctx; | |
ee58915c | 973 | XORKEY *key = xor_newkey(NULL); |
0c13cdf8 MC |
974 | size_t i; |
975 | ||
976 | if (key == NULL) | |
977 | return NULL; | |
978 | ||
979 | if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { | |
23e97567 | 980 | if (RAND_bytes_ex(gctx->libctx, key->privkey, XOR_KEY_SIZE, 0) <= 0) { |
0c13cdf8 MC |
981 | OPENSSL_free(key); |
982 | return NULL; | |
983 | } | |
984 | for (i = 0; i < XOR_KEY_SIZE; i++) | |
985 | key->pubkey[i] = key->privkey[i] ^ private_constant[i]; | |
986 | key->hasprivkey = 1; | |
987 | key->haspubkey = 1; | |
988 | } | |
989 | ||
990 | return key; | |
991 | } | |
992 | ||
2b248f4e P |
993 | /* IMPORT + EXPORT */ |
994 | ||
995 | static int xor_import(void *vkey, int select, const OSSL_PARAM params[]) | |
996 | { | |
997 | XORKEY *key = vkey; | |
998 | const OSSL_PARAM *param_priv_key, *param_pub_key; | |
999 | unsigned char privkey[XOR_KEY_SIZE]; | |
1000 | unsigned char pubkey[XOR_KEY_SIZE]; | |
1001 | void *pprivkey = privkey, *ppubkey = pubkey; | |
1002 | size_t priv_len = 0, pub_len = 0; | |
1003 | int res = 0; | |
1004 | ||
1005 | if (key == NULL || (select & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) | |
1006 | return 0; | |
1007 | ||
1008 | memset(privkey, 0, sizeof(privkey)); | |
1009 | memset(pubkey, 0, sizeof(pubkey)); | |
1010 | param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); | |
1011 | param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); | |
1012 | ||
1013 | if ((param_priv_key != NULL | |
1014 | && !OSSL_PARAM_get_octet_string(param_priv_key, &pprivkey, | |
1015 | sizeof(privkey), &priv_len)) | |
1016 | || (param_pub_key != NULL | |
1017 | && !OSSL_PARAM_get_octet_string(param_pub_key, &ppubkey, | |
1018 | sizeof(pubkey), &pub_len))) | |
1019 | goto err; | |
1020 | ||
1021 | if (priv_len > 0) { | |
1022 | memcpy(key->privkey, privkey, priv_len); | |
1023 | key->hasprivkey = 1; | |
1024 | } | |
1025 | if (pub_len > 0) { | |
1026 | memcpy(key->pubkey, pubkey, pub_len); | |
1027 | key->haspubkey = 1; | |
1028 | } | |
1029 | res = 1; | |
1030 | err: | |
1031 | return res; | |
1032 | } | |
1033 | ||
1034 | static int xor_export(void *vkey, int select, OSSL_CALLBACK *param_cb, | |
1035 | void *cbarg) | |
1036 | { | |
1037 | XORKEY *key = vkey; | |
1038 | OSSL_PARAM params[3], *p = params; | |
1039 | ||
1040 | if (key == NULL || (select & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) | |
1041 | return 0; | |
1042 | ||
1043 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, | |
1044 | key->privkey, | |
1045 | sizeof(key->privkey)); | |
1046 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, | |
1047 | key->pubkey, sizeof(key->pubkey)); | |
1048 | *p++ = OSSL_PARAM_construct_end(); | |
1049 | ||
1050 | return param_cb(params, cbarg); | |
1051 | } | |
1052 | ||
1053 | static const OSSL_PARAM xor_key_types[] = { | |
1054 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), | |
1055 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), | |
1056 | OSSL_PARAM_END | |
1057 | }; | |
1058 | ||
1059 | static const OSSL_PARAM *xor_import_types(int select) | |
1060 | { | |
1061 | return (select & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ? xor_key_types : NULL; | |
1062 | } | |
1063 | ||
1064 | static const OSSL_PARAM *xor_export_types(int select) | |
1065 | { | |
1066 | return (select & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ? xor_key_types : NULL; | |
1067 | } | |
1068 | ||
0c13cdf8 MC |
1069 | static void xor_gen_cleanup(void *genctx) |
1070 | { | |
1071 | OPENSSL_free(genctx); | |
1072 | } | |
1073 | ||
1074 | static const OSSL_DISPATCH xor_keymgmt_functions[] = { | |
ee58915c | 1075 | { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newkey }, |
0c13cdf8 MC |
1076 | { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init }, |
1077 | { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params }, | |
1078 | { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, | |
1079 | (void (*)(void))xor_gen_settable_params }, | |
1080 | { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_gen }, | |
1081 | { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup }, | |
1082 | { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params }, | |
1083 | { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params }, | |
1084 | { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params }, | |
1085 | { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params }, | |
1086 | { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has }, | |
85fcc3fb | 1087 | { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))xor_dup }, |
ee58915c | 1088 | { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freekey }, |
2b248f4e P |
1089 | { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))xor_import }, |
1090 | { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))xor_import_types }, | |
1091 | { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))xor_export }, | |
1092 | { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))xor_export_types }, | |
0c13cdf8 MC |
1093 | { 0, NULL } |
1094 | }; | |
1095 | ||
ee58915c MB |
1096 | /* We're re-using most XOR keymgmt functions also for signature operations: */ |
1097 | static void *xor_xorhmacsig_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) | |
0c13cdf8 | 1098 | { |
ee58915c MB |
1099 | XORKEY *k = xor_gen(genctx, osslcb, cbarg); |
1100 | ||
1101 | if (k == NULL) | |
1102 | return NULL; | |
1103 | k->tls_name = OPENSSL_strdup(XORSIGALG_NAME); | |
1104 | if (k->tls_name == NULL) { | |
1105 | xor_freekey(k); | |
1106 | return NULL; | |
0c13cdf8 | 1107 | } |
ee58915c | 1108 | return k; |
0c13cdf8 MC |
1109 | } |
1110 | ||
ee58915c | 1111 | static void *xor_xorhmacsha2sig_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) |
57e7401f | 1112 | { |
ee58915c | 1113 | XORKEY* k = xor_gen(genctx, osslcb, cbarg); |
57e7401f | 1114 | |
ee58915c MB |
1115 | if (k == NULL) |
1116 | return NULL; | |
1117 | k->tls_name = OPENSSL_strdup(XORSIGALG_HASH_NAME); | |
1118 | if (k->tls_name == NULL) { | |
1119 | xor_freekey(k); | |
1120 | return NULL; | |
57e7401f | 1121 | } |
ee58915c | 1122 | return k; |
57e7401f MC |
1123 | } |
1124 | ||
ee58915c MB |
1125 | |
1126 | static const OSSL_DISPATCH xor_xorhmacsig_keymgmt_functions[] = { | |
1127 | { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newkey }, | |
1128 | { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init }, | |
1129 | { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params }, | |
1130 | { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, | |
1131 | (void (*)(void))xor_gen_settable_params }, | |
1132 | { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_xorhmacsig_gen }, | |
1133 | { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup }, | |
1134 | { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params }, | |
1135 | { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params }, | |
1136 | { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params }, | |
1137 | { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params }, | |
1138 | { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has }, | |
1139 | { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))xor_dup }, | |
1140 | { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freekey }, | |
1141 | { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))xor_import }, | |
1142 | { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))xor_import_types }, | |
1143 | { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))xor_export }, | |
1144 | { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))xor_export_types }, | |
1145 | { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))xor_load }, | |
1146 | { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))xor_match }, | |
0c13cdf8 MC |
1147 | { 0, NULL } |
1148 | }; | |
1149 | ||
ee58915c MB |
1150 | static const OSSL_DISPATCH xor_xorhmacsha2sig_keymgmt_functions[] = { |
1151 | { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newkey }, | |
1152 | { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init }, | |
1153 | { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params }, | |
1154 | { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, | |
1155 | (void (*)(void))xor_gen_settable_params }, | |
1156 | { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_xorhmacsha2sig_gen }, | |
1157 | { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup }, | |
1158 | { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params }, | |
1159 | { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params }, | |
1160 | { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params }, | |
1161 | { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params }, | |
1162 | { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has }, | |
1163 | { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))xor_dup }, | |
1164 | { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freekey }, | |
1165 | { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))xor_import }, | |
1166 | { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))xor_import_types }, | |
1167 | { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))xor_export }, | |
1168 | { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))xor_export_types }, | |
1169 | { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))xor_load }, | |
1170 | { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))xor_match }, | |
1171 | { 0, NULL } | |
1172 | }; | |
1173 | ||
1174 | typedef enum { | |
1175 | KEY_OP_PUBLIC, | |
1176 | KEY_OP_PRIVATE, | |
1177 | KEY_OP_KEYGEN | |
1178 | } xor_key_op_t; | |
1179 | ||
1180 | /* Re-create XORKEY from encoding(s): Same end-state as after key-gen */ | |
1181 | static XORKEY *xor_key_op(const X509_ALGOR *palg, | |
1182 | const unsigned char *p, int plen, | |
1183 | xor_key_op_t op, | |
1184 | OSSL_LIB_CTX *libctx, const char *propq) | |
0c13cdf8 | 1185 | { |
ee58915c MB |
1186 | XORKEY *key = NULL; |
1187 | int nid = NID_undef; | |
32fea070 | 1188 | |
ee58915c MB |
1189 | if (palg != NULL) { |
1190 | int ptype; | |
1191 | ||
1192 | /* Algorithm parameters must be absent */ | |
1193 | X509_ALGOR_get0(NULL, &ptype, NULL, palg); | |
1194 | if (ptype != V_ASN1_UNDEF || palg->algorithm == NULL) { | |
1195 | ERR_raise(ERR_LIB_USER, XORPROV_R_INVALID_ENCODING); | |
1196 | return 0; | |
1197 | } | |
1198 | nid = OBJ_obj2nid(palg->algorithm); | |
1199 | } | |
1200 | ||
1201 | if (p == NULL || nid == EVP_PKEY_NONE || nid == NID_undef) { | |
1202 | ERR_raise(ERR_LIB_USER, XORPROV_R_INVALID_ENCODING); | |
0c13cdf8 | 1203 | return 0; |
ee58915c | 1204 | } |
0c13cdf8 | 1205 | |
ee58915c MB |
1206 | key = xor_newkey(NULL); |
1207 | if (key == NULL) { | |
1208 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
1209 | return 0; | |
1210 | } | |
1211 | ||
1212 | if (XOR_KEY_SIZE != plen) { | |
1213 | ERR_raise(ERR_LIB_USER, XORPROV_R_INVALID_ENCODING); | |
1214 | goto err; | |
1215 | } | |
1216 | ||
1217 | if (op == KEY_OP_PUBLIC) { | |
1218 | memcpy(key->pubkey, p, plen); | |
1219 | key->haspubkey = 1; | |
1220 | } else { | |
1221 | memcpy(key->privkey, p, plen); | |
1222 | key->hasprivkey = 1; | |
1223 | } | |
ecff43e0 | 1224 | |
ee58915c MB |
1225 | key->tls_name = OPENSSL_strdup(OBJ_nid2sn(nid)); |
1226 | if (key->tls_name == NULL) | |
1227 | goto err; | |
1228 | return key; | |
ecff43e0 | 1229 | |
ee58915c MB |
1230 | err: |
1231 | xor_freekey(key); | |
1232 | return NULL; | |
32fea070 NT |
1233 | } |
1234 | ||
ee58915c MB |
1235 | static XORKEY *xor_key_from_x509pubkey(const X509_PUBKEY *xpk, |
1236 | OSSL_LIB_CTX *libctx, const char *propq) | |
1237 | { | |
1238 | const unsigned char *p; | |
1239 | int plen; | |
1240 | X509_ALGOR *palg; | |
1241 | ||
1242 | if (!xpk || (!X509_PUBKEY_get0_param(NULL, &p, &plen, &palg, xpk))) { | |
1243 | return NULL; | |
1244 | } | |
1245 | return xor_key_op(palg, p, plen, KEY_OP_PUBLIC, libctx, propq); | |
1246 | } | |
1247 | ||
1248 | static XORKEY *xor_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, | |
1249 | OSSL_LIB_CTX *libctx, const char *propq) | |
32fea070 | 1250 | { |
ee58915c MB |
1251 | XORKEY *xork = NULL; |
1252 | const unsigned char *p; | |
1253 | int plen; | |
1254 | ASN1_OCTET_STRING *oct = NULL; | |
1255 | const X509_ALGOR *palg; | |
32fea070 | 1256 | |
ee58915c | 1257 | if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf)) |
8d215738 | 1258 | return 0; |
1259 | ||
ee58915c MB |
1260 | oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); |
1261 | if (oct == NULL) { | |
1262 | p = NULL; | |
1263 | plen = 0; | |
1264 | } else { | |
1265 | p = ASN1_STRING_get0_data(oct); | |
1266 | plen = ASN1_STRING_length(oct); | |
1267 | } | |
1268 | ||
1269 | xork = xor_key_op(palg, p, plen, KEY_OP_PRIVATE, | |
1270 | libctx, propq); | |
1271 | ASN1_OCTET_STRING_free(oct); | |
1272 | return xork; | |
1273 | } | |
32fea070 | 1274 | |
ee58915c | 1275 | static const OSSL_ALGORITHM tls_prov_keymgmt[] = { |
32fea070 | 1276 | /* |
ee58915c MB |
1277 | * Obviously this is not FIPS approved, but in order to test in conjunction |
1278 | * with the FIPS provider we pretend that it is. | |
32fea070 | 1279 | */ |
ee58915c MB |
1280 | { "XOR", "provider=tls-provider,fips=yes", |
1281 | xor_keymgmt_functions }, | |
1282 | { XORSIGALG_NAME, "provider=tls-provider,fips=yes", | |
1283 | xor_xorhmacsig_keymgmt_functions }, | |
1284 | { XORSIGALG_HASH_NAME, | |
1285 | "provider=tls-provider,fips=yes", | |
1286 | xor_xorhmacsha2sig_keymgmt_functions }, | |
1287 | { NULL, NULL, NULL } | |
1288 | }; | |
1289 | ||
1290 | struct key2any_ctx_st { | |
1291 | PROV_XOR_CTX *provctx; | |
1292 | ||
1293 | /* Set to 0 if parameters should not be saved (dsa only) */ | |
1294 | int save_parameters; | |
1295 | ||
1296 | /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */ | |
1297 | int cipher_intent; | |
1298 | ||
1299 | EVP_CIPHER *cipher; | |
1300 | ||
1301 | OSSL_PASSPHRASE_CALLBACK *pwcb; | |
1302 | void *pwcbarg; | |
1303 | }; | |
1304 | ||
1305 | typedef int check_key_type_fn(const void *key, int nid); | |
1306 | typedef int key_to_paramstring_fn(const void *key, int nid, int save, | |
1307 | void **str, int *strtype); | |
1308 | typedef int key_to_der_fn(BIO *out, const void *key, | |
1309 | int key_nid, const char *pemname, | |
1310 | key_to_paramstring_fn *p2s, i2d_of_void *k2d, | |
1311 | struct key2any_ctx_st *ctx); | |
1312 | typedef int write_bio_of_void_fn(BIO *bp, const void *x); | |
1313 | ||
1314 | ||
1315 | /* Free the blob allocated during key_to_paramstring_fn */ | |
1316 | static void free_asn1_data(int type, void *data) | |
1317 | { | |
1318 | switch(type) { | |
1319 | case V_ASN1_OBJECT: | |
1320 | ASN1_OBJECT_free(data); | |
1321 | break; | |
1322 | case V_ASN1_SEQUENCE: | |
1323 | ASN1_STRING_free(data); | |
1324 | break; | |
1325 | } | |
1326 | } | |
1327 | ||
1328 | static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, | |
1329 | void *params, int params_type, | |
1330 | i2d_of_void *k2d) | |
1331 | { | |
1332 | /* der, derlen store the key DER output and its length */ | |
1333 | unsigned char *der = NULL; | |
1334 | int derlen; | |
1335 | /* The final PKCS#8 info */ | |
1336 | PKCS8_PRIV_KEY_INFO *p8info = NULL; | |
1337 | ||
1338 | if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL | |
1339 | || (derlen = k2d(key, &der)) <= 0 | |
1340 | || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0, | |
1341 | V_ASN1_UNDEF, NULL, | |
1342 | der, derlen)) { | |
1343 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
1344 | PKCS8_PRIV_KEY_INFO_free(p8info); | |
1345 | OPENSSL_free(der); | |
1346 | p8info = NULL; | |
1347 | } | |
1348 | ||
1349 | return p8info; | |
1350 | } | |
1351 | ||
1352 | static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, | |
1353 | struct key2any_ctx_st *ctx) | |
1354 | { | |
1355 | X509_SIG *p8 = NULL; | |
1356 | char kstr[PEM_BUFSIZE]; | |
1357 | size_t klen = 0; | |
1358 | OSSL_LIB_CTX *libctx = PROV_XOR_LIBCTX_OF(ctx->provctx); | |
1359 | ||
1360 | if (ctx->cipher == NULL || ctx->pwcb == NULL) | |
1361 | return NULL; | |
1362 | ||
1363 | if (!ctx->pwcb(kstr, PEM_BUFSIZE, &klen, NULL, ctx->pwcbarg)) { | |
1364 | ERR_raise(ERR_LIB_USER, PROV_R_UNABLE_TO_GET_PASSPHRASE); | |
1365 | return NULL; | |
1366 | } | |
1367 | /* First argument == -1 means "standard" */ | |
1368 | p8 = PKCS8_encrypt_ex(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info, libctx, NULL); | |
1369 | OPENSSL_cleanse(kstr, klen); | |
1370 | return p8; | |
1371 | } | |
1372 | ||
1373 | static X509_SIG *key_to_encp8(const void *key, int key_nid, | |
1374 | void *params, int params_type, | |
1375 | i2d_of_void *k2d, struct key2any_ctx_st *ctx) | |
1376 | { | |
1377 | PKCS8_PRIV_KEY_INFO *p8info = | |
1378 | key_to_p8info(key, key_nid, params, params_type, k2d); | |
1379 | X509_SIG *p8 = NULL; | |
1380 | ||
1381 | if (p8info == NULL) { | |
1382 | free_asn1_data(params_type, params); | |
1383 | } else { | |
1384 | p8 = p8info_to_encp8(p8info, ctx); | |
1385 | PKCS8_PRIV_KEY_INFO_free(p8info); | |
1386 | } | |
1387 | return p8; | |
1388 | } | |
1389 | ||
1390 | static X509_PUBKEY *xorx_key_to_pubkey(const void *key, int key_nid, | |
1391 | void *params, int params_type, | |
1392 | i2d_of_void k2d) | |
1393 | { | |
1394 | /* der, derlen store the key DER output and its length */ | |
1395 | unsigned char *der = NULL; | |
1396 | int derlen; | |
1397 | /* The final X509_PUBKEY */ | |
1398 | X509_PUBKEY *xpk = NULL; | |
1399 | ||
1400 | if ((xpk = X509_PUBKEY_new()) == NULL | |
1401 | || (derlen = k2d(key, &der)) <= 0 | |
1402 | || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid), | |
1403 | V_ASN1_UNDEF, NULL, | |
1404 | der, derlen)) { | |
1405 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
1406 | X509_PUBKEY_free(xpk); | |
1407 | OPENSSL_free(der); | |
1408 | xpk = NULL; | |
1409 | } | |
1410 | ||
1411 | return xpk; | |
1412 | } | |
1413 | ||
1414 | /* | |
1415 | * key_to_epki_* produce encoded output with the private key data in a | |
1416 | * EncryptedPrivateKeyInfo structure (defined by PKCS#8). They require | |
1417 | * that there's an intent to encrypt, anything else is an error. | |
1418 | * | |
1419 | * key_to_pki_* primarly produce encoded output with the private key data | |
1420 | * in a PrivateKeyInfo structure (also defined by PKCS#8). However, if | |
1421 | * there is an intent to encrypt the data, the corresponding key_to_epki_* | |
1422 | * function is used instead. | |
1423 | * | |
1424 | * key_to_spki_* produce encoded output with the public key data in an | |
1425 | * X.509 SubjectPublicKeyInfo. | |
1426 | * | |
1427 | * Key parameters don't have any defined envelopment of this kind, but are | |
1428 | * included in some manner in the output from the functions described above, | |
1429 | * either in the AlgorithmIdentifier's parameter field, or as part of the | |
1430 | * key data itself. | |
1431 | */ | |
1432 | ||
1433 | static int key_to_epki_der_priv_bio(BIO *out, const void *key, | |
1434 | int key_nid, | |
1435 | ossl_unused const char *pemname, | |
1436 | key_to_paramstring_fn *p2s, | |
1437 | i2d_of_void *k2d, | |
1438 | struct key2any_ctx_st *ctx) | |
1439 | { | |
1440 | int ret = 0; | |
1441 | void *str = NULL; | |
1442 | int strtype = V_ASN1_UNDEF; | |
1443 | X509_SIG *p8; | |
1444 | ||
1445 | if (!ctx->cipher_intent) | |
1446 | return 0; | |
1447 | ||
1448 | if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, | |
1449 | &str, &strtype)) | |
1450 | return 0; | |
1451 | ||
1452 | p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx); | |
1453 | if (p8 != NULL) | |
1454 | ret = i2d_PKCS8_bio(out, p8); | |
1455 | ||
1456 | X509_SIG_free(p8); | |
1457 | ||
1458 | return ret; | |
1459 | } | |
1460 | ||
1461 | static int key_to_epki_pem_priv_bio(BIO *out, const void *key, | |
1462 | int key_nid, | |
1463 | ossl_unused const char *pemname, | |
1464 | key_to_paramstring_fn *p2s, | |
1465 | i2d_of_void *k2d, | |
1466 | struct key2any_ctx_st *ctx) | |
1467 | { | |
1468 | int ret = 0; | |
1469 | void *str = NULL; | |
1470 | int strtype = V_ASN1_UNDEF; | |
1471 | X509_SIG *p8; | |
1472 | ||
1473 | if (!ctx->cipher_intent) | |
1474 | return 0; | |
1475 | ||
1476 | if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, | |
1477 | &str, &strtype)) | |
1478 | return 0; | |
1479 | ||
1480 | p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx); | |
1481 | if (p8 != NULL) | |
1482 | ret = PEM_write_bio_PKCS8(out, p8); | |
1483 | ||
1484 | X509_SIG_free(p8); | |
1485 | ||
1486 | return ret; | |
1487 | } | |
1488 | ||
1489 | static int key_to_pki_der_priv_bio(BIO *out, const void *key, | |
1490 | int key_nid, | |
1491 | ossl_unused const char *pemname, | |
1492 | key_to_paramstring_fn *p2s, | |
1493 | i2d_of_void *k2d, | |
1494 | struct key2any_ctx_st *ctx) | |
1495 | { | |
1496 | int ret = 0; | |
1497 | void *str = NULL; | |
1498 | int strtype = V_ASN1_UNDEF; | |
1499 | PKCS8_PRIV_KEY_INFO *p8info; | |
1500 | ||
1501 | if (ctx->cipher_intent) | |
1502 | return key_to_epki_der_priv_bio(out, key, key_nid, pemname, | |
1503 | p2s, k2d, ctx); | |
1504 | ||
1505 | if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, | |
1506 | &str, &strtype)) | |
1507 | return 0; | |
1508 | ||
1509 | p8info = key_to_p8info(key, key_nid, str, strtype, k2d); | |
1510 | ||
1511 | if (p8info != NULL) | |
1512 | ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); | |
1513 | else | |
1514 | free_asn1_data(strtype, str); | |
1515 | ||
1516 | PKCS8_PRIV_KEY_INFO_free(p8info); | |
1517 | ||
1518 | return ret; | |
1519 | } | |
1520 | ||
1521 | static int key_to_pki_pem_priv_bio(BIO *out, const void *key, | |
1522 | int key_nid, | |
1523 | ossl_unused const char *pemname, | |
1524 | key_to_paramstring_fn *p2s, | |
1525 | i2d_of_void *k2d, | |
1526 | struct key2any_ctx_st *ctx) | |
1527 | { | |
1528 | int ret = 0; | |
1529 | void *str = NULL; | |
1530 | int strtype = V_ASN1_UNDEF; | |
1531 | PKCS8_PRIV_KEY_INFO *p8info; | |
1532 | ||
1533 | if (ctx->cipher_intent) | |
1534 | return key_to_epki_pem_priv_bio(out, key, key_nid, pemname, | |
1535 | p2s, k2d, ctx); | |
1536 | ||
1537 | if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, | |
1538 | &str, &strtype)) | |
1539 | return 0; | |
1540 | ||
1541 | p8info = key_to_p8info(key, key_nid, str, strtype, k2d); | |
1542 | ||
1543 | if (p8info != NULL) | |
1544 | ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); | |
1545 | else | |
1546 | free_asn1_data(strtype, str); | |
1547 | ||
1548 | PKCS8_PRIV_KEY_INFO_free(p8info); | |
1549 | ||
1550 | return ret; | |
1551 | } | |
1552 | ||
1553 | static int key_to_spki_der_pub_bio(BIO *out, const void *key, | |
1554 | int key_nid, | |
1555 | ossl_unused const char *pemname, | |
1556 | key_to_paramstring_fn *p2s, | |
1557 | i2d_of_void *k2d, | |
1558 | struct key2any_ctx_st *ctx) | |
1559 | { | |
1560 | int ret = 0; | |
1561 | X509_PUBKEY *xpk = NULL; | |
1562 | void *str = NULL; | |
1563 | int strtype = V_ASN1_UNDEF; | |
1564 | ||
1565 | if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, | |
1566 | &str, &strtype)) | |
1567 | return 0; | |
1568 | ||
1569 | xpk = xorx_key_to_pubkey(key, key_nid, str, strtype, k2d); | |
1570 | ||
1571 | if (xpk != NULL) | |
1572 | ret = i2d_X509_PUBKEY_bio(out, xpk); | |
1573 | ||
1574 | X509_PUBKEY_free(xpk); | |
1575 | return ret; | |
1576 | } | |
1577 | ||
1578 | static int key_to_spki_pem_pub_bio(BIO *out, const void *key, | |
1579 | int key_nid, | |
1580 | ossl_unused const char *pemname, | |
1581 | key_to_paramstring_fn *p2s, | |
1582 | i2d_of_void *k2d, | |
1583 | struct key2any_ctx_st *ctx) | |
1584 | { | |
1585 | int ret = 0; | |
1586 | X509_PUBKEY *xpk = NULL; | |
1587 | void *str = NULL; | |
1588 | int strtype = V_ASN1_UNDEF; | |
1589 | ||
1590 | if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters, | |
1591 | &str, &strtype)) | |
1592 | return 0; | |
1593 | ||
1594 | xpk = xorx_key_to_pubkey(key, key_nid, str, strtype, k2d); | |
1595 | ||
1596 | if (xpk != NULL) | |
1597 | ret = PEM_write_bio_X509_PUBKEY(out, xpk); | |
1598 | else | |
1599 | free_asn1_data(strtype, str); | |
1600 | ||
1601 | /* Also frees |str| */ | |
1602 | X509_PUBKEY_free(xpk); | |
1603 | return ret; | |
1604 | } | |
1605 | ||
1606 | /* ---------------------------------------------------------------------- */ | |
1607 | ||
1608 | static int prepare_xorx_params(const void *xorxkey, int nid, int save, | |
1609 | void **pstr, int *pstrtype) | |
1610 | { | |
1611 | ASN1_OBJECT *params = NULL; | |
1612 | XORKEY *k = (XORKEY*)xorxkey; | |
1613 | ||
1614 | if (k->tls_name && OBJ_sn2nid(k->tls_name) != nid) { | |
1615 | ERR_raise(ERR_LIB_USER, XORPROV_R_INVALID_KEY); | |
1616 | return 0; | |
1617 | } | |
1618 | ||
1619 | if (nid == NID_undef) { | |
1620 | ERR_raise(ERR_LIB_USER, XORPROV_R_MISSING_OID); | |
1621 | return 0; | |
1622 | } | |
1623 | ||
1624 | params = OBJ_nid2obj(nid); | |
1625 | ||
1626 | if (params == NULL || OBJ_length(params) == 0) { | |
1627 | /* unexpected error */ | |
1628 | ERR_raise(ERR_LIB_USER, XORPROV_R_MISSING_OID); | |
1629 | ASN1_OBJECT_free(params); | |
1630 | return 0; | |
1631 | } | |
1632 | *pstr = params; | |
1633 | *pstrtype = V_ASN1_OBJECT; | |
1634 | return 1; | |
1635 | } | |
1636 | ||
1637 | static int xorx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) | |
1638 | { | |
1639 | const XORKEY *xorxkey = vecxkey; | |
1640 | unsigned char *keyblob; | |
1641 | int retlen; | |
1642 | ||
1643 | if (xorxkey == NULL) { | |
1644 | ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER); | |
1645 | return 0; | |
1646 | } | |
1647 | ||
1648 | keyblob = OPENSSL_memdup(xorxkey->pubkey, retlen = XOR_KEY_SIZE); | |
1649 | if (keyblob == NULL) { | |
1650 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
1651 | return 0; | |
1652 | } | |
1653 | ||
1654 | *pder = keyblob; | |
1655 | return retlen; | |
1656 | } | |
1657 | ||
1658 | static int xorx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) | |
1659 | { | |
1660 | XORKEY *xorxkey = (XORKEY *)vecxkey; | |
1661 | unsigned char* buf = NULL; | |
1662 | ASN1_OCTET_STRING oct; | |
1663 | int keybloblen; | |
1664 | ||
1665 | if (xorxkey == NULL) { | |
1666 | ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER); | |
1667 | return 0; | |
1668 | } | |
1669 | ||
1670 | buf = OPENSSL_secure_malloc(XOR_KEY_SIZE); | |
1671 | memcpy(buf, xorxkey->privkey, XOR_KEY_SIZE); | |
1672 | ||
1673 | oct.data = buf; | |
1674 | oct.length = XOR_KEY_SIZE; | |
1675 | oct.flags = 0; | |
1676 | ||
1677 | keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); | |
1678 | if (keybloblen < 0) { | |
1679 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
1680 | keybloblen = 0; | |
1681 | } | |
1682 | ||
1683 | OPENSSL_secure_clear_free(buf, XOR_KEY_SIZE); | |
1684 | return keybloblen; | |
1685 | } | |
1686 | ||
1687 | # define xorx_epki_priv_to_der xorx_pki_priv_to_der | |
1688 | ||
1689 | /* | |
1690 | * XORX only has PKCS#8 / SubjectPublicKeyInfo | |
1691 | * representation, so we don't define xorx_type_specific_[priv,pub,params]_to_der. | |
1692 | */ | |
1693 | ||
1694 | # define xorx_check_key_type NULL | |
1695 | ||
1696 | # define xorhmacsig_evp_type 0 | |
1697 | # define xorhmacsig_input_type XORSIGALG_NAME | |
1698 | # define xorhmacsig_pem_type XORSIGALG_NAME | |
1699 | # define xorhmacsha2sig_evp_type 0 | |
1700 | # define xorhmacsha2sig_input_type XORSIGALG_HASH_NAME | |
1701 | # define xorhmacsha2sig_pem_type XORSIGALG_HASH_NAME | |
1702 | ||
1703 | /* ---------------------------------------------------------------------- */ | |
1704 | ||
1705 | static OSSL_FUNC_decoder_newctx_fn key2any_newctx; | |
1706 | static OSSL_FUNC_decoder_freectx_fn key2any_freectx; | |
1707 | ||
1708 | static void *key2any_newctx(void *provctx) | |
1709 | { | |
1710 | struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
1711 | ||
1712 | if (ctx != NULL) { | |
1713 | ctx->provctx = provctx; | |
1714 | ctx->save_parameters = 1; | |
1715 | } | |
1716 | ||
1717 | return ctx; | |
1718 | } | |
1719 | ||
1720 | static void key2any_freectx(void *vctx) | |
1721 | { | |
1722 | struct key2any_ctx_st *ctx = vctx; | |
1723 | ||
1724 | EVP_CIPHER_free(ctx->cipher); | |
1725 | OPENSSL_free(ctx); | |
1726 | } | |
1727 | ||
1728 | static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx) | |
1729 | { | |
1730 | static const OSSL_PARAM settables[] = { | |
1731 | OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0), | |
1732 | OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0), | |
1733 | OSSL_PARAM_END, | |
1734 | }; | |
1735 | ||
1736 | return settables; | |
1737 | } | |
1738 | ||
1739 | static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) | |
1740 | { | |
1741 | struct key2any_ctx_st *ctx = vctx; | |
1742 | OSSL_LIB_CTX *libctx = PROV_XOR_LIBCTX_OF(ctx->provctx); | |
1743 | const OSSL_PARAM *cipherp = | |
1744 | OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER); | |
1745 | const OSSL_PARAM *propsp = | |
1746 | OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES); | |
1747 | const OSSL_PARAM *save_paramsp = | |
1748 | OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_SAVE_PARAMETERS); | |
1749 | ||
1750 | if (cipherp != NULL) { | |
1751 | const char *ciphername = NULL; | |
1752 | const char *props = NULL; | |
1753 | ||
1754 | if (!OSSL_PARAM_get_utf8_string_ptr(cipherp, &ciphername)) | |
1755 | return 0; | |
1756 | if (propsp != NULL && !OSSL_PARAM_get_utf8_string_ptr(propsp, &props)) | |
1757 | return 0; | |
1758 | ||
1759 | EVP_CIPHER_free(ctx->cipher); | |
1760 | ctx->cipher = NULL; | |
1761 | ctx->cipher_intent = ciphername != NULL; | |
1762 | if (ciphername != NULL | |
1763 | && ((ctx->cipher = | |
1764 | EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL)) { | |
1765 | return 0; | |
1766 | } | |
1767 | } | |
1768 | ||
1769 | if (save_paramsp != NULL) { | |
1770 | if (!OSSL_PARAM_get_int(save_paramsp, &ctx->save_parameters)) { | |
1771 | return 0; | |
1772 | } | |
1773 | } | |
1774 | return 1; | |
1775 | } | |
1776 | ||
1777 | static int key2any_check_selection(int selection, int selection_mask) | |
1778 | { | |
1779 | /* | |
1780 | * The selections are kinda sorta "levels", i.e. each selection given | |
1781 | * here is assumed to include those following. | |
1782 | */ | |
1783 | int checks[] = { | |
1784 | OSSL_KEYMGMT_SELECT_PRIVATE_KEY, | |
1785 | OSSL_KEYMGMT_SELECT_PUBLIC_KEY, | |
1786 | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | |
1787 | }; | |
1788 | size_t i; | |
1789 | ||
1790 | /* The decoder implementations made here support guessing */ | |
1791 | if (selection == 0) | |
1792 | return 1; | |
1793 | ||
1794 | for (i = 0; i < OSSL_NELEM(checks); i++) { | |
1795 | int check1 = (selection & checks[i]) != 0; | |
1796 | int check2 = (selection_mask & checks[i]) != 0; | |
1797 | ||
1798 | /* | |
1799 | * If the caller asked for the currently checked bit(s), return | |
1800 | * whether the decoder description says it's supported. | |
1801 | */ | |
1802 | if (check1) | |
1803 | return check2; | |
1804 | } | |
1805 | ||
1806 | /* This should be dead code, but just to be safe... */ | |
1807 | return 0; | |
1808 | } | |
1809 | ||
1810 | static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, | |
1811 | const void *key, const char* typestr, const char *pemname, | |
1812 | key_to_der_fn *writer, | |
1813 | OSSL_PASSPHRASE_CALLBACK *pwcb, void *pwcbarg, | |
1814 | key_to_paramstring_fn *key2paramstring, | |
1815 | i2d_of_void *key2der) | |
1816 | { | |
1817 | int ret = 0; | |
1818 | int type = OBJ_sn2nid(typestr); | |
1819 | ||
1820 | if (key == NULL || type <= 0) { | |
1821 | ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER); | |
1822 | } else if (writer != NULL) { | |
1823 | BIO *out = BIO_new_from_core_bio(ctx->provctx->libctx, cout); | |
1824 | ||
1825 | if (out != NULL) { | |
1826 | ctx->pwcb = pwcb; | |
1827 | ctx->pwcbarg = pwcbarg; | |
1828 | ||
1829 | ret = writer(out, key, type, pemname, key2paramstring, key2der, ctx); | |
1830 | } | |
1831 | ||
1832 | BIO_free(out); | |
1833 | } else { | |
1834 | ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT); | |
1835 | } | |
1836 | return ret; | |
1837 | } | |
1838 | ||
1839 | #define DO_ENC_PRIVATE_KEY_selection_mask OSSL_KEYMGMT_SELECT_PRIVATE_KEY | |
1840 | #define DO_ENC_PRIVATE_KEY(impl, type, kind, output) \ | |
1841 | if ((selection & DO_ENC_PRIVATE_KEY_selection_mask) != 0) \ | |
1842 | return key2any_encode(ctx, cout, key, impl##_pem_type, \ | |
1843 | impl##_pem_type " PRIVATE KEY", \ | |
1844 | key_to_##kind##_##output##_priv_bio, \ | |
1845 | cb, cbarg, prepare_##type##_params, \ | |
1846 | type##_##kind##_priv_to_der); | |
1847 | ||
1848 | #define DO_ENC_PUBLIC_KEY_selection_mask OSSL_KEYMGMT_SELECT_PUBLIC_KEY | |
1849 | #define DO_ENC_PUBLIC_KEY(impl, type, kind, output) \ | |
1850 | if ((selection & DO_ENC_PUBLIC_KEY_selection_mask) != 0) \ | |
1851 | return key2any_encode(ctx, cout, key, impl##_pem_type, \ | |
1852 | impl##_pem_type " PUBLIC KEY", \ | |
1853 | key_to_##kind##_##output##_pub_bio, \ | |
1854 | cb, cbarg, prepare_##type##_params, \ | |
1855 | type##_##kind##_pub_to_der); | |
1856 | ||
1857 | #define DO_ENC_PARAMETERS_selection_mask OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | |
1858 | #define DO_ENC_PARAMETERS(impl, type, kind, output) \ | |
1859 | if ((selection & DO_ENC_PARAMETERS_selection_mask) != 0) \ | |
1860 | return key2any_encode(ctx, cout, key, impl##_pem_type, \ | |
1861 | impl##_pem_type " PARAMETERS", \ | |
1862 | key_to_##kind##_##output##_param_bio, \ | |
1863 | NULL, NULL, NULL, \ | |
1864 | type##_##kind##_params_to_der); | |
1865 | ||
1866 | /*- | |
1867 | * Implement the kinds of output structure that can be produced. They are | |
1868 | * referred to by name, and for each name, the following macros are defined | |
1869 | * (braces not included): | |
1870 | * | |
1871 | * DO_{kind}_selection_mask | |
1872 | * | |
1873 | * A mask of selection bits that must not be zero. This is used as a | |
1874 | * selection criterion for each implementation. | |
1875 | * This mask must never be zero. | |
1876 | * | |
1877 | * DO_{kind} | |
1878 | * | |
1879 | * The performing macro. It must use the DO_ macros defined above, | |
1880 | * always in this order: | |
1881 | * | |
1882 | * - DO_PRIVATE_KEY | |
1883 | * - DO_PUBLIC_KEY | |
1884 | * - DO_PARAMETERS | |
1885 | * | |
1886 | * Any of those may be omitted, but the relative order must still be | |
1887 | * the same. | |
1888 | */ | |
1889 | ||
1890 | /* | |
1891 | * PKCS#8 defines two structures for private keys only: | |
1892 | * - PrivateKeyInfo (raw unencrypted form) | |
1893 | * - EncryptedPrivateKeyInfo (encrypted wrapping) | |
1894 | * | |
1895 | * To allow a certain amount of flexibility, we allow the routines | |
1896 | * for PrivateKeyInfo to also produce EncryptedPrivateKeyInfo if a | |
1897 | * passphrase callback has been passed to them. | |
1898 | */ | |
1899 | #define DO_ENC_PrivateKeyInfo_selection_mask DO_ENC_PRIVATE_KEY_selection_mask | |
1900 | #define DO_ENC_PrivateKeyInfo(impl, type, output) \ | |
1901 | DO_ENC_PRIVATE_KEY(impl, type, pki, output) | |
1902 | ||
1903 | #define DO_ENC_EncryptedPrivateKeyInfo_selection_mask DO_ENC_PRIVATE_KEY_selection_mask | |
1904 | #define DO_ENC_EncryptedPrivateKeyInfo(impl, type, output) \ | |
1905 | DO_ENC_PRIVATE_KEY(impl, type, epki, output) | |
1906 | ||
1907 | /* SubjectPublicKeyInfo is a structure for public keys only */ | |
1908 | #define DO_ENC_SubjectPublicKeyInfo_selection_mask DO_ENC_PUBLIC_KEY_selection_mask | |
1909 | #define DO_ENC_SubjectPublicKeyInfo(impl, type, output) \ | |
1910 | DO_ENC_PUBLIC_KEY(impl, type, spki, output) | |
1911 | ||
1912 | /* | |
1913 | * MAKE_ENCODER is the single driver for creating OSSL_DISPATCH tables. | |
1914 | * It takes the following arguments: | |
1915 | * | |
1916 | * impl This is the key type name that's being implemented. | |
1917 | * type This is the type name for the set of functions that implement | |
1918 | * the key type. For example, ed25519, ed448, x25519 and x448 | |
1919 | * are all implemented with the exact same set of functions. | |
1920 | * kind What kind of support to implement. These translate into | |
1921 | * the DO_##kind macros above. | |
1922 | * output The output type to implement. may be der or pem. | |
1923 | * | |
1924 | * The resulting OSSL_DISPATCH array gets the following name (expressed in | |
1925 | * C preprocessor terms) from those arguments: | |
1926 | * | |
1927 | * xor_##impl##_to_##kind##_##output##_encoder_functions | |
1928 | */ | |
1929 | #define MAKE_ENCODER(impl, type, kind, output) \ | |
1930 | static OSSL_FUNC_encoder_import_object_fn \ | |
1931 | impl##_to_##kind##_##output##_import_object; \ | |
1932 | static OSSL_FUNC_encoder_free_object_fn \ | |
1933 | impl##_to_##kind##_##output##_free_object; \ | |
1934 | static OSSL_FUNC_encoder_encode_fn \ | |
1935 | impl##_to_##kind##_##output##_encode; \ | |
1936 | \ | |
1937 | static void * \ | |
1938 | impl##_to_##kind##_##output##_import_object(void *vctx, int selection, \ | |
1939 | const OSSL_PARAM params[]) \ | |
1940 | { \ | |
1941 | struct key2any_ctx_st *ctx = vctx; \ | |
1942 | \ | |
1943 | return xor_prov_import_key(xor_##impl##_keymgmt_functions, \ | |
1944 | ctx->provctx, selection, params); \ | |
1945 | } \ | |
1946 | static void impl##_to_##kind##_##output##_free_object(void *key) \ | |
1947 | { \ | |
1948 | xor_prov_free_key(xor_##impl##_keymgmt_functions, key); \ | |
1949 | } \ | |
1950 | static int impl##_to_##kind##_##output##_does_selection(void *ctx, \ | |
1951 | int selection) \ | |
1952 | { \ | |
1953 | return key2any_check_selection(selection, \ | |
1954 | DO_ENC_##kind##_selection_mask); \ | |
1955 | } \ | |
1956 | static int \ | |
1957 | impl##_to_##kind##_##output##_encode(void *ctx, OSSL_CORE_BIO *cout, \ | |
1958 | const void *key, \ | |
1959 | const OSSL_PARAM key_abstract[], \ | |
1960 | int selection, \ | |
1961 | OSSL_PASSPHRASE_CALLBACK *cb, \ | |
1962 | void *cbarg) \ | |
1963 | { \ | |
1964 | /* We don't deal with abstract objects */ \ | |
1965 | if (key_abstract != NULL) { \ | |
1966 | ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT); \ | |
1967 | return 0; \ | |
1968 | } \ | |
1969 | DO_ENC_##kind(impl, type, output) \ | |
1970 | \ | |
1971 | ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT); \ | |
1972 | return 0; \ | |
1973 | } \ | |
1974 | static const OSSL_DISPATCH \ | |
1975 | xor_##impl##_to_##kind##_##output##_encoder_functions[] = { \ | |
1976 | { OSSL_FUNC_ENCODER_NEWCTX, \ | |
1977 | (void (*)(void))key2any_newctx }, \ | |
1978 | { OSSL_FUNC_ENCODER_FREECTX, \ | |
1979 | (void (*)(void))key2any_freectx }, \ | |
1980 | { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS, \ | |
1981 | (void (*)(void))key2any_settable_ctx_params }, \ | |
1982 | { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, \ | |
1983 | (void (*)(void))key2any_set_ctx_params }, \ | |
1984 | { OSSL_FUNC_ENCODER_DOES_SELECTION, \ | |
1985 | (void (*)(void))impl##_to_##kind##_##output##_does_selection }, \ | |
1986 | { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ | |
1987 | (void (*)(void))impl##_to_##kind##_##output##_import_object }, \ | |
1988 | { OSSL_FUNC_ENCODER_FREE_OBJECT, \ | |
1989 | (void (*)(void))impl##_to_##kind##_##output##_free_object }, \ | |
1990 | { OSSL_FUNC_ENCODER_ENCODE, \ | |
1991 | (void (*)(void))impl##_to_##kind##_##output##_encode }, \ | |
1992 | { 0, NULL } \ | |
1993 | } | |
1994 | ||
1995 | /* | |
1996 | * Replacements for i2d_{TYPE}PrivateKey, i2d_{TYPE}PublicKey, | |
1997 | * i2d_{TYPE}params, as they exist. | |
1998 | */ | |
1999 | ||
2000 | /* | |
2001 | * PKCS#8 and SubjectPublicKeyInfo support. This may duplicate some of the | |
2002 | * implementations specified above, but are more specific. | |
2003 | * The SubjectPublicKeyInfo implementations also replace the | |
2004 | * PEM_write_bio_{TYPE}_PUBKEY functions. | |
2005 | * For PEM, these are expected to be used by PEM_write_bio_PrivateKey(), | |
2006 | * PEM_write_bio_PUBKEY() and PEM_write_bio_Parameters(). | |
2007 | */ | |
2008 | ||
2009 | MAKE_ENCODER(xorhmacsig, xorx, EncryptedPrivateKeyInfo, der); | |
2010 | MAKE_ENCODER(xorhmacsig, xorx, EncryptedPrivateKeyInfo, pem); | |
2011 | MAKE_ENCODER(xorhmacsig, xorx, PrivateKeyInfo, der); | |
2012 | MAKE_ENCODER(xorhmacsig, xorx, PrivateKeyInfo, pem); | |
2013 | MAKE_ENCODER(xorhmacsig, xorx, SubjectPublicKeyInfo, der); | |
2014 | MAKE_ENCODER(xorhmacsig, xorx, SubjectPublicKeyInfo, pem); | |
2015 | MAKE_ENCODER(xorhmacsha2sig, xorx, EncryptedPrivateKeyInfo, der); | |
2016 | MAKE_ENCODER(xorhmacsha2sig, xorx, EncryptedPrivateKeyInfo, pem); | |
2017 | MAKE_ENCODER(xorhmacsha2sig, xorx, PrivateKeyInfo, der); | |
2018 | MAKE_ENCODER(xorhmacsha2sig, xorx, PrivateKeyInfo, pem); | |
2019 | MAKE_ENCODER(xorhmacsha2sig, xorx, SubjectPublicKeyInfo, der); | |
2020 | MAKE_ENCODER(xorhmacsha2sig, xorx, SubjectPublicKeyInfo, pem); | |
2021 | ||
2022 | static const OSSL_ALGORITHM tls_prov_encoder[] = { | |
2023 | #define ENCODER_PROVIDER "tls-provider" | |
2024 | #ifndef ENCODER_PROVIDER | |
2025 | # error Macro ENCODER_PROVIDER undefined | |
2026 | #endif | |
2027 | ||
2028 | #define ENCODER_STRUCTURE_PKCS8 "pkcs8" | |
2029 | #define ENCODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo" | |
2030 | #define ENCODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo" | |
2031 | #define ENCODER_STRUCTURE_EncryptedPrivateKeyInfo "EncryptedPrivateKeyInfo" | |
2032 | #define ENCODER_STRUCTURE_PKCS1 "pkcs1" | |
2033 | #define ENCODER_STRUCTURE_PKCS3 "pkcs3" | |
2034 | ||
2035 | /* Arguments are prefixed with '_' to avoid build breaks on certain platforms */ | |
2036 | /* | |
2037 | * Obviously this is not FIPS approved, but in order to test in conjunction | |
2038 | * with the FIPS provider we pretend that it is. | |
2039 | */ | |
2040 | #define ENCODER_TEXT(_name, _sym) \ | |
2041 | { _name, \ | |
2042 | "provider=" ENCODER_PROVIDER ",fips=yes,output=text", \ | |
2043 | (xor_##_sym##_to_text_encoder_functions) } | |
2044 | #define ENCODER(_name, _sym, _fips, _output) \ | |
2045 | { _name, \ | |
2046 | "provider=" ENCODER_PROVIDER ",fips=yes,output=" #_output, \ | |
2047 | (xor_##_sym##_to_##_output##_encoder_functions) } | |
2048 | ||
2049 | #define ENCODER_w_structure(_name, _sym, _output, _structure) \ | |
2050 | { _name, \ | |
2051 | "provider=" ENCODER_PROVIDER ",fips=yes,output=" #_output \ | |
2052 | ",structure=" ENCODER_STRUCTURE_##_structure, \ | |
2053 | (xor_##_sym##_to_##_structure##_##_output##_encoder_functions) } | |
2054 | ||
2055 | /* | |
2056 | * Entries for human text "encoders" | |
2057 | */ | |
2058 | ||
2059 | /* | |
2060 | * Entries for PKCS#8 and SubjectPublicKeyInfo. | |
2061 | * The "der" ones are added convenience for any user that wants to use | |
2062 | * OSSL_ENCODER directly. | |
2063 | * The "pem" ones also support PEM_write_bio_PrivateKey() and | |
2064 | * PEM_write_bio_PUBKEY(). | |
2065 | */ | |
2066 | ||
2067 | ENCODER_w_structure(XORSIGALG_NAME, xorhmacsig, der, PrivateKeyInfo), | |
2068 | ENCODER_w_structure(XORSIGALG_NAME, xorhmacsig, pem, PrivateKeyInfo), | |
2069 | ENCODER_w_structure(XORSIGALG_NAME, xorhmacsig, der, EncryptedPrivateKeyInfo), | |
2070 | ENCODER_w_structure(XORSIGALG_NAME, xorhmacsig, pem, EncryptedPrivateKeyInfo), | |
2071 | ENCODER_w_structure(XORSIGALG_NAME, xorhmacsig, der, SubjectPublicKeyInfo), | |
2072 | ENCODER_w_structure(XORSIGALG_NAME, xorhmacsig, pem, SubjectPublicKeyInfo), | |
2073 | ENCODER_w_structure(XORSIGALG_HASH_NAME, xorhmacsha2sig, | |
2074 | der, PrivateKeyInfo), | |
2075 | ENCODER_w_structure(XORSIGALG_HASH_NAME, xorhmacsha2sig, | |
2076 | pem, PrivateKeyInfo), | |
2077 | ENCODER_w_structure(XORSIGALG_HASH_NAME, xorhmacsha2sig, | |
2078 | der, EncryptedPrivateKeyInfo), | |
2079 | ENCODER_w_structure(XORSIGALG_HASH_NAME, xorhmacsha2sig, | |
2080 | pem, EncryptedPrivateKeyInfo), | |
2081 | ENCODER_w_structure(XORSIGALG_HASH_NAME, xorhmacsha2sig, | |
2082 | der, SubjectPublicKeyInfo), | |
2083 | ENCODER_w_structure(XORSIGALG_HASH_NAME, xorhmacsha2sig, | |
2084 | pem, SubjectPublicKeyInfo), | |
2085 | #undef ENCODER_PROVIDER | |
2086 | { NULL, NULL, NULL } | |
2087 | }; | |
2088 | ||
2089 | struct der2key_ctx_st; /* Forward declaration */ | |
2090 | typedef int check_key_fn(void *, struct der2key_ctx_st *ctx); | |
2091 | typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx); | |
2092 | typedef void free_key_fn(void *); | |
2093 | typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long, | |
2094 | struct der2key_ctx_st *); | |
2095 | struct keytype_desc_st { | |
2096 | const char *keytype_name; | |
2097 | const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ | |
2098 | ||
2099 | /* The input structure name */ | |
2100 | const char *structure_name; | |
2101 | ||
2102 | /* | |
2103 | * The EVP_PKEY_xxx type macro. Should be zero for type specific | |
2104 | * structures, non-zero when the outermost structure is PKCS#8 or | |
2105 | * SubjectPublicKeyInfo. This determines which of the function | |
2106 | * pointers below will be used. | |
2107 | */ | |
2108 | int evp_type; | |
2109 | ||
2110 | /* The selection mask for OSSL_FUNC_decoder_does_selection() */ | |
2111 | int selection_mask; | |
2112 | ||
2113 | /* For type specific decoders, we use the corresponding d2i */ | |
2114 | d2i_of_void *d2i_private_key; /* From type-specific DER */ | |
2115 | d2i_of_void *d2i_public_key; /* From type-specific DER */ | |
2116 | d2i_of_void *d2i_key_params; /* From type-specific DER */ | |
2117 | d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PrivateKeyInfo */ | |
2118 | d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */ | |
2119 | ||
2120 | /* | |
2121 | * For any key, we may need to check that the key meets expectations. | |
2122 | * This is useful when the same functions can decode several variants | |
2123 | * of a key. | |
2124 | */ | |
2125 | check_key_fn *check_key; | |
2126 | ||
2127 | /* | |
2128 | * For any key, we may need to make provider specific adjustments, such | |
2129 | * as ensure the key carries the correct library context. | |
2130 | */ | |
2131 | adjust_key_fn *adjust_key; | |
2132 | /* {type}_free() */ | |
2133 | free_key_fn *free_key; | |
2134 | }; | |
2135 | ||
2136 | /* | |
2137 | * Start blatant code steal. Alternative: Open up d2i_X509_PUBKEY_INTERNAL | |
2138 | * as per https://github.com/openssl/openssl/issues/16697 (TBD) | |
2139 | * Code from from openssl/crypto/x509/x_pubkey.c as | |
2140 | * ossl_d2i_X509_PUBKEY_INTERNAL is presently not public | |
2141 | */ | |
2142 | struct X509_pubkey_st { | |
2143 | X509_ALGOR *algor; | |
2144 | ASN1_BIT_STRING *public_key; | |
2145 | ||
2146 | EVP_PKEY *pkey; | |
2147 | ||
2148 | /* extra data for the callback, used by d2i_PUBKEY_ex */ | |
2149 | OSSL_LIB_CTX *libctx; | |
2150 | char *propq; | |
2151 | }; | |
2152 | ||
2153 | ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { | |
2154 | ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), | |
2155 | ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) | |
2156 | } static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) | |
2157 | ||
2158 | static X509_PUBKEY *xorx_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, | |
2159 | long len, OSSL_LIB_CTX *libctx) | |
2160 | { | |
2161 | X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); | |
2162 | ||
2163 | if (xpub == NULL) | |
2164 | return NULL; | |
2165 | return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len, | |
2166 | ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), | |
2167 | libctx, NULL); | |
2168 | } | |
2169 | /* end steal https://github.com/openssl/openssl/issues/16697 */ | |
2170 | ||
2171 | /* | |
2172 | * Context used for DER to key decoding. | |
2173 | */ | |
2174 | struct der2key_ctx_st { | |
2175 | PROV_XOR_CTX *provctx; | |
2176 | struct keytype_desc_st *desc; | |
2177 | /* The selection that is passed to xor_der2key_decode() */ | |
2178 | int selection; | |
2179 | /* Flag used to signal that a failure is fatal */ | |
2180 | unsigned int flag_fatal : 1; | |
2181 | }; | |
2182 | ||
2183 | static int xor_read_der(PROV_XOR_CTX *provctx, OSSL_CORE_BIO *cin, | |
2184 | unsigned char **data, long *len) | |
2185 | { | |
2186 | BUF_MEM *mem = NULL; | |
2187 | BIO *in = BIO_new_from_core_bio(provctx->libctx, cin); | |
2188 | int ok = (asn1_d2i_read_bio(in, &mem) >= 0); | |
2189 | ||
2190 | if (ok) { | |
2191 | *data = (unsigned char *)mem->data; | |
2192 | *len = (long)mem->length; | |
2193 | OPENSSL_free(mem); | |
2194 | } | |
2195 | BIO_free(in); | |
2196 | return ok; | |
2197 | } | |
2198 | ||
2199 | typedef void *key_from_pkcs8_t(const PKCS8_PRIV_KEY_INFO *p8inf, | |
2200 | OSSL_LIB_CTX *libctx, const char *propq); | |
2201 | static void *xor_der2key_decode_p8(const unsigned char **input_der, | |
2202 | long input_der_len, struct der2key_ctx_st *ctx, | |
2203 | key_from_pkcs8_t *key_from_pkcs8) | |
2204 | { | |
2205 | PKCS8_PRIV_KEY_INFO *p8inf = NULL; | |
2206 | const X509_ALGOR *alg = NULL; | |
2207 | void *key = NULL; | |
2208 | ||
2209 | if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len)) != NULL | |
2210 | && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf) | |
2211 | && OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type) | |
2212 | key = key_from_pkcs8(p8inf, PROV_XOR_LIBCTX_OF(ctx->provctx), NULL); | |
2213 | PKCS8_PRIV_KEY_INFO_free(p8inf); | |
2214 | ||
2215 | return key; | |
2216 | } | |
2217 | ||
2218 | static XORKEY *xor_d2i_PUBKEY(XORKEY **a, | |
2219 | const unsigned char **pp, long length) | |
2220 | { | |
2221 | XORKEY *key = NULL; | |
2222 | X509_PUBKEY *xpk; | |
2223 | ||
2224 | xpk = xorx_d2i_X509_PUBKEY_INTERNAL(pp, length, NULL); | |
2225 | ||
2226 | key = xor_key_from_x509pubkey(xpk, NULL, NULL); | |
2227 | ||
2228 | if (key == NULL) | |
2229 | goto err_exit; | |
2230 | ||
2231 | if (a != NULL) { | |
2232 | xor_freekey(*a); | |
2233 | *a = key; | |
2234 | } | |
2235 | ||
2236 | err_exit: | |
2237 | X509_PUBKEY_free(xpk); | |
2238 | return key; | |
2239 | } | |
2240 | ||
2241 | ||
2242 | /* ---------------------------------------------------------------------- */ | |
2243 | ||
2244 | static OSSL_FUNC_decoder_freectx_fn der2key_freectx; | |
2245 | static OSSL_FUNC_decoder_decode_fn xor_der2key_decode; | |
2246 | static OSSL_FUNC_decoder_export_object_fn der2key_export_object; | |
2247 | ||
2248 | static struct der2key_ctx_st * | |
2249 | der2key_newctx(void *provctx, struct keytype_desc_st *desc, const char* tls_name) | |
2250 | { | |
2251 | struct der2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
2252 | ||
2253 | if (ctx != NULL) { | |
2254 | ctx->provctx = provctx; | |
2255 | ctx->desc = desc; | |
2256 | if (desc->evp_type == 0) { | |
2257 | ctx->desc->evp_type = OBJ_sn2nid(tls_name); | |
2258 | } | |
2259 | } | |
2260 | return ctx; | |
2261 | } | |
2262 | ||
2263 | static void der2key_freectx(void *vctx) | |
2264 | { | |
2265 | struct der2key_ctx_st *ctx = vctx; | |
2266 | ||
2267 | OPENSSL_free(ctx); | |
2268 | } | |
2269 | ||
2270 | static int der2key_check_selection(int selection, | |
2271 | const struct keytype_desc_st *desc) | |
2272 | { | |
2273 | /* | |
2274 | * The selections are kinda sorta "levels", i.e. each selection given | |
2275 | * here is assumed to include those following. | |
2276 | */ | |
2277 | int checks[] = { | |
2278 | OSSL_KEYMGMT_SELECT_PRIVATE_KEY, | |
2279 | OSSL_KEYMGMT_SELECT_PUBLIC_KEY, | |
2280 | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | |
2281 | }; | |
2282 | size_t i; | |
2283 | ||
2284 | /* The decoder implementations made here support guessing */ | |
2285 | if (selection == 0) | |
2286 | return 1; | |
2287 | ||
2288 | for (i = 0; i < OSSL_NELEM(checks); i++) { | |
2289 | int check1 = (selection & checks[i]) != 0; | |
2290 | int check2 = (desc->selection_mask & checks[i]) != 0; | |
2291 | ||
2292 | /* | |
2293 | * If the caller asked for the currently checked bit(s), return | |
2294 | * whether the decoder description says it's supported. | |
2295 | */ | |
2296 | if (check1) | |
2297 | return check2; | |
2298 | } | |
2299 | ||
2300 | /* This should be dead code, but just to be safe... */ | |
2301 | return 0; | |
2302 | } | |
2303 | ||
2304 | static int xor_der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, | |
2305 | OSSL_CALLBACK *data_cb, void *data_cbarg, | |
2306 | OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) | |
2307 | { | |
2308 | struct der2key_ctx_st *ctx = vctx; | |
2309 | unsigned char *der = NULL; | |
2310 | const unsigned char *derp; | |
2311 | long der_len = 0; | |
2312 | void *key = NULL; | |
2313 | int ok = 0; | |
2314 | ||
2315 | ctx->selection = selection; | |
2316 | /* | |
2317 | * The caller is allowed to specify 0 as a selection mark, to have the | |
2318 | * structure and key type guessed. For type-specific structures, this | |
2319 | * is not recommended, as some structures are very similar. | |
2320 | * Note that 0 isn't the same as OSSL_KEYMGMT_SELECT_ALL, as the latter | |
2321 | * signifies a private key structure, where everything else is assumed | |
2322 | * to be present as well. | |
2323 | */ | |
2324 | if (selection == 0) | |
2325 | selection = ctx->desc->selection_mask; | |
2326 | if ((selection & ctx->desc->selection_mask) == 0) { | |
2327 | ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); | |
2328 | return 0; | |
2329 | } | |
2330 | ||
2331 | ok = xor_read_der(ctx->provctx, cin, &der, &der_len); | |
2332 | if (!ok) | |
2333 | goto next; | |
2334 | ||
2335 | ok = 0; /* Assume that we fail */ | |
2336 | ||
2337 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { | |
2338 | derp = der; | |
2339 | if (ctx->desc->d2i_PKCS8 != NULL) { | |
2340 | key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx); | |
2341 | if (ctx->flag_fatal) | |
2342 | goto end; | |
2343 | } else if (ctx->desc->d2i_private_key != NULL) { | |
2344 | key = ctx->desc->d2i_private_key(NULL, &derp, der_len); | |
2345 | } | |
2346 | if (key == NULL && ctx->selection != 0) | |
2347 | goto next; | |
2348 | } | |
2349 | if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { | |
2350 | derp = der; | |
2351 | if (ctx->desc->d2i_PUBKEY != NULL) | |
2352 | key = ctx->desc->d2i_PUBKEY(NULL, &derp, der_len); | |
2353 | else | |
2354 | key = ctx->desc->d2i_public_key(NULL, &derp, der_len); | |
2355 | if (key == NULL && ctx->selection != 0) | |
2356 | goto next; | |
2357 | } | |
2358 | if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) { | |
2359 | derp = der; | |
2360 | if (ctx->desc->d2i_key_params != NULL) | |
2361 | key = ctx->desc->d2i_key_params(NULL, &derp, der_len); | |
2362 | if (key == NULL && ctx->selection != 0) | |
2363 | goto next; | |
2364 | } | |
2365 | ||
2366 | /* | |
2367 | * Last minute check to see if this was the correct type of key. This | |
2368 | * should never lead to a fatal error, i.e. the decoding itself was | |
2369 | * correct, it was just an unexpected key type. This is generally for | |
2370 | * classes of key types that have subtle variants, like RSA-PSS keys as | |
2371 | * opposed to plain RSA keys. | |
2372 | */ | |
2373 | if (key != NULL | |
2374 | && ctx->desc->check_key != NULL | |
2375 | && !ctx->desc->check_key(key, ctx)) { | |
2376 | ctx->desc->free_key(key); | |
2377 | key = NULL; | |
2378 | } | |
2379 | ||
2380 | if (key != NULL && ctx->desc->adjust_key != NULL) | |
2381 | ctx->desc->adjust_key(key, ctx); | |
2382 | ||
2383 | next: | |
2384 | /* | |
2385 | * Indicated that we successfully decoded something, or not at all. | |
2386 | * Ending up "empty handed" is not an error. | |
2387 | */ | |
2388 | ok = 1; | |
2389 | ||
2390 | /* | |
2391 | * We free memory here so it's not held up during the callback, because | |
2392 | * we know the process is recursive and the allocated chunks of memory | |
2393 | * add up. | |
2394 | */ | |
2395 | OPENSSL_free(der); | |
2396 | der = NULL; | |
2397 | ||
2398 | if (key != NULL) { | |
2399 | OSSL_PARAM params[4]; | |
2400 | int object_type = OSSL_OBJECT_PKEY; | |
2401 | ||
2402 | params[0] = | |
2403 | OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); | |
2404 | params[1] = | |
2405 | OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, | |
2406 | (char *)ctx->desc->keytype_name, | |
2407 | 0); | |
2408 | /* The address of the key becomes the octet string */ | |
2409 | params[2] = | |
2410 | OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, | |
2411 | &key, sizeof(key)); | |
2412 | params[3] = OSSL_PARAM_construct_end(); | |
2413 | ||
2414 | ok = data_cb(params, data_cbarg); | |
2415 | } | |
2416 | ||
2417 | end: | |
2418 | ctx->desc->free_key(key); | |
2419 | OPENSSL_free(der); | |
2420 | ||
2421 | return ok; | |
2422 | } | |
2423 | ||
2424 | static int der2key_export_object(void *vctx, | |
2425 | const void *reference, size_t reference_sz, | |
2426 | OSSL_CALLBACK *export_cb, void *export_cbarg) | |
2427 | { | |
2428 | struct der2key_ctx_st *ctx = vctx; | |
2429 | OSSL_FUNC_keymgmt_export_fn *export = | |
2430 | xor_prov_get_keymgmt_export(ctx->desc->fns); | |
2431 | void *keydata; | |
2432 | ||
2433 | if (reference_sz == sizeof(keydata) && export != NULL) { | |
2434 | /* The contents of the reference is the address to our object */ | |
2435 | keydata = *(void **)reference; | |
2436 | ||
2437 | return export(keydata, ctx->selection, export_cb, export_cbarg); | |
2438 | } | |
2439 | return 0; | |
2440 | } | |
2441 | ||
2442 | /* ---------------------------------------------------------------------- */ | |
2443 | ||
2444 | static void *xorx_d2i_PKCS8(void **key, const unsigned char **der, long der_len, | |
2445 | struct der2key_ctx_st *ctx) | |
2446 | { | |
2447 | return xor_der2key_decode_p8(der, der_len, ctx, | |
2448 | (key_from_pkcs8_t *)xor_key_from_pkcs8); | |
2449 | } | |
2450 | ||
2451 | static void xorx_key_adjust(void *key, struct der2key_ctx_st *ctx) | |
2452 | { | |
2453 | } | |
2454 | ||
2455 | /* ---------------------------------------------------------------------- */ | |
2456 | ||
2457 | #define DO_PrivateKeyInfo(keytype) \ | |
2458 | "PrivateKeyInfo", 0, \ | |
2459 | ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ), \ | |
2460 | NULL, \ | |
2461 | NULL, \ | |
2462 | NULL, \ | |
2463 | xorx_d2i_PKCS8, \ | |
2464 | NULL, \ | |
2465 | NULL, \ | |
2466 | xorx_key_adjust, \ | |
2467 | (free_key_fn *)xor_freekey | |
2468 | ||
2469 | #define DO_SubjectPublicKeyInfo(keytype) \ | |
2470 | "SubjectPublicKeyInfo", 0, \ | |
2471 | ( OSSL_KEYMGMT_SELECT_PUBLIC_KEY ), \ | |
2472 | NULL, \ | |
2473 | NULL, \ | |
2474 | NULL, \ | |
2475 | NULL, \ | |
2476 | (d2i_of_void *)xor_d2i_PUBKEY, \ | |
2477 | NULL, \ | |
2478 | xorx_key_adjust, \ | |
2479 | (free_key_fn *)xor_freekey | |
2480 | ||
2481 | /* | |
2482 | * MAKE_DECODER is the single driver for creating OSSL_DISPATCH tables. | |
2483 | * It takes the following arguments: | |
2484 | * | |
2485 | * keytype_name The implementation key type as a string. | |
2486 | * keytype The implementation key type. This must correspond exactly | |
2487 | * to our existing keymgmt keytype names... in other words, | |
2488 | * there must exist an ossl_##keytype##_keymgmt_functions. | |
2489 | * type The type name for the set of functions that implement the | |
2490 | * decoder for the key type. This isn't necessarily the same | |
2491 | * as keytype. For example, the key types ed25519, ed448, | |
2492 | * x25519 and x448 are all handled by the same functions with | |
2493 | * the common type name ecx. | |
2494 | * kind The kind of support to implement. This translates into | |
2495 | * the DO_##kind macros above, to populate the keytype_desc_st | |
2496 | * structure. | |
2497 | */ | |
2498 | #define MAKE_DECODER(keytype_name, keytype, type, kind) \ | |
2499 | static struct keytype_desc_st kind##_##keytype##_desc = \ | |
2500 | { keytype_name, xor_##keytype##_keymgmt_functions, \ | |
2501 | DO_##kind(keytype) }; \ | |
2502 | \ | |
2503 | static OSSL_FUNC_decoder_newctx_fn kind##_der2##keytype##_newctx; \ | |
2504 | \ | |
2505 | static void *kind##_der2##keytype##_newctx(void *provctx) \ | |
2506 | { \ | |
2507 | return der2key_newctx(provctx, &kind##_##keytype##_desc, keytype_name );\ | |
2508 | } \ | |
2509 | static int kind##_der2##keytype##_does_selection(void *provctx, \ | |
2510 | int selection) \ | |
2511 | { \ | |
2512 | return der2key_check_selection(selection, \ | |
2513 | &kind##_##keytype##_desc); \ | |
2514 | } \ | |
2515 | static const OSSL_DISPATCH \ | |
2516 | xor_##kind##_der_to_##keytype##_decoder_functions[] = { \ | |
2517 | { OSSL_FUNC_DECODER_NEWCTX, \ | |
2518 | (void (*)(void))kind##_der2##keytype##_newctx }, \ | |
2519 | { OSSL_FUNC_DECODER_FREECTX, \ | |
2520 | (void (*)(void))der2key_freectx }, \ | |
2521 | { OSSL_FUNC_DECODER_DOES_SELECTION, \ | |
2522 | (void (*)(void))kind##_der2##keytype##_does_selection }, \ | |
2523 | { OSSL_FUNC_DECODER_DECODE, \ | |
2524 | (void (*)(void))xor_der2key_decode }, \ | |
2525 | { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ | |
2526 | (void (*)(void))der2key_export_object }, \ | |
2527 | { 0, NULL } \ | |
2528 | } | |
2529 | ||
2530 | MAKE_DECODER(XORSIGALG_NAME, xorhmacsig, xor, PrivateKeyInfo); | |
2531 | MAKE_DECODER(XORSIGALG_NAME, xorhmacsig, xor, SubjectPublicKeyInfo); | |
2532 | MAKE_DECODER(XORSIGALG_HASH_NAME, xorhmacsha2sig, xor, PrivateKeyInfo); | |
2533 | MAKE_DECODER(XORSIGALG_HASH_NAME, xorhmacsha2sig, xor, SubjectPublicKeyInfo); | |
2534 | ||
2535 | static const OSSL_ALGORITHM tls_prov_decoder[] = { | |
2536 | #define DECODER_PROVIDER "tls-provider" | |
2537 | #define DECODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo" | |
2538 | #define DECODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo" | |
2539 | ||
2540 | /* Arguments are prefixed with '_' to avoid build breaks on certain platforms */ | |
2541 | /* | |
2542 | * Obviously this is not FIPS approved, but in order to test in conjunction | |
2543 | * with the FIPS provider we pretend that it is. | |
2544 | */ | |
2545 | ||
2546 | #define DECODER(_name, _input, _output) \ | |
2547 | { _name, \ | |
2548 | "provider=" DECODER_PROVIDER ",fips=yes,input=" #_input, \ | |
2549 | (xor_##_input##_to_##_output##_decoder_functions) } | |
2550 | #define DECODER_w_structure(_name, _input, _structure, _output) \ | |
2551 | { _name, \ | |
2552 | "provider=" DECODER_PROVIDER ",fips=yes,input=" #_input \ | |
2553 | ",structure=" DECODER_STRUCTURE_##_structure, \ | |
2554 | (xor_##_structure##_##_input##_to_##_output##_decoder_functions) } | |
2555 | ||
2556 | DECODER_w_structure(XORSIGALG_NAME, der, PrivateKeyInfo, xorhmacsig), | |
2557 | DECODER_w_structure(XORSIGALG_NAME, der, SubjectPublicKeyInfo, xorhmacsig), | |
2558 | DECODER_w_structure(XORSIGALG_HASH_NAME, der, PrivateKeyInfo, xorhmacsha2sig), | |
2559 | DECODER_w_structure(XORSIGALG_HASH_NAME, der, SubjectPublicKeyInfo, xorhmacsha2sig), | |
2560 | #undef DECODER_PROVIDER | |
2561 | { NULL, NULL, NULL } | |
2562 | }; | |
2563 | ||
2564 | #define OSSL_MAX_NAME_SIZE 50 | |
2565 | #define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */ | |
2566 | ||
2567 | static OSSL_FUNC_signature_newctx_fn xor_sig_newctx; | |
2568 | static OSSL_FUNC_signature_sign_init_fn xor_sig_sign_init; | |
2569 | static OSSL_FUNC_signature_verify_init_fn xor_sig_verify_init; | |
2570 | static OSSL_FUNC_signature_sign_fn xor_sig_sign; | |
2571 | static OSSL_FUNC_signature_verify_fn xor_sig_verify; | |
2572 | static OSSL_FUNC_signature_digest_sign_init_fn xor_sig_digest_sign_init; | |
2573 | static OSSL_FUNC_signature_digest_sign_update_fn xor_sig_digest_signverify_update; | |
2574 | static OSSL_FUNC_signature_digest_sign_final_fn xor_sig_digest_sign_final; | |
2575 | static OSSL_FUNC_signature_digest_verify_init_fn xor_sig_digest_verify_init; | |
2576 | static OSSL_FUNC_signature_digest_verify_update_fn xor_sig_digest_signverify_update; | |
2577 | static OSSL_FUNC_signature_digest_verify_final_fn xor_sig_digest_verify_final; | |
2578 | static OSSL_FUNC_signature_freectx_fn xor_sig_freectx; | |
2579 | static OSSL_FUNC_signature_dupctx_fn xor_sig_dupctx; | |
2580 | static OSSL_FUNC_signature_get_ctx_params_fn xor_sig_get_ctx_params; | |
2581 | static OSSL_FUNC_signature_gettable_ctx_params_fn xor_sig_gettable_ctx_params; | |
2582 | static OSSL_FUNC_signature_set_ctx_params_fn xor_sig_set_ctx_params; | |
2583 | static OSSL_FUNC_signature_settable_ctx_params_fn xor_sig_settable_ctx_params; | |
2584 | static OSSL_FUNC_signature_get_ctx_md_params_fn xor_sig_get_ctx_md_params; | |
2585 | static OSSL_FUNC_signature_gettable_ctx_md_params_fn xor_sig_gettable_ctx_md_params; | |
2586 | static OSSL_FUNC_signature_set_ctx_md_params_fn xor_sig_set_ctx_md_params; | |
2587 | static OSSL_FUNC_signature_settable_ctx_md_params_fn xor_sig_settable_ctx_md_params; | |
2588 | ||
2589 | static int xor_get_aid(unsigned char** oidbuf, const char *tls_name) { | |
2590 | X509_ALGOR *algor = X509_ALGOR_new(); | |
2591 | int aidlen = 0; | |
2592 | ||
2593 | X509_ALGOR_set0(algor, OBJ_txt2obj(tls_name, 0), V_ASN1_UNDEF, NULL); | |
2594 | ||
2595 | aidlen = i2d_X509_ALGOR(algor, oidbuf); | |
2596 | X509_ALGOR_free(algor); | |
2597 | return(aidlen); | |
2598 | } | |
2599 | ||
2600 | /* | |
2601 | * What's passed as an actual key is defined by the KEYMGMT interface. | |
2602 | */ | |
2603 | typedef struct { | |
2604 | OSSL_LIB_CTX *libctx; | |
2605 | char *propq; | |
2606 | XORKEY *sig; | |
2607 | ||
2608 | /* | |
2609 | * Flag to determine if the hash function can be changed (1) or not (0) | |
2610 | * Because it's dangerous to change during a DigestSign or DigestVerify | |
2611 | * operation, this flag is cleared by their Init function, and set again | |
2612 | * by their Final function. | |
2613 | */ | |
2614 | unsigned int flag_allow_md : 1; | |
2615 | ||
2616 | char mdname[OSSL_MAX_NAME_SIZE]; | |
2617 | ||
2618 | /* The Algorithm Identifier of the combined signature algorithm */ | |
2619 | unsigned char *aid; | |
2620 | size_t aid_len; | |
2621 | ||
2622 | /* main digest */ | |
2623 | EVP_MD *md; | |
2624 | EVP_MD_CTX *mdctx; | |
2625 | int operation; | |
2626 | } PROV_XORSIG_CTX; | |
2627 | ||
2628 | static void *xor_sig_newctx(void *provctx, const char *propq) | |
2629 | { | |
2630 | PROV_XORSIG_CTX *pxor_sigctx; | |
2631 | ||
2632 | pxor_sigctx = OPENSSL_zalloc(sizeof(PROV_XORSIG_CTX)); | |
2633 | if (pxor_sigctx == NULL) | |
2634 | return NULL; | |
2635 | ||
2636 | pxor_sigctx->libctx = ((PROV_XOR_CTX*)provctx)->libctx; | |
2637 | pxor_sigctx->flag_allow_md = 0; | |
2638 | if (propq != NULL && (pxor_sigctx->propq = OPENSSL_strdup(propq)) == NULL) { | |
2639 | OPENSSL_free(pxor_sigctx); | |
2640 | pxor_sigctx = NULL; | |
2641 | ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); | |
2642 | } | |
2643 | return pxor_sigctx; | |
2644 | } | |
2645 | ||
2646 | static int xor_sig_setup_md(PROV_XORSIG_CTX *ctx, | |
2647 | const char *mdname, const char *mdprops) | |
2648 | { | |
2649 | EVP_MD *md; | |
2650 | ||
2651 | if (mdprops == NULL) | |
2652 | mdprops = ctx->propq; | |
2653 | ||
2654 | md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); | |
2655 | ||
2656 | if ((md == NULL) || (EVP_MD_nid(md)==NID_undef)) { | |
2657 | if (md == NULL) | |
2658 | ERR_raise_data(ERR_LIB_USER, XORPROV_R_INVALID_DIGEST, | |
2659 | "%s could not be fetched", mdname); | |
2660 | EVP_MD_free(md); | |
2661 | return 0; | |
2662 | } | |
2663 | ||
2664 | EVP_MD_CTX_free(ctx->mdctx); | |
2665 | ctx->mdctx = NULL; | |
2666 | EVP_MD_free(ctx->md); | |
2667 | ctx->md = NULL; | |
2668 | ||
2669 | OPENSSL_free(ctx->aid); | |
2670 | ctx->aid = NULL; | |
2671 | ctx->aid_len = xor_get_aid(&(ctx->aid), ctx->sig->tls_name); | |
2672 | ||
2673 | ctx->mdctx = NULL; | |
2674 | ctx->md = md; | |
2675 | OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); | |
2676 | return 1; | |
2677 | } | |
2678 | ||
2679 | static int xor_sig_signverify_init(void *vpxor_sigctx, void *vxorsig, | |
2680 | int operation) | |
2681 | { | |
2682 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2683 | ||
2684 | if (pxor_sigctx == NULL || vxorsig == NULL) | |
2685 | return 0; | |
2686 | xor_freekey(pxor_sigctx->sig); | |
2687 | if (!xor_key_up_ref(vxorsig)) | |
2688 | return 0; | |
2689 | pxor_sigctx->sig = vxorsig; | |
2690 | pxor_sigctx->operation = operation; | |
2691 | if ((operation==EVP_PKEY_OP_SIGN && pxor_sigctx->sig == NULL) | |
2692 | || (operation==EVP_PKEY_OP_VERIFY && pxor_sigctx->sig == NULL)) { | |
2693 | ERR_raise(ERR_LIB_USER, XORPROV_R_INVALID_KEY); | |
2694 | return 0; | |
2695 | } | |
2696 | return 1; | |
2697 | } | |
2698 | ||
2699 | static int xor_sig_sign_init(void *vpxor_sigctx, void *vxorsig, | |
2700 | const OSSL_PARAM params[]) | |
2701 | { | |
2702 | return xor_sig_signverify_init(vpxor_sigctx, vxorsig, EVP_PKEY_OP_SIGN); | |
2703 | } | |
2704 | ||
2705 | static int xor_sig_verify_init(void *vpxor_sigctx, void *vxorsig, | |
2706 | const OSSL_PARAM params[]) | |
2707 | { | |
2708 | return xor_sig_signverify_init(vpxor_sigctx, vxorsig, EVP_PKEY_OP_VERIFY); | |
2709 | } | |
2710 | ||
2711 | static int xor_sig_sign(void *vpxor_sigctx, unsigned char *sig, size_t *siglen, | |
2712 | size_t sigsize, const unsigned char *tbs, size_t tbslen) | |
2713 | { | |
2714 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2715 | XORKEY *xorkey = pxor_sigctx->sig; | |
2716 | ||
2717 | size_t max_sig_len = EVP_MAX_MD_SIZE; | |
2718 | size_t xor_sig_len = 0; | |
2719 | int rv = 0; | |
2720 | ||
2721 | if (xorkey == NULL || !xorkey->hasprivkey) { | |
2722 | ERR_raise(ERR_LIB_USER, XORPROV_R_NO_PRIVATE_KEY); | |
2723 | return rv; | |
2724 | } | |
2725 | ||
2726 | if (sig == NULL) { | |
2727 | *siglen = max_sig_len; | |
2728 | return 1; | |
2729 | } | |
2730 | if (*siglen < max_sig_len) { | |
2731 | ERR_raise(ERR_LIB_USER, XORPROV_R_BUFFER_LENGTH_WRONG); | |
2732 | return rv; | |
2733 | } | |
2734 | ||
2735 | /* | |
2736 | * create HMAC using XORKEY as key and hash as data: | |
2737 | * No real crypto, just for test, don't do this at home! | |
2738 | */ | |
2739 | if (!EVP_Q_mac(pxor_sigctx->libctx, "HMAC", NULL, "sha1", NULL, | |
2740 | xorkey->privkey, XOR_KEY_SIZE, tbs, tbslen, | |
2741 | &sig[0], EVP_MAX_MD_SIZE, &xor_sig_len)) { | |
2742 | ERR_raise(ERR_LIB_USER, XORPROV_R_SIGNING_FAILED); | |
2743 | goto endsign; | |
2744 | } | |
2745 | ||
2746 | *siglen = xor_sig_len; | |
2747 | rv = 1; /* success */ | |
2748 | ||
2749 | endsign: | |
2750 | return rv; | |
2751 | } | |
2752 | ||
2753 | static int xor_sig_verify(void *vpxor_sigctx, | |
2754 | const unsigned char *sig, size_t siglen, | |
2755 | const unsigned char *tbs, size_t tbslen) | |
2756 | { | |
2757 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2758 | XORKEY *xorkey = pxor_sigctx->sig; | |
2759 | unsigned char resignature[EVP_MAX_MD_SIZE]; | |
2760 | size_t resiglen; | |
2761 | int i; | |
2762 | ||
2763 | if (xorkey == NULL || sig == NULL || tbs == NULL) { | |
2764 | ERR_raise(ERR_LIB_USER, XORPROV_R_WRONG_PARAMETERS); | |
2765 | return 0; | |
2766 | } | |
2767 | ||
2768 | /* | |
2769 | * This is no real verify: just re-sign and compare: | |
2770 | * Don't do this at home! Not fit for real use! | |
2771 | */ | |
2772 | /* First re-create private key from public key: */ | |
2773 | for (i = 0; i < XOR_KEY_SIZE; i++) | |
2774 | xorkey->privkey[i] = xorkey->pubkey[i] ^ private_constant[i]; | |
2775 | ||
2776 | /* Now re-create signature */ | |
2777 | if (!EVP_Q_mac(pxor_sigctx->libctx, "HMAC", NULL, "sha1", NULL, | |
2778 | xorkey->privkey, XOR_KEY_SIZE, tbs, tbslen, | |
2779 | &resignature[0], EVP_MAX_MD_SIZE, &resiglen)) { | |
2780 | ERR_raise(ERR_LIB_USER, XORPROV_R_VERIFY_ERROR); | |
2781 | return 0; | |
2782 | } | |
2783 | ||
2784 | /* Now compare with signature passed */ | |
2785 | if (siglen != resiglen || memcmp(resignature, sig, siglen) != 0) { | |
2786 | ERR_raise(ERR_LIB_USER, XORPROV_R_VERIFY_ERROR); | |
2787 | return 0; | |
2788 | } | |
2789 | return 1; | |
2790 | } | |
2791 | ||
2792 | static int xor_sig_digest_signverify_init(void *vpxor_sigctx, const char *mdname, | |
2793 | void *vxorsig, int operation) | |
2794 | { | |
2795 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2796 | char *rmdname = (char *)mdname; | |
2797 | ||
2798 | if (rmdname == NULL) | |
2799 | rmdname = "sha256"; | |
2800 | ||
2801 | pxor_sigctx->flag_allow_md = 0; | |
2802 | if (!xor_sig_signverify_init(vpxor_sigctx, vxorsig, operation)) | |
2803 | return 0; | |
2804 | ||
2805 | if (!xor_sig_setup_md(pxor_sigctx, rmdname, NULL)) | |
2806 | return 0; | |
2807 | ||
2808 | pxor_sigctx->mdctx = EVP_MD_CTX_new(); | |
2809 | if (pxor_sigctx->mdctx == NULL) | |
2810 | goto error; | |
2811 | ||
2812 | if (!EVP_DigestInit_ex(pxor_sigctx->mdctx, pxor_sigctx->md, NULL)) | |
2813 | goto error; | |
2814 | ||
2815 | return 1; | |
2816 | ||
2817 | error: | |
2818 | EVP_MD_CTX_free(pxor_sigctx->mdctx); | |
2819 | EVP_MD_free(pxor_sigctx->md); | |
2820 | pxor_sigctx->mdctx = NULL; | |
2821 | pxor_sigctx->md = NULL; | |
2822 | return 0; | |
2823 | } | |
2824 | ||
2825 | static int xor_sig_digest_sign_init(void *vpxor_sigctx, const char *mdname, | |
2826 | void *vxorsig, const OSSL_PARAM params[]) | |
2827 | { | |
2828 | return xor_sig_digest_signverify_init(vpxor_sigctx, mdname, vxorsig, | |
2829 | EVP_PKEY_OP_SIGN); | |
2830 | } | |
2831 | ||
2832 | static int xor_sig_digest_verify_init(void *vpxor_sigctx, const char *mdname, void *vxorsig, const OSSL_PARAM params[]) | |
2833 | { | |
2834 | return xor_sig_digest_signverify_init(vpxor_sigctx, mdname, | |
2835 | vxorsig, EVP_PKEY_OP_VERIFY); | |
2836 | } | |
2837 | ||
2838 | int xor_sig_digest_signverify_update(void *vpxor_sigctx, | |
2839 | const unsigned char *data, | |
2840 | size_t datalen) | |
2841 | { | |
2842 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2843 | ||
2844 | if (pxor_sigctx == NULL || pxor_sigctx->mdctx == NULL) | |
2845 | return 0; | |
2846 | ||
2847 | return EVP_DigestUpdate(pxor_sigctx->mdctx, data, datalen); | |
2848 | } | |
2849 | ||
2850 | int xor_sig_digest_sign_final(void *vpxor_sigctx, | |
2851 | unsigned char *sig, size_t *siglen, | |
2852 | size_t sigsize) | |
2853 | { | |
2854 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2855 | unsigned char digest[EVP_MAX_MD_SIZE]; | |
2856 | unsigned int dlen = 0; | |
2857 | ||
2858 | if (sig != NULL) { | |
2859 | if (pxor_sigctx == NULL || pxor_sigctx->mdctx == NULL) | |
2860 | return 0; | |
2861 | ||
2862 | if (!EVP_DigestFinal_ex(pxor_sigctx->mdctx, digest, &dlen)) | |
2863 | return 0; | |
2864 | ||
2865 | pxor_sigctx->flag_allow_md = 1; | |
2866 | } | |
2867 | ||
2868 | return xor_sig_sign(vpxor_sigctx, sig, siglen, sigsize, digest, (size_t)dlen); | |
2869 | ||
2870 | } | |
2871 | ||
2872 | int xor_sig_digest_verify_final(void *vpxor_sigctx, const unsigned char *sig, | |
2873 | size_t siglen) | |
2874 | { | |
2875 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2876 | unsigned char digest[EVP_MAX_MD_SIZE]; | |
2877 | unsigned int dlen = 0; | |
2878 | ||
2879 | if (pxor_sigctx == NULL || pxor_sigctx->mdctx == NULL) | |
2880 | return 0; | |
2881 | ||
2882 | if (!EVP_DigestFinal_ex(pxor_sigctx->mdctx, digest, &dlen)) | |
2883 | return 0; | |
2884 | ||
2885 | pxor_sigctx->flag_allow_md = 1; | |
2886 | ||
2887 | return xor_sig_verify(vpxor_sigctx, sig, siglen, digest, (size_t)dlen); | |
2888 | } | |
2889 | ||
2890 | static void xor_sig_freectx(void *vpxor_sigctx) | |
2891 | { | |
2892 | PROV_XORSIG_CTX *ctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2893 | ||
2894 | OPENSSL_free(ctx->propq); | |
2895 | EVP_MD_CTX_free(ctx->mdctx); | |
2896 | EVP_MD_free(ctx->md); | |
2897 | ctx->propq = NULL; | |
2898 | ctx->mdctx = NULL; | |
2899 | ctx->md = NULL; | |
2900 | xor_freekey(ctx->sig); | |
2901 | ctx->sig = NULL; | |
2902 | OPENSSL_free(ctx->aid); | |
2903 | OPENSSL_free(ctx); | |
2904 | } | |
2905 | ||
2906 | static void *xor_sig_dupctx(void *vpxor_sigctx) | |
2907 | { | |
2908 | PROV_XORSIG_CTX *srcctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2909 | PROV_XORSIG_CTX *dstctx; | |
2910 | ||
2911 | dstctx = OPENSSL_zalloc(sizeof(*srcctx)); | |
2912 | if (dstctx == NULL) | |
2913 | return NULL; | |
2914 | ||
2915 | *dstctx = *srcctx; | |
2916 | dstctx->sig = NULL; | |
2917 | dstctx->md = NULL; | |
2918 | dstctx->mdctx = NULL; | |
2919 | dstctx->aid = NULL; | |
2920 | ||
2921 | if ((srcctx->sig != NULL) && !xor_key_up_ref(srcctx->sig)) | |
2922 | goto err; | |
2923 | dstctx->sig = srcctx->sig; | |
2924 | ||
2925 | if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) | |
2926 | goto err; | |
2927 | dstctx->md = srcctx->md; | |
2928 | ||
2929 | if (srcctx->mdctx != NULL) { | |
2930 | dstctx->mdctx = EVP_MD_CTX_new(); | |
2931 | if (dstctx->mdctx == NULL | |
2932 | || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) | |
2933 | goto err; | |
2934 | } | |
2935 | ||
2936 | return dstctx; | |
2937 | err: | |
2938 | xor_sig_freectx(dstctx); | |
2939 | return NULL; | |
2940 | } | |
2941 | ||
2942 | static int xor_sig_get_ctx_params(void *vpxor_sigctx, OSSL_PARAM *params) | |
2943 | { | |
2944 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2945 | OSSL_PARAM *p; | |
2946 | ||
2947 | if (pxor_sigctx == NULL || params == NULL) | |
2948 | return 0; | |
2949 | ||
2950 | p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); | |
2951 | ||
2952 | if (pxor_sigctx->aid == NULL) | |
2953 | pxor_sigctx->aid_len = xor_get_aid(&(pxor_sigctx->aid), pxor_sigctx->sig->tls_name); | |
2954 | ||
2955 | if (p != NULL | |
2956 | && !OSSL_PARAM_set_octet_string(p, pxor_sigctx->aid, pxor_sigctx->aid_len)) | |
2957 | return 0; | |
2958 | ||
2959 | p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); | |
2960 | if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pxor_sigctx->mdname)) | |
2961 | return 0; | |
2962 | ||
2963 | return 1; | |
2964 | } | |
2965 | ||
2966 | static const OSSL_PARAM known_gettable_ctx_params[] = { | |
2967 | OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), | |
2968 | OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), | |
2969 | OSSL_PARAM_END | |
2970 | }; | |
2971 | ||
2972 | static const OSSL_PARAM *xor_sig_gettable_ctx_params(ossl_unused void *vpxor_sigctx, ossl_unused void *vctx) | |
2973 | { | |
2974 | return known_gettable_ctx_params; | |
2975 | } | |
2976 | ||
2977 | static int xor_sig_set_ctx_params(void *vpxor_sigctx, const OSSL_PARAM params[]) | |
2978 | { | |
2979 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
2980 | const OSSL_PARAM *p; | |
2981 | ||
2982 | if (pxor_sigctx == NULL || params == NULL) | |
2983 | return 0; | |
2984 | ||
2985 | p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); | |
2986 | /* Not allowed during certain operations */ | |
2987 | if (p != NULL && !pxor_sigctx->flag_allow_md) | |
2988 | return 0; | |
2989 | if (p != NULL) { | |
2990 | char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; | |
2991 | char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; | |
2992 | const OSSL_PARAM *propsp = | |
2993 | OSSL_PARAM_locate_const(params, | |
2994 | OSSL_SIGNATURE_PARAM_PROPERTIES); | |
2995 | ||
2996 | if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) | |
2997 | return 0; | |
2998 | if (propsp != NULL | |
2999 | && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) | |
3000 | return 0; | |
3001 | if (!xor_sig_setup_md(pxor_sigctx, mdname, mdprops)) | |
3002 | return 0; | |
3003 | } | |
3004 | ||
3005 | return 1; | |
3006 | } | |
3007 | ||
3008 | static const OSSL_PARAM known_settable_ctx_params[] = { | |
3009 | OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), | |
3010 | OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), | |
3011 | OSSL_PARAM_END | |
3012 | }; | |
3013 | ||
3014 | static const OSSL_PARAM *xor_sig_settable_ctx_params(ossl_unused void *vpsm2ctx, | |
3015 | ossl_unused void *provctx) | |
3016 | { | |
3017 | return known_settable_ctx_params; | |
3018 | } | |
3019 | ||
3020 | static int xor_sig_get_ctx_md_params(void *vpxor_sigctx, OSSL_PARAM *params) | |
3021 | { | |
3022 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
3023 | ||
3024 | if (pxor_sigctx->mdctx == NULL) | |
3025 | return 0; | |
3026 | ||
3027 | return EVP_MD_CTX_get_params(pxor_sigctx->mdctx, params); | |
3028 | } | |
3029 | ||
3030 | static const OSSL_PARAM *xor_sig_gettable_ctx_md_params(void *vpxor_sigctx) | |
3031 | { | |
3032 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
3033 | ||
3034 | if (pxor_sigctx->md == NULL) | |
3035 | return 0; | |
3036 | ||
3037 | return EVP_MD_gettable_ctx_params(pxor_sigctx->md); | |
3038 | } | |
3039 | ||
3040 | static int xor_sig_set_ctx_md_params(void *vpxor_sigctx, const OSSL_PARAM params[]) | |
3041 | { | |
3042 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
3043 | ||
3044 | if (pxor_sigctx->mdctx == NULL) | |
3045 | return 0; | |
3046 | ||
3047 | return EVP_MD_CTX_set_params(pxor_sigctx->mdctx, params); | |
3048 | } | |
3049 | ||
3050 | static const OSSL_PARAM *xor_sig_settable_ctx_md_params(void *vpxor_sigctx) | |
3051 | { | |
3052 | PROV_XORSIG_CTX *pxor_sigctx = (PROV_XORSIG_CTX *)vpxor_sigctx; | |
3053 | ||
3054 | if (pxor_sigctx->md == NULL) | |
3055 | return 0; | |
3056 | ||
3057 | return EVP_MD_settable_ctx_params(pxor_sigctx->md); | |
3058 | } | |
3059 | ||
3060 | static const OSSL_DISPATCH xor_signature_functions[] = { | |
3061 | { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))xor_sig_newctx }, | |
3062 | { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))xor_sig_sign_init }, | |
3063 | { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))xor_sig_sign }, | |
3064 | { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))xor_sig_verify_init }, | |
3065 | { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))xor_sig_verify }, | |
3066 | { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, | |
3067 | (void (*)(void))xor_sig_digest_sign_init }, | |
3068 | { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, | |
3069 | (void (*)(void))xor_sig_digest_signverify_update }, | |
3070 | { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, | |
3071 | (void (*)(void))xor_sig_digest_sign_final }, | |
3072 | { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, | |
3073 | (void (*)(void))xor_sig_digest_verify_init }, | |
3074 | { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, | |
3075 | (void (*)(void))xor_sig_digest_signverify_update }, | |
3076 | { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, | |
3077 | (void (*)(void))xor_sig_digest_verify_final }, | |
3078 | { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))xor_sig_freectx }, | |
3079 | { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))xor_sig_dupctx }, | |
3080 | { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))xor_sig_get_ctx_params }, | |
3081 | { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, | |
3082 | (void (*)(void))xor_sig_gettable_ctx_params }, | |
3083 | { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))xor_sig_set_ctx_params }, | |
3084 | { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, | |
3085 | (void (*)(void))xor_sig_settable_ctx_params }, | |
3086 | { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, | |
3087 | (void (*)(void))xor_sig_get_ctx_md_params }, | |
3088 | { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, | |
3089 | (void (*)(void))xor_sig_gettable_ctx_md_params }, | |
3090 | { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, | |
3091 | (void (*)(void))xor_sig_set_ctx_md_params }, | |
3092 | { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, | |
3093 | (void (*)(void))xor_sig_settable_ctx_md_params }, | |
3094 | { 0, NULL } | |
3095 | }; | |
3096 | ||
3097 | static const OSSL_ALGORITHM tls_prov_signature[] = { | |
3098 | /* | |
3099 | * Obviously this is not FIPS approved, but in order to test in conjunction | |
3100 | * with the FIPS provider we pretend that it is. | |
3101 | */ | |
3102 | { XORSIGALG_NAME, "provider=tls-provider,fips=yes", | |
3103 | xor_signature_functions }, | |
3104 | { XORSIGALG_HASH_NAME, "provider=tls-provider,fips=yes", | |
3105 | xor_signature_functions }, | |
3106 | { XORSIGALG12_NAME, "provider=tls-provider,fips=yes", | |
3107 | xor_signature_functions }, | |
3108 | { NULL, NULL, NULL } | |
3109 | }; | |
3110 | ||
3111 | ||
3112 | static const OSSL_ALGORITHM *tls_prov_query(void *provctx, int operation_id, | |
3113 | int *no_cache) | |
3114 | { | |
3115 | *no_cache = 0; | |
3116 | switch (operation_id) { | |
3117 | case OSSL_OP_KEYMGMT: | |
3118 | return tls_prov_keymgmt; | |
3119 | case OSSL_OP_KEYEXCH: | |
3120 | return tls_prov_keyexch; | |
3121 | case OSSL_OP_KEM: | |
3122 | return tls_prov_kem; | |
3123 | case OSSL_OP_ENCODER: | |
3124 | return tls_prov_encoder; | |
3125 | case OSSL_OP_DECODER: | |
3126 | return tls_prov_decoder; | |
3127 | case OSSL_OP_SIGNATURE: | |
3128 | return tls_prov_signature; | |
3129 | } | |
3130 | return NULL; | |
3131 | } | |
3132 | ||
3133 | static void tls_prov_teardown(void *provctx) | |
3134 | { | |
3135 | int i; | |
3136 | PROV_XOR_CTX *pctx = (PROV_XOR_CTX*)provctx; | |
3137 | ||
3138 | OSSL_LIB_CTX_free(pctx->libctx); | |
3139 | ||
3140 | for (i = 0; i < NUM_DUMMY_GROUPS; i++) { | |
3141 | OPENSSL_free(dummy_group_names[i]); | |
3142 | dummy_group_names[i] = NULL; | |
3143 | } | |
3144 | OPENSSL_free(pctx); | |
3145 | } | |
3146 | ||
3147 | /* Functions we provide to the core */ | |
3148 | static const OSSL_DISPATCH tls_prov_dispatch_table[] = { | |
3149 | { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))tls_prov_teardown }, | |
3150 | { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))tls_prov_query }, | |
3151 | { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))tls_prov_get_capabilities }, | |
3152 | { 0, NULL } | |
3153 | }; | |
3154 | ||
3155 | static | |
3156 | unsigned int randomize_tls_alg_id(OSSL_LIB_CTX *libctx) | |
3157 | { | |
3158 | /* | |
3159 | * Randomise the id we're going to use to ensure we don't interoperate | |
3160 | * with anything but ourselves. | |
3161 | */ | |
3162 | unsigned int id; | |
3163 | static unsigned int mem[10] = { 0 }; | |
3164 | static int in_mem = 0; | |
3165 | int i; | |
3166 | ||
3167 | retry: | |
3168 | if (RAND_bytes_ex(libctx, (unsigned char *)&id, sizeof(id), 0) <= 0) | |
3169 | return 0; | |
3170 | /* | |
3171 | * Ensure id is within the IANA Reserved for private use range | |
3172 | * (65024-65279) | |
3173 | */ | |
3174 | id %= 65279 - 65024; | |
3175 | id += 65024; | |
3176 | ||
3177 | /* Ensure we did not already issue this id */ | |
3178 | for (i = 0; i < in_mem; i++) | |
3179 | if (mem[i] == id) | |
3180 | goto retry; | |
3181 | ||
3182 | /* Add this id to the list of ids issued by this function */ | |
3183 | mem[in_mem++] = id; | |
3184 | ||
3185 | return id; | |
3186 | } | |
3187 | ||
3188 | int tls_provider_init(const OSSL_CORE_HANDLE *handle, | |
3189 | const OSSL_DISPATCH *in, | |
3190 | const OSSL_DISPATCH **out, | |
3191 | void **provctx) | |
3192 | { | |
3193 | OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_from_dispatch(handle, in); | |
3194 | OSSL_FUNC_core_obj_create_fn *c_obj_create= NULL; | |
3195 | OSSL_FUNC_core_obj_add_sigid_fn *c_obj_add_sigid= NULL; | |
3196 | PROV_XOR_CTX *prov_ctx = xor_newprovctx(libctx); | |
3197 | ||
3198 | if (libctx == NULL || prov_ctx == NULL) | |
3199 | return 0; | |
3200 | ||
3201 | *provctx = prov_ctx; | |
3202 | ||
3203 | /* | |
3204 | * Randomise the group_id and code_points we're going to use to ensure we | |
3205 | * don't interoperate with anything but ourselves. | |
3206 | */ | |
3207 | xor_group.group_id = randomize_tls_alg_id(libctx); | |
3208 | xor_kemgroup.group_id = randomize_tls_alg_id(libctx); | |
3209 | xor_sigalg.code_point = randomize_tls_alg_id(libctx); | |
3210 | xor_sigalg_hash.code_point = randomize_tls_alg_id(libctx); | |
3211 | ||
3212 | /* Retrieve registration functions */ | |
3213 | for (; in->function_id != 0; in++) { | |
3214 | switch (in->function_id) { | |
3215 | case OSSL_FUNC_CORE_OBJ_CREATE: | |
3216 | c_obj_create = OSSL_FUNC_core_obj_create(in); | |
3217 | break; | |
3218 | case OSSL_FUNC_CORE_OBJ_ADD_SIGID: | |
3219 | c_obj_add_sigid = OSSL_FUNC_core_obj_add_sigid(in); | |
3220 | break; | |
3221 | /* Just ignore anything we don't understand */ | |
3222 | default: | |
3223 | break; | |
3224 | } | |
3225 | } | |
3226 | ||
3227 | /* | |
3228 | * Register algorithms manually as add_provider_sigalgs is | |
3229 | * only called during session establishment -- too late for | |
3230 | * key & cert generation... | |
3231 | */ | |
3232 | if (!c_obj_create(handle, XORSIGALG_OID, XORSIGALG_NAME, XORSIGALG_NAME)) { | |
3233 | ERR_raise(ERR_LIB_USER, XORPROV_R_OBJ_CREATE_ERR); | |
3234 | return 0; | |
3235 | } | |
3236 | ||
3237 | if (!c_obj_add_sigid(handle, XORSIGALG_OID, "", XORSIGALG_OID)) { | |
3238 | ERR_raise(ERR_LIB_USER, XORPROV_R_OBJ_CREATE_ERR); | |
3239 | return 0; | |
3240 | } | |
3241 | if (!c_obj_create(handle, XORSIGALG_HASH_OID, XORSIGALG_HASH_NAME, NULL)) { | |
3242 | ERR_raise(ERR_LIB_USER, XORPROV_R_OBJ_CREATE_ERR); | |
3243 | return 0; | |
3244 | } | |
3245 | ||
3246 | if (!c_obj_add_sigid(handle, XORSIGALG_HASH_OID, XORSIGALG_HASH, XORSIGALG_HASH_OID)) { | |
3247 | ERR_raise(ERR_LIB_USER, XORPROV_R_OBJ_CREATE_ERR); | |
3248 | return 0; | |
3249 | } | |
32fea070 | 3250 | |
0c13cdf8 MC |
3251 | *out = tls_prov_dispatch_table; |
3252 | return 1; | |
3253 | } |