1/* 2 * Copyright 2019-2022 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 <openssl/params.h> 11#include <openssl/core_dispatch.h> 12#include <openssl/core_names.h> 13#include <openssl/evp.h> 14#include "internal/cryptlib.h" 15#include "crypto/modes.h" 16 17# define MAXCHUNK ((size_t)1 << 30) 18# define MAXBITCHUNK ((size_t)1 << (sizeof(size_t) * 8 - 4)) 19 20#define GENERIC_BLOCK_SIZE 16 21#define IV_STATE_UNINITIALISED 0 /* initial state is not initialized */ 22#define IV_STATE_BUFFERED 1 /* iv has been copied to the iv buffer */ 23#define IV_STATE_COPIED 2 /* iv has been copied from the iv buffer */ 24#define IV_STATE_FINISHED 3 /* the iv has been used - so don't reuse it */ 25 26#define PROV_CIPHER_FUNC(type, name, args) typedef type (* OSSL_##name##_fn)args 27 28typedef struct prov_cipher_hw_st PROV_CIPHER_HW; 29typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; 30 31typedef int (PROV_CIPHER_HW_FN)(PROV_CIPHER_CTX *dat, unsigned char *out, 32 const unsigned char *in, size_t len); 33 34/* Internal flags that can be queried */ 35#define PROV_CIPHER_FLAG_AEAD 0x0001 36#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 37#define PROV_CIPHER_FLAG_CTS 0x0004 38#define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 39#define PROV_CIPHER_FLAG_RAND_KEY 0x0010 40/* Internal flags that are only used within the provider */ 41#define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 42#define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 43 44struct prov_cipher_ctx_st { 45 block128_f block; 46 union { 47 cbc128_f cbc; 48 ctr128_f ctr; 49 ecb128_f ecb; 50 } stream; 51 52 unsigned int mode; 53 size_t keylen; /* key size (in bytes) */ 54 size_t ivlen; 55 size_t blocksize; 56 size_t bufsz; /* Number of bytes in buf */ 57 unsigned int cts_mode; /* Use to set the type for CTS modes */ 58 unsigned int pad : 1; /* Whether padding should be used or not */ 59 unsigned int enc : 1; /* Set to 1 for encrypt, or 0 otherwise */ 60 unsigned int iv_set : 1; /* Set when the iv is copied to the iv/oiv buffers */ 61 unsigned int key_set : 1; /* Set when key is set on the context */ 62 unsigned int updated : 1; /* Set to 1 during update for one shot ciphers */ 63 unsigned int variable_keylength : 1; 64 unsigned int inverse_cipher : 1; /* set to 1 to use inverse cipher */ 65 unsigned int use_bits : 1; /* Set to 0 for cfb1 to use bits instead of bytes */ 66 67 unsigned int tlsversion; /* If TLS padding is in use the TLS version number */ 68 unsigned char *tlsmac; /* tls MAC extracted from the last record */ 69 int alloced; /* 70 * Whether the tlsmac data has been allocated or 71 * points into the user buffer. 72 */ 73 size_t tlsmacsize; /* Size of the TLS MAC */ 74 int removetlspad; /* Whether TLS padding should be removed or not */ 75 size_t removetlsfixed; /* 76 * Length of the fixed size data to remove when 77 * processing TLS data (equals mac size plus 78 * IV size if applicable) 79 */ 80 81 /* 82 * num contains the number of bytes of |iv| which are valid for modes that 83 * manage partial blocks themselves. 84 */ 85 unsigned int num; 86 87 /* The original value of the iv */ 88 unsigned char oiv[GENERIC_BLOCK_SIZE]; 89 /* Buffer of partial blocks processed via update calls */ 90 unsigned char buf[GENERIC_BLOCK_SIZE]; 91 unsigned char iv[GENERIC_BLOCK_SIZE]; 92 const PROV_CIPHER_HW *hw; /* hardware specific functions */ 93 const void *ks; /* Pointer to algorithm specific key data */ 94 OSSL_LIB_CTX *libctx; 95}; 96 97struct prov_cipher_hw_st { 98 int (*init)(PROV_CIPHER_CTX *dat, const uint8_t *key, size_t keylen); 99 PROV_CIPHER_HW_FN *cipher; 100 void (*copyctx)(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src); 101}; 102 103void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx); 104OSSL_FUNC_cipher_encrypt_init_fn ossl_cipher_generic_einit; 105OSSL_FUNC_cipher_decrypt_init_fn ossl_cipher_generic_dinit; 106OSSL_FUNC_cipher_update_fn ossl_cipher_generic_block_update; 107OSSL_FUNC_cipher_final_fn ossl_cipher_generic_block_final; 108OSSL_FUNC_cipher_update_fn ossl_cipher_generic_stream_update; 109OSSL_FUNC_cipher_final_fn ossl_cipher_generic_stream_final; 110OSSL_FUNC_cipher_cipher_fn ossl_cipher_generic_cipher; 111OSSL_FUNC_cipher_get_ctx_params_fn ossl_cipher_generic_get_ctx_params; 112OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_generic_set_ctx_params; 113OSSL_FUNC_cipher_gettable_params_fn ossl_cipher_generic_gettable_params; 114OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_generic_gettable_ctx_params; 115OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_generic_settable_ctx_params; 116OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_var_keylen_set_ctx_params; 117OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_var_keylen_settable_ctx_params; 118OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_aead_gettable_ctx_params; 119OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_aead_settable_ctx_params; 120 121int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, 122 uint64_t flags, 123 size_t kbits, size_t blkbits, size_t ivbits); 124void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, 125 size_t ivbits, unsigned int mode, 126 uint64_t flags, 127 const PROV_CIPHER_HW *hw, void *provctx); 128 129#define IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits,\ 130 blkbits, ivbits, typ) \ 131const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ 132 { OSSL_FUNC_CIPHER_NEWCTX, \ 133 (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ 134 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ 135 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ 136 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit }, \ 137 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit }, \ 138 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ 139 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ 140 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ 141 { OSSL_FUNC_CIPHER_GET_PARAMS, \ 142 (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ 143 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ 144 (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ 145 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ 146 (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ 147 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ 148 (void (*)(void))ossl_cipher_generic_gettable_params }, \ 149 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ 150 (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ 151 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ 152 (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ 153 { 0, NULL } \ 154}; 155 156#define IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, \ 157 kbits, blkbits, ivbits, typ) \ 158const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ 159 { OSSL_FUNC_CIPHER_NEWCTX, \ 160 (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ 161 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ 162 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ 163 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit },\ 164 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit },\ 165 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ 166 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ 167 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ 168 { OSSL_FUNC_CIPHER_GET_PARAMS, \ 169 (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ 170 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ 171 (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ 172 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ 173 (void (*)(void))ossl_cipher_var_keylen_set_ctx_params }, \ 174 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ 175 (void (*)(void))ossl_cipher_generic_gettable_params }, \ 176 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ 177 (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ 178 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ 179 (void (*)(void))ossl_cipher_var_keylen_settable_ctx_params }, \ 180 { 0, NULL } \ 181}; 182 183 184#define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \ 185 kbits, blkbits, ivbits, typ) \ 186static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ 187static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ 188{ \ 189 return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ 190 flags, kbits, blkbits, ivbits); \ 191} \ 192static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ 193static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ 194{ \ 195 PROV_##UCALG##_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\ 196 : NULL; \ 197 if (ctx != NULL) { \ 198 ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ 199 EVP_CIPH_##UCMODE##_MODE, flags, \ 200 ossl_prov_cipher_hw_##alg##_##lcmode(kbits),\ 201 provctx); \ 202 } \ 203 return ctx; \ 204} \ 205 206#define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 207 blkbits, ivbits, typ) \ 208IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 209 blkbits, ivbits, typ) \ 210IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 211 blkbits, ivbits, typ) 212 213#define IMPLEMENT_var_keylen_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 214 blkbits, ivbits, typ) \ 215IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 216 blkbits, ivbits, typ) \ 217IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 218 blkbits, ivbits, typ) 219 220PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cbc; 221PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ecb; 222PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ofb128; 223PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb128; 224PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb8; 225PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb1; 226PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ctr; 227PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cbc; 228PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb8; 229PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb128; 230PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128; 231#define ossl_cipher_hw_chunked_ecb ossl_cipher_hw_generic_ecb 232#define ossl_cipher_hw_chunked_ctr ossl_cipher_hw_generic_ctr 233#define ossl_cipher_hw_chunked_cfb1 ossl_cipher_hw_generic_cfb1 234 235#define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ 236static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ 237 unsigned char *out, \ 238 const unsigned char *in, size_t len) \ 239{ \ 240 int num = ctx->num; \ 241 KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \ 242 \ 243 while (len >= MAXCHUNK) { \ 244 FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, &num); \ 245 len -= MAXCHUNK; \ 246 in += MAXCHUNK; \ 247 out += MAXCHUNK; \ 248 } \ 249 if (len > 0) { \ 250 FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, &num); \ 251 } \ 252 ctx->num = num; \ 253 return 1; \ 254} 255 256#define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ 257static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ 258 unsigned char *out, \ 259 const unsigned char *in, size_t len) \ 260{ \ 261 size_t i, bl = ctx->blocksize; \ 262 KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \ 263 \ 264 if (len < bl) \ 265 return 1; \ 266 for (i = 0, len -= bl; i <= len; i += bl) \ 267 FUNC_PREFIX##_encrypt(in + i, out + i, key, ctx->enc); \ 268 return 1; \ 269} 270 271#define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ 272static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ 273 unsigned char *out, \ 274 const unsigned char *in, size_t len) \ 275{ \ 276 KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \ 277 \ 278 while (len >= MAXCHUNK) { \ 279 FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, ctx->enc); \ 280 len -= MAXCHUNK; \ 281 in += MAXCHUNK; \ 282 out += MAXCHUNK; \ 283 } \ 284 if (len > 0) \ 285 FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, ctx->enc); \ 286 return 1; \ 287} 288 289#define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ 290static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ 291 unsigned char *out, \ 292 const unsigned char *in, size_t len) \ 293{ \ 294 size_t chunk = MAXCHUNK; \ 295 KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks); \ 296 int num = ctx->num; \ 297 \ 298 if (len < chunk) \ 299 chunk = len; \ 300 while (len > 0 && len >= chunk) { \ 301 FUNC_PREFIX##_encrypt(in, out, (long)chunk, key, ctx->iv, &num, \ 302 ctx->enc); \ 303 len -= chunk; \ 304 in += chunk; \ 305 out += chunk; \ 306 if (len < chunk) \ 307 chunk = len; \ 308 } \ 309 ctx->num = num; \ 310 return 1; \ 311} 312 313#define IMPLEMENT_CIPHER_HW_COPYCTX(name, CTX_TYPE) \ 314static void name(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) \ 315{ \ 316 CTX_TYPE *sctx = (CTX_TYPE *)src; \ 317 CTX_TYPE *dctx = (CTX_TYPE *)dst; \ 318 \ 319 *dctx = *sctx; \ 320 dst->ks = &dctx->ks.ks; \ 321} 322 323#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \ 324static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \ 325 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \ 326 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \ 327 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \ 328 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \ 329 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \ 330 OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), 331 332#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \ 333 OSSL_PARAM_END \ 334}; \ 335const OSSL_PARAM * name##_gettable_ctx_params(ossl_unused void *cctx, \ 336 ossl_unused void *provctx) \ 337{ \ 338 return name##_known_gettable_ctx_params; \ 339} 340 341#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \ 342static const OSSL_PARAM name##_known_settable_ctx_params[] = { \ 343 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \ 344 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), 345#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \ 346 OSSL_PARAM_END \ 347}; \ 348const OSSL_PARAM * name##_settable_ctx_params(ossl_unused void *cctx, \ 349 ossl_unused void *provctx) \ 350{ \ 351 return name##_known_settable_ctx_params; \ 352} 353 354int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, 355 size_t ivlen); 356 357size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen, 358 size_t blocksize, 359 const unsigned char **in, size_t *inlen); 360int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, 361 size_t blocksize, 362 const unsigned char **in, size_t *inlen); 363