openssl/providers/implementations/kem/template_kem.c
Michael Baentsch 51921b8737 first cut at KEM & key management skeletons
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25640)
2024-10-21 11:47:16 +01:00

192 lines
5.5 KiB
C

/*
* 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 <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include <openssl/err.h>
#include <openssl/proverr.h>
#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
};