OpenVPN
xkey_provider.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2021-2023 Selva Nair <selva.nair@gmail.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation, either version 2 of the License,
13  * or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #include "syshead.h"
30 #include "error.h"
31 #include "buffer.h"
32 #include "xkey_common.h"
33 
34 #ifdef HAVE_XKEY_PROVIDER
35 
36 #include <openssl/provider.h>
37 #include <openssl/params.h>
38 #include <openssl/core_dispatch.h>
39 #include <openssl/core_object.h>
40 #include <openssl/core_names.h>
41 #include <openssl/store.h>
42 #include <openssl/evp.h>
43 #include <openssl/err.h>
44 
45 /* A descriptive name */
46 static const char *provname = "OpenVPN External Key Provider";
47 
48 typedef struct
49 {
50  OSSL_LIB_CTX *libctx;
51 } XKEY_PROVIDER_CTX;
52 
53 /* helper to print debug messages */
54 #define xkey_dmsg(f, ...) \
55  do { \
56  dmsg(f|M_NOLF, "xkey_provider: In %s: ", __func__); \
57  dmsg(f|M_NOPREFIX, __VA_ARGS__); \
58  } while(0)
59 
60 typedef enum
61 {
62  ORIGIN_UNDEFINED = 0,
63  OPENSSL_NATIVE, /* native key imported in */
64  EXTERNAL_KEY
65 } XKEY_ORIGIN;
66 
84 typedef struct
85 {
87  void *handle;
89  EVP_PKEY *pubkey;
91  XKEY_ORIGIN origin;
93  XKEY_EXTERNAL_SIGN_fn *sign;
95  XKEY_PRIVKEY_FREE_fn *free;
96  XKEY_PROVIDER_CTX *prov;
97  int refcount;
98 } XKEY_KEYDATA;
99 
100 static inline const char *
101 get_keytype(const XKEY_KEYDATA *key)
102 {
103  int keytype = key->pubkey ? EVP_PKEY_get_id(key->pubkey) : 0;
104 
105  switch (keytype)
106  {
107  case EVP_PKEY_RSA:
108  return "RSA";
109 
110  case EVP_PKEY_ED448:
111  return "ED448";
112 
113  case EVP_PKEY_ED25519:
114  return "ED25519";
115 
116  default:
117  return "EC";
118  }
119 }
120 
121 
122 static int
123 KEYSIZE(const XKEY_KEYDATA *key)
124 {
125  return key->pubkey ? EVP_PKEY_get_size(key->pubkey) : 0;
126 }
127 
132 int
133 xkey_native_sign(XKEY_KEYDATA *key, unsigned char *sig, size_t *siglen,
134  const unsigned char *tbs, size_t tbslen, XKEY_SIGALG sigalg);
135 
136 
137 /* keymgmt provider */
138 
139 /* keymgmt callbacks we implement */
140 static OSSL_FUNC_keymgmt_new_fn keymgmt_new;
141 static OSSL_FUNC_keymgmt_free_fn keymgmt_free;
142 static OSSL_FUNC_keymgmt_load_fn keymgmt_load;
143 static OSSL_FUNC_keymgmt_has_fn keymgmt_has;
144 static OSSL_FUNC_keymgmt_match_fn keymgmt_match;
145 static OSSL_FUNC_keymgmt_import_fn rsa_keymgmt_import;
146 static OSSL_FUNC_keymgmt_import_fn ec_keymgmt_import;
147 static OSSL_FUNC_keymgmt_import_types_fn keymgmt_import_types;
148 static OSSL_FUNC_keymgmt_get_params_fn keymgmt_get_params;
149 static OSSL_FUNC_keymgmt_gettable_params_fn keymgmt_gettable_params;
150 static OSSL_FUNC_keymgmt_set_params_fn keymgmt_set_params;
151 static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_keymgmt_name;
152 static OSSL_FUNC_keymgmt_query_operation_name_fn ec_keymgmt_name;
153 
154 static int
155 keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM params[]);
156 
157 static XKEY_KEYDATA *
158 keydata_new()
159 {
160  xkey_dmsg(D_XKEY, "entry");
161 
162  XKEY_KEYDATA *key = OPENSSL_zalloc(sizeof(*key));
163  if (!key)
164  {
165  msg(M_NONFATAL, "xkey_keydata_new: out of memory");
166  }
167 
168  return key;
169 }
170 
171 static void
172 keydata_free(XKEY_KEYDATA *key)
173 {
174  xkey_dmsg(D_XKEY, "entry");
175 
176  if (!key || key->refcount-- > 0) /* free when refcount goes to zero */
177  {
178  return;
179  }
180  if (key->free && key->handle)
181  {
182  key->free(key->handle);
183  key->handle = NULL;
184  }
185  if (key->pubkey)
186  {
187  EVP_PKEY_free(key->pubkey);
188  }
189  OPENSSL_free(key);
190 }
191 
192 static void *
193 keymgmt_new(void *provctx)
194 {
195  xkey_dmsg(D_XKEY, "entry");
196 
197  XKEY_KEYDATA *key = keydata_new();
198  if (key)
199  {
200  key->prov = provctx;
201  }
202 
203  return key;
204 }
205 
206 static void *
207 keymgmt_load(const void *reference, size_t reference_sz)
208 {
209  xkey_dmsg(D_XKEY, "entry");
210 
211  return NULL;
212 }
213 
246 static int
247 keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[], const char *name)
248 {
249  xkey_dmsg(D_XKEY, "entry");
250 
251  XKEY_KEYDATA *key = keydata;
252  ASSERT(key);
253 
254  /* Our private key is immutable -- we import only if keydata is empty */
255  if (key->handle || key->pubkey)
256  {
257  msg(M_WARN, "Error: keymgmt_import: keydata not empty -- our keys are immutable");
258  return 0;
259  }
260 
261  /* if params contain a custom origin, call our helper to import custom keys */
262  const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, "xkey-origin");
263  if (p && p->data_type == OSSL_PARAM_UTF8_STRING)
264  {
265  key->origin = EXTERNAL_KEY;
266  xkey_dmsg(D_XKEY, "importing external key");
267  return keymgmt_import_helper(key, params);
268  }
269 
270  xkey_dmsg(D_XKEY, "importing native key");
271 
272  /* create a native public key and assign it to key->pubkey */
273  EVP_PKEY *pkey = NULL;
274  int selection_pub = selection & ~OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
275 
276  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(key->prov->libctx, name, NULL);
277  if (!ctx
278  || (EVP_PKEY_fromdata_init(ctx) != 1)
279  || (EVP_PKEY_fromdata(ctx, &pkey, selection_pub, (OSSL_PARAM *) params) !=1))
280  {
281  msg(M_WARN, "Error: keymgmt_import failed for key type <%s>", name);
282  if (pkey)
283  {
284  EVP_PKEY_free(pkey);
285  }
286  if (ctx)
287  {
288  EVP_PKEY_CTX_free(ctx);
289  }
290  return 0;
291  }
292 
293  key->pubkey = pkey;
294  key->origin = OPENSSL_NATIVE;
295  if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
296  {
297  /* create private key */
298  pkey = NULL;
299  if (EVP_PKEY_fromdata(ctx, &pkey, selection, (OSSL_PARAM *) params) == 1)
300  {
301  key->handle = pkey;
302  key->free = (XKEY_PRIVKEY_FREE_fn *) EVP_PKEY_free;
303  }
304  }
305  EVP_PKEY_CTX_free(ctx);
306 
307  xkey_dmsg(D_XKEY, "imported native %s key", EVP_PKEY_get0_type_name(pkey));
308  return 1;
309 }
310 
311 static int
312 rsa_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[])
313 {
314  xkey_dmsg(D_XKEY, "entry");
315 
316  return keymgmt_import(keydata, selection, params, "RSA");
317 }
318 
319 static int
320 ec_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[])
321 {
322  xkey_dmsg(D_XKEY, "entry");
323 
324  return keymgmt_import(keydata, selection, params, "EC");
325 }
326 
327 static int
328 ed448_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[])
329 {
330  xkey_dmsg(D_XKEY, "entry");
331 
332  return keymgmt_import(keydata, selection, params, "ED448");
333 }
334 
335 static int
336 ed25519_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[])
337 {
338  xkey_dmsg(D_XKEY, "entry");
339 
340  return keymgmt_import(keydata, selection, params, "ED25519");
341 }
342 
343 /* This function has to exist for key import to work
344  * though we do not support import of individual params
345  * like n or e. We simply return an empty list here for
346  * both rsa and ec, which works.
347  */
348 static const OSSL_PARAM *
349 keymgmt_import_types(int selection)
350 {
351  xkey_dmsg(D_XKEY, "entry");
352 
353  static const OSSL_PARAM key_types[] = { OSSL_PARAM_END };
354 
355  if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
356  {
357  return key_types;
358  }
359  return NULL;
360 }
361 
362 static void
363 keymgmt_free(void *keydata)
364 {
365  xkey_dmsg(D_XKEY, "entry");
366 
367  keydata_free(keydata);
368 }
369 
370 static int
371 keymgmt_has(const void *keydata, int selection)
372 {
373  xkey_dmsg(D_XKEY, "selection = %d", selection);
374 
375  const XKEY_KEYDATA *key = keydata;
376  int ok = (key != NULL);
377 
378  if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
379  {
380  ok = ok && key->pubkey;
381  }
382  if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
383  {
384  ok = ok && key->handle;
385  }
386 
387  return ok;
388 }
389 
390 static int
391 keymgmt_match(const void *keydata1, const void *keydata2, int selection)
392 {
393  const XKEY_KEYDATA *key1 = keydata1;
394  const XKEY_KEYDATA *key2 = keydata2;
395 
396  xkey_dmsg(D_XKEY, "entry");
397 
398  int ret = key1 && key2 && key1->pubkey && key2->pubkey;
399 
400  /* our keys always have pubkey -- we only match them */
401 
402  if (selection & OSSL_KEYMGMT_SELECT_KEYPAIR)
403  {
404  ret = ret && EVP_PKEY_eq(key1->pubkey, key2->pubkey);
405  xkey_dmsg(D_XKEY, "checking key pair match: res = %d", ret);
406  }
407 
408  if (selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
409  {
410  ret = ret && EVP_PKEY_parameters_eq(key1->pubkey, key2->pubkey);
411  xkey_dmsg(D_XKEY, "checking parameter match: res = %d", ret);
412  }
413 
414  return ret;
415 }
416 
417 /* A minimal set of key params that we can return */
418 static const OSSL_PARAM *
419 keymgmt_gettable_params(void *provctx)
420 {
421  xkey_dmsg(D_XKEY, "entry");
422 
423  static OSSL_PARAM gettable[] = {
424  OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
425  OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
426  OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
427  OSSL_PARAM_END
428  };
429  return gettable;
430 }
431 
432 static int
433 keymgmt_get_params(void *keydata, OSSL_PARAM *params)
434 {
435  xkey_dmsg(D_XKEY, "entry");
436 
437  XKEY_KEYDATA *key = keydata;
438  if (!key || !key->pubkey)
439  {
440  return 0;
441  }
442 
443  return EVP_PKEY_get_params(key->pubkey, params);
444 }
445 
446 /* Helper used by keymgmt_import and keymgmt_set_params
447  * for our keys. Not to be used for OpenSSL native keys.
448  */
449 static int
450 keymgmt_import_helper(XKEY_KEYDATA *key, const OSSL_PARAM *params)
451 {
452  xkey_dmsg(D_XKEY, "entry");
453 
454  const OSSL_PARAM *p;
455  EVP_PKEY *pkey = NULL;
456 
457  ASSERT(key);
458  /* calling this with native keys is a coding error */
459  ASSERT(key->origin != OPENSSL_NATIVE);
460 
461  if (params == NULL)
462  {
463  return 1; /* not an error */
464  }
465 
466  /* our keys are immutable, we do not allow resetting parameters */
467  if (key->pubkey)
468  {
469  return 0;
470  }
471 
472  /* only check params we understand and ignore the rest */
473 
474  p = OSSL_PARAM_locate_const(params, "pubkey"); /*setting pubkey on our keydata */
475  if (p && p->data_type == OSSL_PARAM_OCTET_STRING
476  && p->data_size == sizeof(pkey))
477  {
478  pkey = *(EVP_PKEY **)p->data;
479  ASSERT(pkey);
480 
481  int id = EVP_PKEY_get_id(pkey);
482  if (id != EVP_PKEY_RSA && id != EVP_PKEY_EC && id != EVP_PKEY_ED25519 && id != EVP_PKEY_ED448)
483  {
484  msg(M_WARN, "Error: xkey keymgmt_import: unknown key type (%d)", id);
485  return 0;
486  }
487 
488  key->pubkey = EVP_PKEY_dup(pkey);
489  if (key->pubkey == NULL)
490  {
491  msg(M_NONFATAL, "Error: xkey keymgmt_import: duplicating pubkey failed.");
492  return 0;
493  }
494  }
495 
496  p = OSSL_PARAM_locate_const(params, "handle"); /*setting privkey */
497  if (p && p->data_type == OSSL_PARAM_OCTET_PTR
498  && p->data_size == sizeof(key->handle))
499  {
500  key->handle = *(void **)p->data;
501  /* caller should keep the reference alive until we call free */
502  ASSERT(key->handle); /* fix your params array */
503  }
504 
505  p = OSSL_PARAM_locate_const(params, "sign_op"); /*setting sign_op */
506  if (p && p->data_type == OSSL_PARAM_OCTET_PTR
507  && p->data_size == sizeof(key->sign))
508  {
509  key->sign = *(void **)p->data;
510  ASSERT(key->sign); /* fix your params array */
511  }
512 
513  /* optional parameters */
514  p = OSSL_PARAM_locate_const(params, "free_op"); /*setting free_op */
515  if (p && p->data_type == OSSL_PARAM_OCTET_PTR
516  && p->data_size == sizeof(key->free))
517  {
518  key->free = *(void **)p->data;
519  }
520  xkey_dmsg(D_XKEY, "imported external %s key", EVP_PKEY_get0_type_name(key->pubkey));
521 
522  return 1;
523 }
524 
536 static int
537 keymgmt_set_params(void *keydata, const OSSL_PARAM *params)
538 {
539  XKEY_KEYDATA *key = keydata;
540  ASSERT(key);
541 
542  xkey_dmsg(D_XKEY, "entry");
543 
544  if (key->origin != OPENSSL_NATIVE)
545  {
546  return keymgmt_import_helper(key, params);
547  }
548  else if (key->handle == NULL) /* once handle is set our key is immutable */
549  {
550  /* pubkey is always native -- just delegate */
551  return EVP_PKEY_set_params(key->pubkey, (OSSL_PARAM *)params);
552  }
553  else
554  {
555  msg(M_WARN, "xkey keymgmt_set_params: key is immutable");
556  }
557  return 1;
558 }
559 
560 static const char *
561 rsa_keymgmt_name(int id)
562 {
563  xkey_dmsg(D_XKEY, "entry");
564 
565  return "RSA";
566 }
567 
568 static const char *
569 ec_keymgmt_name(int id)
570 {
571  xkey_dmsg(D_XKEY, "entry");
572 
573  if (id == OSSL_OP_SIGNATURE)
574  {
575  return "ECDSA";
576  }
577  /* though we do not implement keyexch we could be queried for
578  * keyexch mechanism supported by EC keys
579  */
580  else if (id == OSSL_OP_KEYEXCH)
581  {
582  return "ECDH";
583  }
584 
585  msg(D_XKEY, "xkey ec_keymgmt_name called with op_id != SIGNATURE or KEYEXCH id=%d", id);
586  return "EC";
587 }
588 
589 static const OSSL_DISPATCH rsa_keymgmt_functions[] = {
590  {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))keymgmt_new},
591  {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))keymgmt_free},
592  {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))keymgmt_load},
593  {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))keymgmt_has},
594  {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))keymgmt_match},
595  {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))rsa_keymgmt_import},
596  {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))keymgmt_import_types},
597  {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params},
598  {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))keymgmt_get_params},
599  {OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))keymgmt_set_params},
600  {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params}, /* same as gettable */
601  {OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))rsa_keymgmt_name},
602  {0, NULL }
603 };
604 
605 static const OSSL_DISPATCH ec_keymgmt_functions[] = {
606  {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))keymgmt_new},
607  {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))keymgmt_free},
608  {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))keymgmt_load},
609  {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))keymgmt_has},
610  {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))keymgmt_match},
611  {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_keymgmt_import},
612  {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))keymgmt_import_types},
613  {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params},
614  {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))keymgmt_get_params},
615  {OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))keymgmt_set_params},
616  {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params}, /* same as gettable */
617  {OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))ec_keymgmt_name},
618  {0, NULL }
619 };
620 
621 static const OSSL_DISPATCH ed448_keymgmt_functions[] = {
622  {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))keymgmt_new},
623  {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))keymgmt_free},
624  {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))keymgmt_load},
625  {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))keymgmt_has},
626  {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))keymgmt_match},
627  {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ed448_keymgmt_import},
628  {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))keymgmt_import_types},
629  {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params},
630  {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))keymgmt_get_params},
631  {OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))keymgmt_set_params},
632  {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params}, /* same as gettable */
633  {0, NULL }
634 };
635 
636 static const OSSL_DISPATCH ed25519_keymgmt_functions[] = {
637  {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))keymgmt_new},
638  {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))keymgmt_free},
639  {OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))keymgmt_load},
640  {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))keymgmt_has},
641  {OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))keymgmt_match},
642  {OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ed25519_keymgmt_import},
643  {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))keymgmt_import_types},
644  {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params},
645  {OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))keymgmt_get_params},
646  {OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))keymgmt_set_params},
647  {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))keymgmt_gettable_params}, /* same as gettable */
648  {0, NULL }
649 };
650 
651 
652 const OSSL_ALGORITHM keymgmts[] = {
653  {"RSA:rsaEncryption", XKEY_PROV_PROPS, rsa_keymgmt_functions, "OpenVPN xkey RSA Key Manager"},
654  {"RSA-PSS:RSASSA-PSS", XKEY_PROV_PROPS, rsa_keymgmt_functions, "OpenVPN xkey RSA-PSS Key Manager"},
655  {"EC:id-ecPublicKey", XKEY_PROV_PROPS, ec_keymgmt_functions, "OpenVPN xkey EC Key Manager"},
656  {"ED448", XKEY_PROV_PROPS, ed448_keymgmt_functions, "OpenVPN xkey ED448 Key Manager"},
657  {"ED25519", XKEY_PROV_PROPS, ed25519_keymgmt_functions, "OpenVPN xkey ED25519 Key Manager"},
658  {NULL, NULL, NULL, NULL}
659 };
660 
661 
662 /* signature provider */
663 
664 /* signature provider callbacks we provide */
665 static OSSL_FUNC_signature_newctx_fn signature_newctx;
666 static OSSL_FUNC_signature_freectx_fn signature_freectx;
667 static OSSL_FUNC_signature_sign_init_fn signature_sign_init;
668 static OSSL_FUNC_signature_sign_fn signature_sign;
669 static OSSL_FUNC_signature_digest_verify_init_fn signature_digest_verify_init;
670 static OSSL_FUNC_signature_digest_verify_fn signature_digest_verify;
671 static OSSL_FUNC_signature_digest_sign_init_fn signature_digest_sign_init;
672 static OSSL_FUNC_signature_digest_sign_fn signature_digest_sign;
673 static OSSL_FUNC_signature_set_ctx_params_fn signature_set_ctx_params;
674 static OSSL_FUNC_signature_settable_ctx_params_fn signature_settable_ctx_params;
675 static OSSL_FUNC_signature_get_ctx_params_fn signature_get_ctx_params;
676 static OSSL_FUNC_signature_gettable_ctx_params_fn signature_gettable_ctx_params;
677 
678 typedef struct
679 {
680  XKEY_PROVIDER_CTX *prov;
681  XKEY_KEYDATA *keydata;
682  XKEY_SIGALG sigalg;
683 } XKEY_SIGNATURE_CTX;
684 
685 static const XKEY_SIGALG default_sigalg = { .mdname = "MD5-SHA1", .saltlen = "digest",
686  .padmode = "pkcs1", .keytype = "RSA"};
687 
688 const struct {
689  int nid;
690  const char *name;
691 } digest_names[] = {{NID_md5_sha1, "MD5-SHA1"}, {NID_sha1, "SHA1"},
692  {NID_sha224, "SHA224", }, {NID_sha256, "SHA256"}, {NID_sha384, "SHA384"},
693  {NID_sha512, "SHA512"}, {0, NULL}};
694 /* Use of NIDs as opposed to EVP_MD_fetch is okay here
695  * as these are only used for converting names passed in
696  * by OpenSSL to const strings.
697  */
698 
699 static struct {
700  int id;
701  const char *name;
702 } padmode_names[] = {{RSA_PKCS1_PADDING, "pkcs1"},
703  {RSA_PKCS1_PSS_PADDING, "pss"},
704  {RSA_NO_PADDING, "none"},
705  {0, NULL}};
706 
707 static const char *saltlen_names[] = {"digest", "max", "auto", NULL};
708 
709 /* Return a string literal for digest name - normalizes
710  * alternate names like SHA2-256 to SHA256 etc.
711  */
712 static const char *
713 xkey_mdname(const char *name)
714 {
715  if (name == NULL)
716  {
717  return "none";
718  }
719 
720  int i = 0;
721 
722  int nid = EVP_MD_get_type(EVP_get_digestbyname(name));
723 
724  while (digest_names[i].name && nid != digest_names[i].nid)
725  {
726  i++;
727  }
728  return digest_names[i].name ? digest_names[i].name : "MD5-SHA1";
729 }
730 
731 static void *
732 signature_newctx(void *provctx, const char *propq)
733 {
734  xkey_dmsg(D_XKEY, "entry");
735 
736  (void) propq; /* unused */
737 
738  XKEY_SIGNATURE_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
739  if (!sctx)
740  {
741  msg(M_NONFATAL, "xkey_signature_newctx: out of memory");
742  return NULL;
743  }
744 
745  sctx->prov = provctx;
746  sctx->sigalg = default_sigalg;
747 
748  return sctx;
749 }
750 
751 static void
752 signature_freectx(void *ctx)
753 {
754  xkey_dmsg(D_XKEY, "entry");
755 
756  XKEY_SIGNATURE_CTX *sctx = ctx;
757 
758  keydata_free(sctx->keydata);
759 
760  OPENSSL_free(sctx);
761 }
762 
763 static const OSSL_PARAM *
764 signature_settable_ctx_params(void *ctx, void *provctx)
765 {
766  xkey_dmsg(D_XKEY, "entry");
767 
768  static OSSL_PARAM settable[] = {
769  OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0),
770  OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
771  OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
772  OSSL_PARAM_END
773  };
774 
775  return settable;
776 }
777 
778 static int
779 signature_set_ctx_params(void *ctx, const OSSL_PARAM params[])
780 {
781  xkey_dmsg(D_XKEY, "entry");
782 
783  XKEY_SIGNATURE_CTX *sctx = ctx;
784  const OSSL_PARAM *p;
785 
786  if (params == NULL)
787  {
788  return 1; /* not an error */
789  }
790  p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE);
791  if (p && p->data_type == OSSL_PARAM_UTF8_STRING)
792  {
793  sctx->sigalg.padmode = NULL;
794  for (int i = 0; padmode_names[i].id != 0; i++)
795  {
796  if (!strcmp(p->data, padmode_names[i].name))
797  {
798  sctx->sigalg.padmode = padmode_names[i].name;
799  break;
800  }
801  }
802  if (sctx->sigalg.padmode == NULL)
803  {
804  msg(M_WARN, "xkey signature_ctx: padmode <%s>, treating as <none>",
805  (char *)p->data);
806  sctx->sigalg.padmode = "none";
807  }
808  xkey_dmsg(D_XKEY, "setting padmode as %s", sctx->sigalg.padmode);
809  }
810  else if (p && p->data_type == OSSL_PARAM_INTEGER)
811  {
812  sctx->sigalg.padmode = NULL;
813  int padmode = 0;
814  if (OSSL_PARAM_get_int(p, &padmode))
815  {
816  for (int i = 0; padmode_names[i].id != 0; i++)
817  {
818  if (padmode == padmode_names[i].id)
819  {
820  sctx->sigalg.padmode = padmode_names[i].name;
821  break;
822  }
823  }
824  }
825  if (padmode == 0 || sctx->sigalg.padmode == NULL)
826  {
827  msg(M_WARN, "xkey signature_ctx: padmode <%d>, treating as <none>", padmode);
828  sctx->sigalg.padmode = "none";
829  }
830  xkey_dmsg(D_XKEY, "setting padmode <%s>", sctx->sigalg.padmode);
831  }
832  else if (p)
833  {
834  msg(M_WARN, "xkey_signature_params: unknown padmode ignored");
835  }
836 
837  p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
838  if (p && p->data_type == OSSL_PARAM_UTF8_STRING)
839  {
840  sctx->sigalg.mdname = xkey_mdname(p->data);
841  xkey_dmsg(D_XKEY, "setting hashalg as %s", sctx->sigalg.mdname);
842  }
843  else if (p)
844  {
845  msg(M_WARN, "xkey_signature_params: unknown digest type ignored");
846  }
847 
848  p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN);
849  if (p && p->data_type == OSSL_PARAM_UTF8_STRING)
850  {
851  sctx->sigalg.saltlen = NULL;
852  for (int i = 0; saltlen_names[i] != NULL; i++)
853  {
854  if (!strcmp(p->data, saltlen_names[i]))
855  {
856  sctx->sigalg.saltlen = saltlen_names[i];
857  break;
858  }
859  }
860  if (sctx->sigalg.saltlen == NULL)
861  {
862  msg(M_WARN, "xkey_signature_params: unknown saltlen <%s>",
863  (char *)p->data);
864  sctx->sigalg.saltlen = "digest"; /* most common */
865  }
866  xkey_dmsg(D_XKEY, "setting saltlen to %s", sctx->sigalg.saltlen);
867  }
868  else if (p)
869  {
870  msg(M_WARN, "xkey_signature_params: unknown saltlen ignored");
871  }
872 
873  return 1;
874 }
875 
876 static const OSSL_PARAM *
877 signature_gettable_ctx_params(void *ctx, void *provctx)
878 {
879  xkey_dmsg(D_XKEY, "entry");
880 
881  static OSSL_PARAM gettable[] = { OSSL_PARAM_END }; /* Empty list */
882 
883  return gettable;
884 }
885 
886 static int
887 signature_get_ctx_params(void *ctx, OSSL_PARAM params[])
888 {
889  xkey_dmsg(D_XKEY, "not implemented");
890  return 0;
891 }
892 
893 static int
894 signature_sign_init(void *ctx, void *provkey, const OSSL_PARAM params[])
895 {
896  xkey_dmsg(D_XKEY, "entry");
897 
898  XKEY_SIGNATURE_CTX *sctx = ctx;
899 
900  if (sctx->keydata)
901  {
902  keydata_free(sctx->keydata);
903  }
904  sctx->keydata = provkey;
905  sctx->keydata->refcount++; /* we are keeping a copy */
906  sctx->sigalg.keytype = get_keytype(sctx->keydata);
907 
908  signature_set_ctx_params(sctx, params);
909 
910  return 1;
911 }
912 
913 /* Sign digest or message using sign function */
914 static int
915 xkey_sign_dispatch(XKEY_SIGNATURE_CTX *sctx, unsigned char *sig, size_t *siglen,
916  const unsigned char *tbs, size_t tbslen)
917 {
918  XKEY_EXTERNAL_SIGN_fn *sign = sctx->keydata->sign;
919  int ret = 0;
920 
921  if (sctx->keydata->origin == OPENSSL_NATIVE)
922  {
923  ret = xkey_native_sign(sctx->keydata, sig, siglen, tbs, tbslen, sctx->sigalg);
924  }
925  else if (sign)
926  {
927  ret = sign(sctx->keydata->handle, sig, siglen, tbs, tbslen, sctx->sigalg);
928  xkey_dmsg(D_XKEY, "xkey_provider: external sign op returned ret = %d siglen = %d", ret, (int) *siglen);
929  }
930  else
931  {
932  msg(M_NONFATAL, "xkey_provider: Internal error: No sign callback for external key.");
933  }
934 
935  return ret;
936 }
937 
938 static int
939 signature_sign(void *ctx, unsigned char *sig, size_t *siglen, size_t sigsize,
940  const unsigned char *tbs, size_t tbslen)
941 {
942  xkey_dmsg(D_XKEY, "entry with siglen = %zu\n", *siglen);
943 
944  XKEY_SIGNATURE_CTX *sctx = ctx;
945  ASSERT(sctx);
946  ASSERT(sctx->keydata);
947 
948  if (!sig)
949  {
950  *siglen = KEYSIZE(sctx->keydata);
951  return 1;
952  }
953 
954  sctx->sigalg.op = "Sign";
955  return xkey_sign_dispatch(sctx, sig, siglen, tbs, tbslen);
956 }
957 
958 static int
959 signature_digest_verify_init(void *ctx, const char *mdname, void *provkey,
960  const OSSL_PARAM params[])
961 {
962  xkey_dmsg(D_XKEY, "mdname <%s>", mdname);
963 
964  msg(M_WARN, "xkey_provider: DigestVerifyInit is not implemented");
965  return 0;
966 }
967 
968 /* We do not expect to be called for DigestVerify() but still
969  * return an empty function for it in the sign dispatch array
970  * for debugging purposes.
971  */
972 static int
973 signature_digest_verify(void *ctx, const unsigned char *sig, size_t siglen,
974  const unsigned char *tbs, size_t tbslen)
975 {
976  xkey_dmsg(D_XKEY, "entry");
977 
978  msg(M_WARN, "xkey_provider: DigestVerify is not implemented");
979  return 0;
980 }
981 
982 static int
983 signature_digest_sign_init(void *ctx, const char *mdname,
984  void *provkey, const OSSL_PARAM params[])
985 {
986  xkey_dmsg(D_XKEY, "mdname = <%s>", mdname);
987 
988  XKEY_SIGNATURE_CTX *sctx = ctx;
989 
990  ASSERT(sctx);
991  ASSERT(provkey);
992  ASSERT(sctx->prov);
993 
994  if (sctx->keydata)
995  {
996  keydata_free(sctx->keydata);
997  }
998  sctx->keydata = provkey; /* used by digest_sign */
999  sctx->keydata->refcount++;
1000  sctx->sigalg.keytype = get_keytype(sctx->keydata);
1001 
1002  signature_set_ctx_params(ctx, params);
1003  if (!strcmp(sctx->sigalg.keytype, "ED448") || !strcmp(sctx->sigalg.keytype, "ED25519"))
1004  {
1005  /* EdDSA requires NULL as digest for the DigestSign API instead
1006  * of using the normal Sign API. Ensure it is actually NULL too */
1007  if (mdname != NULL)
1008  {
1009  msg(M_WARN, "xkey digest_sign_init: mdname must be NULL for ED448/ED25519.");
1010  return 0;
1011  }
1012  sctx->sigalg.mdname = "none";
1013  }
1014  else if (mdname)
1015  {
1016  sctx->sigalg.mdname = xkey_mdname(mdname); /* get a string literal pointer */
1017  }
1018  else
1019  {
1020  msg(M_WARN, "xkey digest_sign_init: mdname is NULL.");
1021  }
1022  return 1;
1023 }
1024 
1025 static int
1026 signature_digest_sign(void *ctx, unsigned char *sig, size_t *siglen,
1027  size_t sigsize, const unsigned char *tbs, size_t tbslen)
1028 {
1029  xkey_dmsg(D_XKEY, "entry");
1030 
1031  XKEY_SIGNATURE_CTX *sctx = ctx;
1032 
1033  ASSERT(sctx);
1034  ASSERT(sctx->keydata);
1035 
1036  if (!sig) /* set siglen and return */
1037  {
1038  *siglen = KEYSIZE(sctx->keydata);
1039  return 1;
1040  }
1041 
1042  if (sctx->keydata->origin != OPENSSL_NATIVE)
1043  {
1044  /* pass the message itself to the backend */
1045  sctx->sigalg.op = "DigestSign";
1046  return xkey_sign_dispatch(ctx, sig, siglen, tbs, tbslen);
1047  }
1048 
1049  /* create digest and pass on to signature_sign() */
1050 
1051  const char *mdname = sctx->sigalg.mdname;
1052  EVP_MD *md = EVP_MD_fetch(sctx->prov->libctx, mdname, NULL);
1053  if (!md)
1054  {
1055  msg(M_WARN, "WARN: xkey digest_sign_init: MD_fetch failed for <%s>", mdname);
1056  return 0;
1057  }
1058 
1059  /* construct digest using OpenSSL */
1060  unsigned char buf[EVP_MAX_MD_SIZE];
1061  unsigned int sz;
1062  if (EVP_Digest(tbs, tbslen, buf, &sz, md, NULL) != 1)
1063  {
1064  msg(M_WARN, "WARN: xkey digest_sign: EVP_Digest failed");
1065  EVP_MD_free(md);
1066  return 0;
1067  }
1068  EVP_MD_free(md);
1069 
1070  return signature_sign(ctx, sig, siglen, sigsize, buf, sz);
1071 }
1072 
1073 /* Sign digest using native sign function -- will only work for native keys
1074  */
1075 int
1076 xkey_native_sign(XKEY_KEYDATA *key, unsigned char *sig, size_t *siglen,
1077  const unsigned char *tbs, size_t tbslen, XKEY_SIGALG sigalg)
1078 {
1079  xkey_dmsg(D_XKEY, "entry");
1080 
1081  ASSERT(key);
1082 
1083  EVP_PKEY *pkey = key->handle;
1084  int ret = 0;
1085 
1086  ASSERT(sig);
1087 
1088  if (!pkey)
1089  {
1090  msg(M_NONFATAL, "Error: xkey provider: signature request with empty private key");
1091  return 0;
1092  }
1093 
1094  const char *saltlen = sigalg.saltlen;
1095  const char *mdname = sigalg.mdname;
1096  const char *padmode = sigalg.padmode;
1097 
1098  xkey_dmsg(D_XKEY, "digest=<%s>, padmode=<%s>, saltlen=<%s>", mdname, padmode, saltlen);
1099 
1100  int i = 0;
1101  OSSL_PARAM params[6];
1102  if (EVP_PKEY_get_id(pkey) == EVP_PKEY_RSA)
1103  {
1104  params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, (char *)mdname, 0);
1105  params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, (char *)padmode, 0);
1106  if (!strcmp(sigalg.padmode, "pss"))
1107  {
1108  params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, (char *) saltlen, 0);
1109  /* same digest for mgf1 */
1110  params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, (char *) mdname, 0);
1111  }
1112  }
1113  params[i++] = OSSL_PARAM_construct_end();
1114 
1115  EVP_PKEY_CTX *ectx = EVP_PKEY_CTX_new_from_pkey(key->prov->libctx, pkey, NULL);
1116 
1117  if (!ectx)
1118  {
1119  msg(M_WARN, "WARN: xkey test_sign: call to EVP_PKEY_CTX_new...failed");
1120  return 0;
1121  }
1122 
1123  if (EVP_PKEY_sign_init_ex(ectx, NULL) != 1)
1124  {
1125  msg(M_WARN, "WARN: xkey test_sign: call to EVP_PKEY_sign_init failed");
1126  return 0;
1127  }
1128  EVP_PKEY_CTX_set_params(ectx, params);
1129 
1130  ret = EVP_PKEY_sign(ectx, sig, siglen, tbs, tbslen);
1131  EVP_PKEY_CTX_free(ectx);
1132 
1133  return ret;
1134 }
1135 
1136 static const OSSL_DISPATCH signature_functions[] = {
1137  {OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))signature_newctx},
1138  {OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))signature_freectx},
1139  {OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))signature_sign_init},
1140  {OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))signature_sign},
1141  {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, (void (*)(void))signature_digest_verify_init},
1142  {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, (void (*)(void))signature_digest_verify},
1143  {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))signature_digest_sign_init},
1144  {OSSL_FUNC_SIGNATURE_DIGEST_SIGN, (void (*)(void))signature_digest_sign},
1145  {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))signature_set_ctx_params},
1146  {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))signature_settable_ctx_params},
1147  {OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))signature_get_ctx_params},
1148  {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))signature_gettable_ctx_params},
1149  {0, NULL }
1150 };
1151 
1152 const OSSL_ALGORITHM signatures[] = {
1153  {"RSA:rsaEncryption", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey RSA Signature"},
1154  {"ECDSA", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey ECDSA Signature"},
1155  {"ED448", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey Ed448 Signature"},
1156  {"ED25519", XKEY_PROV_PROPS, signature_functions, "OpenVPN xkey Ed25519 Signature"},
1157  {NULL, NULL, NULL, NULL}
1158 };
1159 
1160 /* main provider interface */
1161 
1162 /* provider callbacks we implement */
1163 static OSSL_FUNC_provider_query_operation_fn query_operation;
1164 static OSSL_FUNC_provider_gettable_params_fn gettable_params;
1165 static OSSL_FUNC_provider_get_params_fn get_params;
1166 static OSSL_FUNC_provider_teardown_fn teardown;
1167 
1168 static const OSSL_ALGORITHM *
1169 query_operation(void *provctx, int op, int *no_store)
1170 {
1171  xkey_dmsg(D_XKEY, "op = %d", op);
1172 
1173  *no_store = 0;
1174 
1175  switch (op)
1176  {
1177  case OSSL_OP_SIGNATURE:
1178  return signatures;
1179 
1180  case OSSL_OP_KEYMGMT:
1181  return keymgmts;
1182 
1183  default:
1184  xkey_dmsg(D_XKEY, "op not supported");
1185  break;
1186  }
1187  return NULL;
1188 }
1189 
1190 static const OSSL_PARAM *
1191 gettable_params(void *provctx)
1192 {
1193  xkey_dmsg(D_XKEY, "entry");
1194 
1195  static const OSSL_PARAM param_types[] = {
1196  OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0),
1197  OSSL_PARAM_END
1198  };
1199 
1200  return param_types;
1201 }
1202 static int
1203 get_params(void *provctx, OSSL_PARAM params[])
1204 {
1205  OSSL_PARAM *p;
1206 
1207  xkey_dmsg(D_XKEY, "entry");
1208 
1209  p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
1210  if (p)
1211  {
1212  return (OSSL_PARAM_set_utf8_ptr(p, provname) != 0);
1213  }
1214 
1215  return 0;
1216 }
1217 
1218 static void
1219 teardown(void *provctx)
1220 {
1221  xkey_dmsg(D_XKEY, "entry");
1222 
1223  XKEY_PROVIDER_CTX *prov = provctx;
1224  if (prov && prov->libctx)
1225  {
1226  OSSL_LIB_CTX_free(prov->libctx);
1227  }
1228  OPENSSL_free(prov);
1229 }
1230 
1231 static const OSSL_DISPATCH dispatch_table[] = {
1232  {OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))gettable_params},
1233  {OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))get_params},
1234  {OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))query_operation},
1235  {OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))teardown},
1236  {0, NULL}
1237 };
1238 
1239 int
1240 xkey_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in,
1241  const OSSL_DISPATCH **out, void **provctx)
1242 {
1243  XKEY_PROVIDER_CTX *prov;
1244 
1245  xkey_dmsg(D_XKEY, "entry");
1246 
1247  prov = OPENSSL_zalloc(sizeof(*prov));
1248  if (!prov)
1249  {
1250  msg(M_NONFATAL, "xkey_provider_init: out of memory");
1251  return 0;
1252  }
1253 
1254  /* Make a child libctx for our use and set default prop query
1255  * on it to ensure calls we delegate won't loop back to us.
1256  */
1257  prov->libctx = OSSL_LIB_CTX_new_child(handle, in);
1258 
1259  EVP_set_default_properties(prov->libctx, "provider!=ovpn.xkey");
1260 
1261  *out = dispatch_table;
1262  *provctx = prov;
1263 
1264  return 1;
1265 }
1266 
1267 #endif /* HAVE_XKEY_PROVIDER */
error.h
teardown
static int teardown(void **state)
Definition: test.c:22
EVP_MD_fetch
static const EVP_MD * EVP_MD_fetch(void *ctx, const char *algorithm, const char *properties)
Definition: openssl_compat.h:788
M_NONFATAL
#define M_NONFATAL
Definition: error.h:96
key1
static const char *const key1
Definition: cert_data.h:56
xkey_common.h
EVP_MD_free
static void EVP_MD_free(const EVP_MD *md)
Definition: openssl_compat.h:802
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:149
ASSERT
#define ASSERT(x)
Definition: error.h:201
M_WARN
#define M_WARN
Definition: error.h:97
buffer.h
syshead.h
D_XKEY
#define D_XKEY
Definition: errlevel.h:117
config.h
key2
Container for bidirectional cipher and HMAC key material.
Definition: crypto.h:179
msg
#define msg(flags,...)
Definition: error.h:150
OSSL_LIB_CTX
void OSSL_LIB_CTX
Definition: openssl_compat.h:774