Path: blob/main/crypto/openssl/providers/implementations/include/prov/ciphercommon.h
104826 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};192193#define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \194kbits, blkbits, ivbits, typ) \195static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \196static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \197{ \198return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \199flags, kbits, blkbits, ivbits); \200} \201static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \202static void *alg##_##kbits##_##lcmode##_newctx(void *provctx) \203{ \204PROV_##UCALG##_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \205: NULL; \206if (ctx != NULL) { \207ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \208EVP_CIPH_##UCMODE##_MODE, flags, \209ossl_prov_cipher_hw_##alg##_##lcmode(kbits), \210provctx); \211} \212return ctx; \213}214215#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \216blkbits, ivbits, typ) \217IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \218blkbits, ivbits, typ) \219IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \220blkbits, ivbits, typ)221222#define IMPLEMENT_var_keylen_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \223blkbits, ivbits, typ) \224IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \225blkbits, ivbits, typ) \226IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \227blkbits, ivbits, typ)228229PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cbc;230PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ecb;231PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ofb128;232PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb128;233PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb8;234PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb1;235PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ctr;236PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cbc;237PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb8;238PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb128;239PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128;240#define ossl_cipher_hw_chunked_ecb ossl_cipher_hw_generic_ecb241#define ossl_cipher_hw_chunked_ctr ossl_cipher_hw_generic_ctr242#define ossl_cipher_hw_chunked_cfb1 ossl_cipher_hw_generic_cfb1243244#define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \245static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \246unsigned char *out, \247const unsigned char *in, size_t len) \248{ \249int num = ctx->num; \250KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \251\252while (len >= MAXCHUNK) { \253FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, &num); \254len -= MAXCHUNK; \255in += MAXCHUNK; \256out += MAXCHUNK; \257} \258if (len > 0) { \259FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, &num); \260} \261ctx->num = num; \262return 1; \263}264265#define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \266static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \267unsigned char *out, \268const unsigned char *in, size_t len) \269{ \270size_t i, bl = ctx->blocksize; \271KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \272\273if (len < bl) \274return 1; \275for (i = 0, len -= bl; i <= len; i += bl) \276FUNC_PREFIX##_encrypt(in + i, out + i, key, ctx->enc); \277return 1; \278}279280#define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \281static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \282unsigned char *out, \283const unsigned char *in, size_t len) \284{ \285KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \286\287while (len >= MAXCHUNK) { \288FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, ctx->enc); \289len -= MAXCHUNK; \290in += MAXCHUNK; \291out += MAXCHUNK; \292} \293if (len > 0) \294FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, ctx->enc); \295return 1; \296}297298#define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \299static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \300unsigned char *out, \301const unsigned char *in, size_t len) \302{ \303size_t chunk = MAXCHUNK; \304KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \305int num = ctx->num; \306\307if (len < chunk) \308chunk = len; \309while (len > 0 && len >= chunk) { \310FUNC_PREFIX##_encrypt(in, out, (long)chunk, key, ctx->iv, &num, \311ctx->enc); \312len -= chunk; \313in += chunk; \314out += chunk; \315if (len < chunk) \316chunk = len; \317} \318ctx->num = num; \319return 1; \320}321322#define IMPLEMENT_CIPHER_HW_COPYCTX(name, CTX_TYPE) \323static void name(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) \324{ \325CTX_TYPE *sctx = (CTX_TYPE *)src; \326CTX_TYPE *dctx = (CTX_TYPE *)dst; \327\328*dctx = *sctx; \329dst->ks = &dctx->ks.ks; \330}331332#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \333static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \334OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \335OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \336OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \337OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \338OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \339OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0),340341#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \342OSSL_PARAM_END \343} \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} \358; \359const OSSL_PARAM *name##_settable_ctx_params(ossl_unused void *cctx, \360ossl_unused void *provctx) \361{ \362return name##_known_settable_ctx_params; \363}364365int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,366size_t ivlen);367368size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen,369size_t blocksize,370const unsigned char **in, size_t *inlen);371int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen,372size_t blocksize,373const unsigned char **in, size_t *inlen);374375#endif376377378