1 /*
2 * Copyright 2024 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 debug_print("encaps outlens set to %d and %d\n", *outlen, *secretlen);
147 return 1;
148 }
149
150 /* check key and perform real KEM operation */
151
152 debug_print("encaps OK\n");
153 return 1;
154 }
155
template_decapsulate(void * vctx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)156 static int template_decapsulate(void *vctx, unsigned char *out, size_t *outlen,
157 const unsigned char *in, size_t inlen)
158 {
159 debug_print("decaps %p to %p inlen at %d\n", vctx, out, inlen);
160
161 /* add algorithm-specific length checks */
162
163 if (outlen != NULL)
164 *outlen = 0; /* replace with shared secret length */
165
166 if (out == NULL) {
167 debug_print("decaps outlen set to %d \n", *outlen);
168 return 1;
169 }
170
171 /* check key and perform real decaps operation */
172
173 debug_print("decaps OK\n");
174 return 1;
175 }
176
177 const OSSL_DISPATCH ossl_template_asym_kem_functions[] = {
178 { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))template_newctx },
179 { OSSL_FUNC_KEM_ENCAPSULATE_INIT,
180 (void (*)(void))template_encapsulate_init },
181 { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))template_encapsulate },
182 { OSSL_FUNC_KEM_DECAPSULATE_INIT,
183 (void (*)(void))template_decapsulate_init },
184 { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))template_decapsulate },
185 { OSSL_FUNC_KEM_FREECTX, (void (*)(void))template_freectx },
186 { OSSL_FUNC_KEM_SET_CTX_PARAMS,
187 (void (*)(void))template_set_ctx_params },
188 { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS,
189 (void (*)(void))template_settable_ctx_params },
190 OSSL_DISPATCH_END
191 };
192