/* * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include #include #include #include #include #include #include #include #include "prov/provider_ctx.h" #include "prov/implementations.h" #include "prov/securitycheck.h" #include "prov/providercommon.h" extern const OSSL_DISPATCH ossl_template_asym_kem_functions[]; #define BUFSIZE 1000 #if defined(NDEBUG) || defined(OPENSSL_NO_STDIO) static void debug_print(char *fmt, ...) { } #else static void debug_print(char *fmt, ...) { char out[BUFSIZE]; va_list argptr; va_start(argptr, fmt); vsnprintf(out, BUFSIZE, fmt, argptr); va_end(argptr); if (getenv("TEMPLATEKEM")) fprintf(stderr, "TEMPLATE_KEM: %s", out); } #endif typedef struct { OSSL_LIB_CTX *libctx; /* some algorithm-specific key struct */ int op; } PROV_TEMPLATE_CTX; static OSSL_FUNC_kem_newctx_fn template_newctx; static OSSL_FUNC_kem_encapsulate_init_fn template_encapsulate_init; static OSSL_FUNC_kem_encapsulate_fn template_encapsulate; static OSSL_FUNC_kem_decapsulate_init_fn template_decapsulate_init; static OSSL_FUNC_kem_decapsulate_fn template_decapsulate; static OSSL_FUNC_kem_freectx_fn template_freectx; static OSSL_FUNC_kem_set_ctx_params_fn template_set_ctx_params; static OSSL_FUNC_kem_settable_ctx_params_fn template_settable_ctx_params; static void *template_newctx(void *provctx) { PROV_TEMPLATE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); debug_print("newctx called\n"); if (ctx == NULL) return NULL; ctx->libctx = PROV_LIBCTX_OF(provctx); debug_print("newctx returns %p\n", ctx); return ctx; } static void template_freectx(void *vctx) { PROV_TEMPLATE_CTX *ctx = (PROV_TEMPLATE_CTX *)vctx; debug_print("freectx %p\n", ctx); OPENSSL_free(ctx); } static int template_init(void *vctx, int operation, void *vkey, void *vauth, ossl_unused const OSSL_PARAM params[]) { PROV_TEMPLATE_CTX *ctx = (PROV_TEMPLATE_CTX *)vctx; debug_print("init %p / %p\n", ctx, vkey); if (!ossl_prov_is_running()) return 0; /* check and fill in reference to key */ ctx->op = operation; debug_print("init OK\n"); return 1; } static int template_encapsulate_init(void *vctx, void *vkey, const OSSL_PARAM params[]) { return template_init(vctx, EVP_PKEY_OP_ENCAPSULATE, vkey, NULL, params); } static int template_decapsulate_init(void *vctx, void *vkey, const OSSL_PARAM params[]) { return template_init(vctx, EVP_PKEY_OP_DECAPSULATE, vkey, NULL, params); } static int template_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_TEMPLATE_CTX *ctx = (PROV_TEMPLATE_CTX *)vctx; debug_print("set ctx params %p\n", ctx); if (ctx == NULL) return 0; if (ossl_param_is_empty(params)) return 1; debug_print("set ctx params OK\n"); return 1; } static const OSSL_PARAM known_settable_template_ctx_params[] = { /* possibly more params */ OSSL_PARAM_END }; static const OSSL_PARAM *template_settable_ctx_params(ossl_unused void *vctx, ossl_unused void *provctx) { return known_settable_template_ctx_params; } static int template_encapsulate(void *vctx, unsigned char *out, size_t *outlen, unsigned char *secret, size_t *secretlen) { debug_print("encaps %p to %p\n", vctx, out); /* add algorithm-specific length checks */ if (outlen != NULL) *outlen = 0; /* replace with real encapsulated data length */ if (secretlen != NULL) *secretlen = 0; /* replace with real shared secret length */ if (out == NULL) { debug_print("encaps outlens set to %d and %d\n", *outlen, *secretlen); return 1; } /* check key and perform real KEM operation */ debug_print("encaps OK\n"); return 1; } static int template_decapsulate(void *vctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen) { debug_print("decaps %p to %p inlen at %d\n", vctx, out, inlen); /* add algorithm-specific length checks */ if (outlen != NULL) *outlen = 0; /* replace with shared secret length */ if (out == NULL) { debug_print("decaps outlen set to %d \n", *outlen); return 1; } /* check key and perform real decaps operation */ debug_print("decaps OK\n"); return 1; } const OSSL_DISPATCH ossl_template_asym_kem_functions[] = { { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))template_newctx }, { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))template_encapsulate_init }, { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))template_encapsulate }, { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))template_decapsulate_init }, { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))template_decapsulate }, { OSSL_FUNC_KEM_FREECTX, (void (*)(void))template_freectx }, { OSSL_FUNC_KEM_SET_CTX_PARAMS, (void (*)(void))template_set_ctx_params }, { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, (void (*)(void))template_settable_ctx_params }, OSSL_DISPATCH_END };