Path: blob/main/crypto/openssl/providers/implementations/include/prov/ciphercommon.h
48534 views
/*1* Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#ifndef OSSL_PROV_CIPHERCOMMON_H10# define OSSL_PROV_CIPHERCOMMON_H11# pragma once1213# include <openssl/params.h>14# include <openssl/core_dispatch.h>15# include <openssl/core_names.h>16# include <openssl/evp.h>17# include "internal/cryptlib.h"18# include "crypto/modes.h"1920# define MAXCHUNK ((size_t)1 << 30)21# define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4))2223# define GENERIC_BLOCK_SIZE 1624# define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */25# define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */26# define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */27# define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */2829# define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args3031typedef struct prov_cipher_hw_st PROV_CIPHER_HW;32typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX;3334typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out,35const unsigned char *in, size_t len);3637/* Internal flags that can be queried */38# define PROV_CIPHER_FLAG_AEAD 0x000139# define PROV_CIPHER_FLAG_CUSTOM_IV 0x000240# define PROV_CIPHER_FLAG_CTS 0x000441# define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x000842# define PROV_CIPHER_FLAG_RAND_KEY 0x001043/* Internal flags that are only used within the provider */44# define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x010045# define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x02004647struct prov_cipher_ctx_st {48/* place buffer at the beginning for memory alignment */49/* The original value of the iv */50unsigned char oiv[GENERIC_BLOCK_SIZE];51/* Buffer of partial blocks processed via update calls */52unsigned char buf[GENERIC_BLOCK_SIZE];53unsigned char iv[GENERIC_BLOCK_SIZE];5455block128_f block;56union {57cbc128_f cbc;58ctr128_f ctr;59ecb128_f ecb;60} stream;6162unsigned int mode;63size_t keylen; /* key size (in bytes) */64size_t ivlen;65size_t blocksize;66size_t bufsz; /* Number of bytes in buf */67unsigned int cts_mode; /* Use to set the type for CTS modes */68unsigned int pad : 1; /* Whether padding should be used or not */69unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */70unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */71unsigned int key_set : 1; /* Set when key is set on the context */72unsigned int updated : 1; /* Set to 1 during update for one shot ciphers */73unsigned int variable_keylength : 1;74unsigned int inverse_cipher : 1; /* set to 1 to use inverse cipher */75unsigned int use_bits : 1; /* Set to 0 for cfb1 to use bits instead of bytes */7677unsigned int tlsversion; /* If TLS padding is in use the TLS version number */78unsigned char *tlsmac; /* tls MAC extracted from the last record */79int alloced; /*80* Whether the tlsmac data has been allocated or81* points into the user buffer.82*/83size_t tlsmacsize; /* Size of the TLS MAC */84int removetlspad; /* Whether TLS padding should be removed or not */85size_t removetlsfixed; /*86* Length of the fixed size data to remove when87* processing TLS data (equals mac size plus88* IV size if applicable)89*/9091/*92* num contains the number of bytes of |iv| which are valid for modes that93* manage partial blocks themselves.94*/95unsigned int num;96const PROV_CIPHER_HW *hw; /* hardware specific functions */97const void *ks; /* Pointer to algorithm specific key data */98OSSL_LIB_CTX *libctx;99};100101struct prov_cipher_hw_st {102int (*init)(PROV_CIPHER_CTX *dat, const uint8_t *key, size_t keylen);103PROV_CIPHER_HW_FN *cipher;104void (*copyctx)(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src);105};106107void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx);108OSSL_FUNC_cipher_encrypt_init_fn ossl_cipher_generic_einit;109OSSL_FUNC_cipher_decrypt_init_fn ossl_cipher_generic_dinit;110OSSL_FUNC_cipher_update_fn ossl_cipher_generic_block_update;111OSSL_FUNC_cipher_final_fn ossl_cipher_generic_block_final;112OSSL_FUNC_cipher_update_fn ossl_cipher_generic_stream_update;113OSSL_FUNC_cipher_final_fn ossl_cipher_generic_stream_final;114OSSL_FUNC_cipher_cipher_fn ossl_cipher_generic_cipher;115OSSL_FUNC_cipher_get_ctx_params_fn ossl_cipher_generic_get_ctx_params;116OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_generic_set_ctx_params;117OSSL_FUNC_cipher_gettable_params_fn ossl_cipher_generic_gettable_params;118OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_generic_gettable_ctx_params;119OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_generic_settable_ctx_params;120OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_var_keylen_set_ctx_params;121OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_var_keylen_settable_ctx_params;122OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_aead_gettable_ctx_params;123OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_aead_settable_ctx_params;124OSSL_FUNC_cipher_encrypt_skey_init_fn ossl_cipher_generic_skey_einit;125OSSL_FUNC_cipher_decrypt_skey_init_fn ossl_cipher_generic_skey_dinit;126127int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,128uint64_t flags,129size_t kbits, size_t blkbits, size_t ivbits);130void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,131size_t ivbits, unsigned int mode,132uint64_t flags,133const PROV_CIPHER_HW *hw, void *provctx);134135# define IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits,\136blkbits, ivbits, typ) \137const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \138{ OSSL_FUNC_CIPHER_NEWCTX, \139(void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \140{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \141{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \142{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit }, \143{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit }, \144{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\145{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \146{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \147{ OSSL_FUNC_CIPHER_GET_PARAMS, \148(void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \149{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \150(void (*)(void))ossl_cipher_generic_get_ctx_params }, \151{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \152(void (*)(void))ossl_cipher_generic_set_ctx_params }, \153{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \154(void (*)(void))ossl_cipher_generic_gettable_params }, \155{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \156(void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \157{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \158(void (*)(void))ossl_cipher_generic_settable_ctx_params }, \159{ OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT, (void (*)(void))ossl_cipher_generic_skey_einit },\160{ OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT, (void (*)(void))ossl_cipher_generic_skey_dinit },\161OSSL_DISPATCH_END \162};163164# define IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, \165kbits, blkbits, ivbits, typ) \166const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \167{ OSSL_FUNC_CIPHER_NEWCTX, \168(void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \169{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \170{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \171{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit },\172{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit },\173{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\174{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \175{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \176{ OSSL_FUNC_CIPHER_GET_PARAMS, \177(void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \178{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \179(void (*)(void))ossl_cipher_generic_get_ctx_params }, \180{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \181(void (*)(void))ossl_cipher_var_keylen_set_ctx_params }, \182{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \183(void (*)(void))ossl_cipher_generic_gettable_params }, \184{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \185(void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \186{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \187(void (*)(void))ossl_cipher_var_keylen_settable_ctx_params }, \188{ OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT, (void (*)(void))ossl_cipher_generic_skey_einit },\189{ OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT, (void (*)(void))ossl_cipher_generic_skey_dinit },\190OSSL_DISPATCH_END \191};192193194# define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \195kbits, blkbits, ivbits, typ) \196static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \197static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \198{ \199return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \200flags, kbits, blkbits, ivbits); \201} \202static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \203static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \204{ \205PROV_##UCALG##_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\206: NULL; \207if (ctx != NULL) { \208ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \209EVP_CIPH_##UCMODE##_MODE, flags, \210ossl_prov_cipher_hw_##alg##_##lcmode(kbits),\211provctx); \212} \213return ctx; \214} \215216# define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \217blkbits, ivbits, typ) \218IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \219blkbits, ivbits, typ) \220IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \221blkbits, ivbits, typ)222223# define IMPLEMENT_var_keylen_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \224blkbits, ivbits, typ) \225IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \226blkbits, ivbits, typ) \227IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \228blkbits, ivbits, typ)229230PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cbc;231PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ecb;232PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ofb128;233PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb128;234PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb8;235PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb1;236PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ctr;237PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cbc;238PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb8;239PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb128;240PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128;241# define ossl_cipher_hw_chunked_ecb ossl_cipher_hw_generic_ecb242# define ossl_cipher_hw_chunked_ctr ossl_cipher_hw_generic_ctr243# define ossl_cipher_hw_chunked_cfb1 ossl_cipher_hw_generic_cfb1244245# define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \246static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \247unsigned char *out, \248const unsigned char *in, size_t len) \249{ \250int num = ctx->num; \251KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \252\253while (len >= MAXCHUNK) { \254FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, &num); \255len -= MAXCHUNK; \256in += MAXCHUNK; \257out += MAXCHUNK; \258} \259if (len > 0) { \260FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, &num); \261} \262ctx->num = num; \263return 1; \264}265266# define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \267static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \268unsigned char *out, \269const unsigned char *in, size_t len) \270{ \271size_t i, bl = ctx->blocksize; \272KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \273\274if (len < bl) \275return 1; \276for (i = 0, len -= bl; i <= len; i += bl) \277FUNC_PREFIX##_encrypt(in + i, out + i, key, ctx->enc); \278return 1; \279}280281# define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \282static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \283unsigned char *out, \284const unsigned char *in, size_t len) \285{ \286KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \287\288while (len >= MAXCHUNK) { \289FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, ctx->enc); \290len -= MAXCHUNK; \291in += MAXCHUNK; \292out += MAXCHUNK; \293} \294if (len > 0) \295FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, ctx->enc); \296return 1; \297}298299# define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \300static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \301unsigned char *out, \302const unsigned char *in, size_t len) \303{ \304size_t chunk = MAXCHUNK; \305KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \306int num = ctx->num; \307\308if (len < chunk) \309chunk = len; \310while (len > 0 && len >= chunk) { \311FUNC_PREFIX##_encrypt(in, out, (long)chunk, key, ctx->iv, &num, \312ctx->enc); \313len -= chunk; \314in += chunk; \315out += chunk; \316if (len < chunk) \317chunk = len; \318} \319ctx->num = num; \320return 1; \321}322323# define IMPLEMENT_CIPHER_HW_COPYCTX(name, CTX_TYPE) \324static void name(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) \325{ \326CTX_TYPE *sctx = (CTX_TYPE *)src; \327CTX_TYPE *dctx = (CTX_TYPE *)dst; \328\329*dctx = *sctx; \330dst->ks = &dctx->ks.ks; \331}332333# define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \334static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \335OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \336OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \337OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \338OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \339OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \340OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),341342# define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \343OSSL_PARAM_END \344}; \345const OSSL_PARAM * name##_gettable_ctx_params(ossl_unused void *cctx, \346ossl_unused void *provctx) \347{ \348return name##_known_gettable_ctx_params; \349}350351# define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \352static const OSSL_PARAM name##_known_settable_ctx_params[] = { \353OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \354OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),355# define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \356OSSL_PARAM_END \357}; \358const OSSL_PARAM * name##_settable_ctx_params(ossl_unused void *cctx, \359ossl_unused void *provctx) \360{ \361return name##_known_settable_ctx_params; \362}363364int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,365size_t ivlen);366367size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen,368size_t blocksize,369const unsigned char **in, size_t *inlen);370int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen,371size_t blocksize,372const unsigned char **in, size_t *inlen);373374#endif375376377