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 28 typedef struct prov_cipher_hw_st PROV_CIPHER_HW; 29 typedef struct prov_cipher_ctx_st PROV_CIPHER_CTX; 30 31 typedef 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 44 struct 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 97 struct 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 103 void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx); 104 OSSL_FUNC_cipher_encrypt_init_fn ossl_cipher_generic_einit; 105 OSSL_FUNC_cipher_decrypt_init_fn ossl_cipher_generic_dinit; 106 OSSL_FUNC_cipher_update_fn ossl_cipher_generic_block_update; 107 OSSL_FUNC_cipher_final_fn ossl_cipher_generic_block_final; 108 OSSL_FUNC_cipher_update_fn ossl_cipher_generic_stream_update; 109 OSSL_FUNC_cipher_final_fn ossl_cipher_generic_stream_final; 110 OSSL_FUNC_cipher_cipher_fn ossl_cipher_generic_cipher; 111 OSSL_FUNC_cipher_get_ctx_params_fn ossl_cipher_generic_get_ctx_params; 112 OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_generic_set_ctx_params; 113 OSSL_FUNC_cipher_gettable_params_fn ossl_cipher_generic_gettable_params; 114 OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_generic_gettable_ctx_params; 115 OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_generic_settable_ctx_params; 116 OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_var_keylen_set_ctx_params; 117 OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_var_keylen_settable_ctx_params; 118 OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_aead_gettable_ctx_params; 119 OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_aead_settable_ctx_params; 120 121 int 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); 124 void 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) \ 131 const 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) \ 158 const 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) \ 186 static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ 187 static 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 } \ 192 static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ 193 static 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) \ 208 IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 209 blkbits, ivbits, typ) \ 210 IMPLEMENT_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) \ 215 IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 216 blkbits, ivbits, typ) \ 217 IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \ 218 blkbits, ivbits, typ) 219 220 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cbc; 221 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ecb; 222 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ofb128; 223 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb128; 224 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb8; 225 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb1; 226 PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ctr; 227 PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cbc; 228 PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb8; 229 PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb128; 230 PROV_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) \ 236 static 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) \ 257 static 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) \ 272 static 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) \ 290 static 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) \ 314 static 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) \ 324 static 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 }; \ 335 const 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) \ 342 static 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 }; \ 348 const 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 354 int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, 355 size_t ivlen); 356 357 size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen, 358 size_t blocksize, 359 const unsigned char **in, size_t *inlen); 360 int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, 361 size_t blocksize, 362 const unsigned char **in, size_t *inlen); 363