1 /*
2 * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <string.h>
11 #include <openssl/crypto.h>
12 #include <openssl/evp.h>
13 #include <openssl/core_dispatch.h>
14 #include <openssl/core_names.h>
15 #include <openssl/params.h>
16 #include <openssl/err.h>
17 #include <openssl/proverr.h>
18 #include "prov/provider_ctx.h"
19 #include "prov/implementations.h"
20 #include "prov/securitycheck.h"
21 #include "prov/providercommon.h"
22
23 extern const OSSL_DISPATCH ossl_template_asym_kem_functions[];
24
25 #define BUFSIZE 1000
26 #if defined(NDEBUG) || defined(OPENSSL_NO_STDIO)
debug_print(char * fmt,...)27 static void debug_print(char *fmt, ...)
28 {
29 }
30
31 #else
debug_print(char * fmt,...)32 static void debug_print(char *fmt, ...)
33 {
34 char out[BUFSIZE];
35 va_list argptr;
36
37 va_start(argptr, fmt);
38 vsnprintf(out, BUFSIZE, fmt, argptr);
39 va_end(argptr);
40 if (getenv("TEMPLATEKEM"))
41 fprintf(stderr, "TEMPLATE_KEM: %s", out);
42 }
43 #endif
44
45 typedef struct {
46 OSSL_LIB_CTX *libctx;
47 /* some algorithm-specific key struct */
48 int op;
49 } PROV_TEMPLATE_CTX;
50
51 static OSSL_FUNC_kem_newctx_fn template_newctx;
52 static OSSL_FUNC_kem_encapsulate_init_fn template_encapsulate_init;
53 static OSSL_FUNC_kem_encapsulate_fn template_encapsulate;
54 static OSSL_FUNC_kem_decapsulate_init_fn template_decapsulate_init;
55 static OSSL_FUNC_kem_decapsulate_fn template_decapsulate;
56 static OSSL_FUNC_kem_freectx_fn template_freectx;
57 static OSSL_FUNC_kem_set_ctx_params_fn template_set_ctx_params;
58 static OSSL_FUNC_kem_settable_ctx_params_fn template_settable_ctx_params;
59
template_newctx(void * provctx)60 static void *template_newctx(void *provctx)
61 {
62 PROV_TEMPLATE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
63
64 debug_print("newctx called\n");
65 if (ctx == NULL)
66 return NULL;
67 ctx->libctx = PROV_LIBCTX_OF(provctx);
68
69 debug_print("newctx returns %p\n", ctx);
70 return ctx;
71 }
72
template_freectx(void * vctx)73 static void template_freectx(void *vctx)
74 {
75 PROV_TEMPLATE_CTX *ctx = (PROV_TEMPLATE_CTX *)vctx;
76
77 debug_print("freectx %p\n", ctx);
78 OPENSSL_free(ctx);
79 }
80
template_init(void * vctx,int operation,void * vkey,void * vauth,ossl_unused const OSSL_PARAM params[])81 static int template_init(void *vctx, int operation, void *vkey, void *vauth,
82 ossl_unused const OSSL_PARAM params[])
83 {
84 PROV_TEMPLATE_CTX *ctx = (PROV_TEMPLATE_CTX *)vctx;
85
86 debug_print("init %p / %p\n", ctx, vkey);
87 if (!ossl_prov_is_running())
88 return 0;
89
90 /* check and fill in reference to key */
91 ctx->op = operation;
92 debug_print("init OK\n");
93 return 1;
94 }
95
template_encapsulate_init(void * vctx,void * vkey,const OSSL_PARAM params[])96 static int template_encapsulate_init(void *vctx, void *vkey,
97 const OSSL_PARAM params[])
98 {
99 return template_init(vctx, EVP_PKEY_OP_ENCAPSULATE, vkey, NULL, params);
100 }
101
template_decapsulate_init(void * vctx,void * vkey,const OSSL_PARAM params[])102 static int template_decapsulate_init(void *vctx, void *vkey,
103 const OSSL_PARAM params[])
104 {
105 return template_init(vctx, EVP_PKEY_OP_DECAPSULATE, vkey, NULL, params);
106 }
107
template_set_ctx_params(void * vctx,const OSSL_PARAM params[])108 static int template_set_ctx_params(void *vctx, const OSSL_PARAM params[])
109 {
110 PROV_TEMPLATE_CTX *ctx = (PROV_TEMPLATE_CTX *)vctx;
111
112 debug_print("set ctx params %p\n", ctx);
113 if (ctx == NULL)
114 return 0;
115 if (ossl_param_is_empty(params))
116 return 1;
117
118 debug_print("set ctx params OK\n");
119 return 1;
120 }
121
122 static const OSSL_PARAM known_settable_template_ctx_params[] = {
123 /* possibly more params */
124 OSSL_PARAM_END
125 };
126
template_settable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)127 static const OSSL_PARAM *template_settable_ctx_params(ossl_unused void *vctx,
128 ossl_unused void *provctx)
129 {
130 return known_settable_template_ctx_params;
131 }
132
template_encapsulate(void * vctx,unsigned char * out,size_t * outlen,unsigned char * secret,size_t * secretlen)133 static int template_encapsulate(void *vctx, unsigned char *out, size_t *outlen,
134 unsigned char *secret, size_t *secretlen)
135 {
136 debug_print("encaps %p to %p\n", vctx, out);
137
138 /* add algorithm-specific length checks */
139
140 if (outlen != NULL)
141 *outlen = 0; /* replace with real encapsulated data length */
142 if (secretlen != NULL)
143 *secretlen = 0; /* replace with real shared secret length */
144
145 if (out == NULL) {
146 if (outlen != NULL && secretlen != NULL)
147 debug_print("encaps outlens set to %zu and %zu\n", *outlen, *secretlen);
148 return 1;
149 }
150
151 /* check key and perform real KEM operation */
152
153 debug_print("encaps OK\n");
154 return 1;
155 }
156
template_decapsulate(void * vctx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)157 static int template_decapsulate(void *vctx, unsigned char *out, size_t *outlen,
158 const unsigned char *in, size_t inlen)
159 {
160 debug_print("decaps %p to %p inlen at %zu\n", vctx, out, inlen);
161
162 /* add algorithm-specific length checks */
163
164 if (outlen != NULL)
165 *outlen = 0; /* replace with shared secret length */
166
167 if (out == NULL) {
168 if (outlen != NULL)
169 debug_print("decaps outlen set to %zu \n", *outlen);
170 return 1;
171 }
172
173 /* check key and perform real decaps operation */
174
175 debug_print("decaps OK\n");
176 return 1;
177 }
178
179 const OSSL_DISPATCH ossl_template_asym_kem_functions[] = {
180 { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))template_newctx },
181 { OSSL_FUNC_KEM_ENCAPSULATE_INIT,
182 (void (*)(void))template_encapsulate_init },
183 { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))template_encapsulate },
184 { OSSL_FUNC_KEM_DECAPSULATE_INIT,
185 (void (*)(void))template_decapsulate_init },
186 { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))template_decapsulate },
187 { OSSL_FUNC_KEM_FREECTX, (void (*)(void))template_freectx },
188 { OSSL_FUNC_KEM_SET_CTX_PARAMS,
189 (void (*)(void))template_set_ctx_params },
190 { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS,
191 (void (*)(void))template_settable_ctx_params },
192 OSSL_DISPATCH_END
193 };
194