Home | History | Annotate | Line # | Download | only in test
fake_pipelineprov.c revision 1.1.1.2
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos /*
     11      1.1  christos  * This file uses the low level AES functions (which are deprecated for
     12      1.1  christos  * non-internal use) in order to implement provider AES ciphers.
     13      1.1  christos  */
     14      1.1  christos #include "internal/deprecated.h"
     15      1.1  christos 
     16      1.1  christos #include <openssl/core.h>
     17      1.1  christos #include <openssl/core_names.h>
     18      1.1  christos #include <openssl/params.h>
     19      1.1  christos #include <openssl/proverr.h>
     20      1.1  christos #include "prov/providercommon.h"
     21      1.1  christos #include "prov/ciphercommon.h"
     22      1.1  christos #include "prov/ciphercommon_aead.h"
     23      1.1  christos #include "testutil.h"
     24      1.1  christos #include "fake_pipelineprov.h"
     25      1.1  christos 
     26      1.1  christos /*
     27      1.1  christos  * This file provides a fake provider that implements a pipeline cipher
     28      1.1  christos  * for AES GCM.
     29      1.1  christos  */
     30      1.1  christos 
     31      1.1  christos typedef struct fake_pipeline_ctx_st {
     32      1.1  christos     size_t keylen;
     33      1.1  christos     size_t ivlen;
     34      1.1  christos     size_t numpipes;
     35      1.1  christos     EVP_CIPHER *cipher;
     36      1.1  christos     EVP_CIPHER_CTX *cipher_ctxs[EVP_MAX_PIPES];
     37      1.1  christos } CIPHER_PIPELINE_CTX;
     38      1.1  christos 
     39      1.1  christos static void *fake_pipeline_newctx(void *provctx, char *ciphername,
     40  1.1.1.2  christos     size_t kbits, size_t ivbits)
     41      1.1  christos {
     42      1.1  christos     CIPHER_PIPELINE_CTX *ctx;
     43      1.1  christos 
     44      1.1  christos     if (!ossl_prov_is_running())
     45      1.1  christos         return NULL;
     46      1.1  christos 
     47      1.1  christos     ctx = OPENSSL_zalloc(sizeof(*ctx));
     48      1.1  christos     if (ctx == NULL)
     49      1.1  christos         return NULL;
     50      1.1  christos 
     51      1.1  christos     ctx->keylen = kbits / 8;
     52      1.1  christos     ctx->ivlen = ivbits / 8;
     53      1.1  christos     ctx->numpipes = 0;
     54      1.1  christos     ctx->cipher = EVP_CIPHER_fetch(provctx, ciphername, "provider=default");
     55      1.1  christos 
     56      1.1  christos     return ctx;
     57      1.1  christos }
     58      1.1  christos 
     59      1.1  christos static OSSL_FUNC_cipher_freectx_fn fake_pipeline_freectx;
     60      1.1  christos static void fake_pipeline_freectx(void *vctx)
     61      1.1  christos {
     62      1.1  christos     CIPHER_PIPELINE_CTX *ctx = (CIPHER_PIPELINE_CTX *)vctx;
     63      1.1  christos     size_t i;
     64      1.1  christos 
     65      1.1  christos     EVP_CIPHER_free(ctx->cipher);
     66      1.1  christos     for (i = 0; i < ctx->numpipes; i++)
     67      1.1  christos         EVP_CIPHER_CTX_free(ctx->cipher_ctxs[i]);
     68      1.1  christos     OPENSSL_clear_free(ctx, sizeof(*ctx));
     69      1.1  christos }
     70      1.1  christos 
     71      1.1  christos OSSL_FUNC_cipher_pipeline_encrypt_init_fn fake_pipeline_einit;
     72      1.1  christos OSSL_FUNC_cipher_pipeline_decrypt_init_fn fake_pipeline_dinit;
     73      1.1  christos OSSL_FUNC_cipher_pipeline_update_fn fake_pipeline_update;
     74      1.1  christos OSSL_FUNC_cipher_pipeline_final_fn fake_pipeline_final;
     75      1.1  christos OSSL_FUNC_cipher_gettable_ctx_params_fn fake_pipeline_aead_gettable_ctx_params;
     76      1.1  christos OSSL_FUNC_cipher_get_ctx_params_fn fake_pipeline_aead_get_ctx_params;
     77      1.1  christos OSSL_FUNC_cipher_settable_ctx_params_fn fake_pipeline_aead_settable_ctx_params;
     78      1.1  christos OSSL_FUNC_cipher_set_ctx_params_fn fake_pipeline_aead_set_ctx_params;
     79      1.1  christos 
     80      1.1  christos static int fake_pipeline_init(void *vctx,
     81  1.1.1.2  christos     const unsigned char *key, size_t keylen,
     82  1.1.1.2  christos     size_t numpipes, const unsigned char **iv,
     83  1.1.1.2  christos     size_t ivlen, int enc)
     84      1.1  christos {
     85      1.1  christos     CIPHER_PIPELINE_CTX *ctx = (CIPHER_PIPELINE_CTX *)vctx;
     86      1.1  christos     size_t i = 0;
     87      1.1  christos 
     88      1.1  christos     ctx->numpipes = numpipes;
     89      1.1  christos     for (i = 0; i < numpipes; i++) {
     90      1.1  christos         ctx->cipher_ctxs[i] = EVP_CIPHER_CTX_new();
     91      1.1  christos         if (ctx->cipher_ctxs[i] == NULL)
     92      1.1  christos             return 0;
     93      1.1  christos         if (!EVP_CipherInit(ctx->cipher_ctxs[i], ctx->cipher, key, iv[i], enc))
     94      1.1  christos             return 0;
     95      1.1  christos     }
     96      1.1  christos 
     97      1.1  christos     return 1;
     98      1.1  christos }
     99      1.1  christos 
    100      1.1  christos int fake_pipeline_einit(void *vctx,
    101  1.1.1.2  christos     const unsigned char *key, size_t keylen,
    102  1.1.1.2  christos     size_t numpipes, const unsigned char **iv,
    103  1.1.1.2  christos     size_t ivlen, const OSSL_PARAM params[])
    104      1.1  christos {
    105      1.1  christos     return fake_pipeline_init(vctx, key, keylen, numpipes, iv, ivlen, 1);
    106      1.1  christos }
    107      1.1  christos 
    108      1.1  christos int fake_pipeline_dinit(void *vctx,
    109  1.1.1.2  christos     const unsigned char *key, size_t keylen,
    110  1.1.1.2  christos     size_t numpipes, const unsigned char **iv,
    111  1.1.1.2  christos     size_t ivlen, const OSSL_PARAM params[])
    112      1.1  christos {
    113      1.1  christos     return fake_pipeline_init(vctx, key, keylen, numpipes, iv, ivlen, 0);
    114      1.1  christos }
    115      1.1  christos 
    116      1.1  christos int fake_pipeline_update(void *vctx, size_t numpipes,
    117  1.1.1.2  christos     unsigned char **out, size_t *outl,
    118  1.1.1.2  christos     const size_t *outsize,
    119  1.1.1.2  christos     const unsigned char **in, const size_t *inl)
    120      1.1  christos {
    121      1.1  christos     CIPHER_PIPELINE_CTX *ctx = (CIPHER_PIPELINE_CTX *)vctx;
    122      1.1  christos     int ioutl, inl_;
    123      1.1  christos     size_t i = 0;
    124      1.1  christos 
    125      1.1  christos     for (i = 0; i < numpipes; i++) {
    126      1.1  christos         inl_ = (int)inl[i];
    127      1.1  christos         if (!EVP_CipherUpdate(ctx->cipher_ctxs[i],
    128  1.1.1.2  christos                 (out != NULL) ? out[i] : NULL,
    129  1.1.1.2  christos                 &ioutl,
    130  1.1.1.2  christos                 in[i], inl_))
    131      1.1  christos             return 0;
    132      1.1  christos         outl[i] = (size_t)ioutl;
    133      1.1  christos     }
    134      1.1  christos     return 1;
    135      1.1  christos }
    136      1.1  christos 
    137      1.1  christos int fake_pipeline_final(void *vctx, size_t numpipes,
    138  1.1.1.2  christos     unsigned char **out, size_t *outl,
    139  1.1.1.2  christos     const size_t *outsize)
    140      1.1  christos {
    141      1.1  christos     CIPHER_PIPELINE_CTX *ctx = (CIPHER_PIPELINE_CTX *)vctx;
    142      1.1  christos     int ioutl;
    143      1.1  christos     size_t i = 0;
    144      1.1  christos 
    145      1.1  christos     for (i = 0; i < numpipes; i++) {
    146      1.1  christos         if (!EVP_CipherFinal(ctx->cipher_ctxs[i], out[i], &ioutl))
    147      1.1  christos             return 0;
    148      1.1  christos         outl[i] = (size_t)ioutl;
    149      1.1  christos     }
    150      1.1  christos     return 1;
    151      1.1  christos }
    152      1.1  christos 
    153      1.1  christos static const OSSL_PARAM fake_pipeline_aead_known_gettable_ctx_params[] = {
    154      1.1  christos     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
    155      1.1  christos     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
    156      1.1  christos     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
    157      1.1  christos     OSSL_PARAM_octet_ptr(OSSL_CIPHER_PARAM_PIPELINE_AEAD_TAG, NULL, 0),
    158      1.1  christos     OSSL_PARAM_END
    159      1.1  christos };
    160      1.1  christos const OSSL_PARAM *fake_pipeline_aead_gettable_ctx_params(ossl_unused void *cctx,
    161  1.1.1.2  christos     ossl_unused void *provctx)
    162      1.1  christos {
    163      1.1  christos     return fake_pipeline_aead_known_gettable_ctx_params;
    164      1.1  christos }
    165      1.1  christos 
    166      1.1  christos static const OSSL_PARAM fake_pipeline_aead_known_settable_ctx_params[] = {
    167      1.1  christos     OSSL_PARAM_octet_ptr(OSSL_CIPHER_PARAM_PIPELINE_AEAD_TAG, NULL, 0),
    168      1.1  christos     OSSL_PARAM_END
    169      1.1  christos };
    170      1.1  christos const OSSL_PARAM *fake_pipeline_aead_settable_ctx_params(ossl_unused void *cctx,
    171  1.1.1.2  christos     ossl_unused void *provctx)
    172      1.1  christos {
    173      1.1  christos     return fake_pipeline_aead_known_settable_ctx_params;
    174      1.1  christos }
    175      1.1  christos 
    176      1.1  christos int fake_pipeline_aead_get_ctx_params(void *vctx, OSSL_PARAM params[])
    177      1.1  christos {
    178      1.1  christos     CIPHER_PIPELINE_CTX *ctx = (CIPHER_PIPELINE_CTX *)vctx;
    179      1.1  christos     OSSL_PARAM *p;
    180      1.1  christos     size_t taglen, i;
    181      1.1  christos     unsigned char **aead_tags = NULL;
    182      1.1  christos     OSSL_PARAM aead_params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
    183      1.1  christos 
    184      1.1  christos     if (ossl_param_is_empty(params))
    185      1.1  christos         return 1;
    186      1.1  christos 
    187      1.1  christos     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
    188      1.1  christos     if (p != NULL) {
    189      1.1  christos         if (!OSSL_PARAM_set_size_t(p, ctx->ivlen)) {
    190      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    191      1.1  christos             return 0;
    192      1.1  christos         }
    193      1.1  christos     }
    194      1.1  christos 
    195      1.1  christos     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
    196      1.1  christos     if (p != NULL) {
    197      1.1  christos         if (!OSSL_PARAM_set_size_t(p, ctx->keylen)) {
    198      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    199      1.1  christos             return 0;
    200      1.1  christos         }
    201      1.1  christos     }
    202      1.1  christos 
    203      1.1  christos     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PIPELINE_AEAD_TAG);
    204      1.1  christos     if (p != NULL) {
    205      1.1  christos         if (!OSSL_PARAM_get_octet_ptr(p, (const void **)&aead_tags, &taglen)) {
    206      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    207      1.1  christos             return 0;
    208      1.1  christos         }
    209      1.1  christos         for (i = 0; i < ctx->numpipes; i++) {
    210      1.1  christos             aead_params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
    211  1.1.1.2  christos                 (void *)aead_tags[i],
    212  1.1.1.2  christos                 taglen);
    213      1.1  christos             if (!EVP_CIPHER_CTX_get_params(ctx->cipher_ctxs[i], aead_params)) {
    214      1.1  christos                 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    215      1.1  christos                 return 0;
    216      1.1  christos             }
    217      1.1  christos         }
    218      1.1  christos     }
    219      1.1  christos 
    220      1.1  christos     return 1;
    221      1.1  christos }
    222      1.1  christos 
    223      1.1  christos int fake_pipeline_aead_set_ctx_params(void *vctx, const OSSL_PARAM params[])
    224      1.1  christos {
    225      1.1  christos     CIPHER_PIPELINE_CTX *ctx = (CIPHER_PIPELINE_CTX *)vctx;
    226      1.1  christos     const OSSL_PARAM *p;
    227      1.1  christos     size_t taglen, i;
    228      1.1  christos     unsigned char **aead_tags = NULL;
    229      1.1  christos     OSSL_PARAM aead_params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
    230      1.1  christos 
    231      1.1  christos     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PIPELINE_AEAD_TAG);
    232      1.1  christos     if (p != NULL) {
    233      1.1  christos         if (!OSSL_PARAM_get_octet_ptr(p, (const void **)&aead_tags, &taglen)) {
    234      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    235      1.1  christos             return 0;
    236      1.1  christos         }
    237      1.1  christos         for (i = 0; i < ctx->numpipes; i++) {
    238      1.1  christos             aead_params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
    239  1.1.1.2  christos                 (void *)aead_tags[i],
    240  1.1.1.2  christos                 taglen);
    241      1.1  christos             if (!EVP_CIPHER_CTX_set_params(ctx->cipher_ctxs[i], aead_params)) {
    242      1.1  christos                 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    243      1.1  christos                 return 0;
    244      1.1  christos             }
    245      1.1  christos         }
    246      1.1  christos     }
    247      1.1  christos 
    248      1.1  christos     /* No other settable ctx param */
    249      1.1  christos     return 1;
    250      1.1  christos }
    251      1.1  christos 
    252  1.1.1.2  christos #define IMPLEMENT_aead_cipher_pipeline(alg, lc, UCMODE, flags, kbits, blkbits,       \
    253  1.1.1.2  christos     ivbits, ciphername)                                                              \
    254  1.1.1.2  christos     static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;         \
    255  1.1.1.2  christos     static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[])                \
    256  1.1.1.2  christos     {                                                                                \
    257  1.1.1.2  christos         return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,      \
    258  1.1.1.2  christos             flags, kbits, blkbits, ivbits);                                          \
    259  1.1.1.2  christos     }                                                                                \
    260  1.1.1.2  christos     static OSSL_FUNC_cipher_newctx_fn fake_pipeline_##alg##_##kbits##_##lc##_newctx; \
    261  1.1.1.2  christos     static void *fake_pipeline_##alg##_##kbits##_##lc##_newctx(void *provctx)        \
    262  1.1.1.2  christos     {                                                                                \
    263  1.1.1.2  christos         return fake_pipeline_newctx(provctx, ciphername, kbits, ivbits);             \
    264  1.1.1.2  christos     }                                                                                \
    265  1.1.1.2  christos     static const OSSL_DISPATCH fake_pipeline_##alg##kbits##lc##_functions[] = {      \
    266  1.1.1.2  christos         { OSSL_FUNC_CIPHER_NEWCTX,                                                   \
    267  1.1.1.2  christos             (void (*)(void))fake_pipeline_##alg##_##kbits##_##lc##_newctx },         \
    268  1.1.1.2  christos         { OSSL_FUNC_CIPHER_FREECTX,                                                  \
    269  1.1.1.2  christos             (void (*)(void))fake_pipeline_freectx },                                 \
    270  1.1.1.2  christos         { OSSL_FUNC_CIPHER_PIPELINE_ENCRYPT_INIT,                                    \
    271  1.1.1.2  christos             (void (*)(void))fake_pipeline_einit },                                   \
    272  1.1.1.2  christos         { OSSL_FUNC_CIPHER_PIPELINE_DECRYPT_INIT,                                    \
    273  1.1.1.2  christos             (void (*)(void))fake_pipeline_dinit },                                   \
    274  1.1.1.2  christos         { OSSL_FUNC_CIPHER_PIPELINE_UPDATE,                                          \
    275  1.1.1.2  christos             (void (*)(void))fake_pipeline_update },                                  \
    276  1.1.1.2  christos         { OSSL_FUNC_CIPHER_PIPELINE_FINAL,                                           \
    277  1.1.1.2  christos             (void (*)(void))fake_pipeline_final },                                   \
    278  1.1.1.2  christos         { OSSL_FUNC_CIPHER_GET_PARAMS,                                               \
    279  1.1.1.2  christos             (void (*)(void))alg##_##kbits##_##lc##_get_params },                     \
    280  1.1.1.2  christos         { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                           \
    281  1.1.1.2  christos             (void (*)(void))fake_pipeline_aead_get_ctx_params },                     \
    282  1.1.1.2  christos         { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                           \
    283  1.1.1.2  christos             (void (*)(void))fake_pipeline_aead_set_ctx_params },                     \
    284  1.1.1.2  christos         { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                          \
    285  1.1.1.2  christos             (void (*)(void))ossl_cipher_generic_gettable_params },                   \
    286  1.1.1.2  christos         { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                      \
    287  1.1.1.2  christos             (void (*)(void))fake_pipeline_aead_gettable_ctx_params },                \
    288  1.1.1.2  christos         { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                      \
    289  1.1.1.2  christos             (void (*)(void))fake_pipeline_aead_settable_ctx_params },                \
    290  1.1.1.2  christos         OSSL_DISPATCH_END                                                            \
    291      1.1  christos     }
    292      1.1  christos 
    293      1.1  christos IMPLEMENT_aead_cipher_pipeline(aes, gcm, GCM, AEAD_FLAGS, 256, 8, 96, "AES-256-GCM");
    294      1.1  christos 
    295      1.1  christos static const OSSL_ALGORITHM fake_ciphers[] = {
    296  1.1.1.2  christos     { "AES-256-GCM", "provider=fake-pipeline", fake_pipeline_aes256gcm_functions },
    297  1.1.1.2  christos     { NULL, NULL, NULL }
    298      1.1  christos };
    299      1.1  christos 
    300      1.1  christos static const OSSL_ALGORITHM *fake_pipeline_query(OSSL_PROVIDER *prov,
    301  1.1.1.2  christos     int operation_id,
    302  1.1.1.2  christos     int *no_cache)
    303      1.1  christos {
    304      1.1  christos     *no_cache = 0;
    305      1.1  christos     switch (operation_id) {
    306      1.1  christos     case OSSL_OP_CIPHER:
    307      1.1  christos         return fake_ciphers;
    308      1.1  christos     }
    309      1.1  christos     return NULL;
    310      1.1  christos }
    311      1.1  christos 
    312      1.1  christos /* Functions we provide to the core */
    313      1.1  christos static const OSSL_DISPATCH fake_pipeline_method[] = {
    314      1.1  christos     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free },
    315      1.1  christos     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fake_pipeline_query },
    316      1.1  christos     OSSL_DISPATCH_END
    317      1.1  christos };
    318      1.1  christos 
    319      1.1  christos static int fake_pipeline_provider_init(const OSSL_CORE_HANDLE *handle,
    320  1.1.1.2  christos     const OSSL_DISPATCH *in,
    321  1.1.1.2  christos     const OSSL_DISPATCH **out, void **provctx)
    322      1.1  christos {
    323      1.1  christos     if (!TEST_ptr(*provctx = OSSL_LIB_CTX_new()))
    324      1.1  christos         return 0;
    325      1.1  christos     *out = fake_pipeline_method;
    326      1.1  christos     return 1;
    327      1.1  christos }
    328      1.1  christos 
    329      1.1  christos OSSL_PROVIDER *fake_pipeline_start(OSSL_LIB_CTX *libctx)
    330      1.1  christos {
    331      1.1  christos     OSSL_PROVIDER *p;
    332      1.1  christos 
    333      1.1  christos     if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "fake-pipeline",
    334  1.1.1.2  christos             fake_pipeline_provider_init))
    335  1.1.1.2  christos         || !TEST_ptr(p = OSSL_PROVIDER_try_load(libctx, "fake-pipeline", 1)))
    336      1.1  christos         return NULL;
    337      1.1  christos 
    338      1.1  christos     return p;
    339      1.1  christos }
    340      1.1  christos 
    341      1.1  christos void fake_pipeline_finish(OSSL_PROVIDER *p)
    342      1.1  christos {
    343      1.1  christos     OSSL_PROVIDER_unload(p);
    344      1.1  christos }
    345