Home | History | Annotate | Line # | Download | only in kem
      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)
     27 static void debug_print(char *fmt, ...)
     28 {
     29 }
     30 
     31 #else
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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