1 2 /* 3 * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. 4 * 5 * Licensed under the Apache License 2.0 (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11 /* 12 * AES low level APIs are deprecated for public use, but still ok for internal 13 * use where we're using them to implement the higher level EVP interface, as is 14 * the case here. 15 */ 16 #include "internal/deprecated.h" 17 18 #include <openssl/proverr.h> 19 #include "cipher_aes_xts.h" 20 #include "prov/implementations.h" 21 #include "prov/providercommon.h" 22 23 #define AES_XTS_FLAGS PROV_CIPHER_FLAG_CUSTOM_IV 24 #define AES_XTS_IV_BITS 128 25 #define AES_XTS_BLOCK_BITS 8 26 27 /* forward declarations */ 28 static OSSL_FUNC_cipher_encrypt_init_fn aes_xts_einit; 29 static OSSL_FUNC_cipher_decrypt_init_fn aes_xts_dinit; 30 static OSSL_FUNC_cipher_update_fn aes_xts_stream_update; 31 static OSSL_FUNC_cipher_final_fn aes_xts_stream_final; 32 static OSSL_FUNC_cipher_cipher_fn aes_xts_cipher; 33 static OSSL_FUNC_cipher_freectx_fn aes_xts_freectx; 34 static OSSL_FUNC_cipher_dupctx_fn aes_xts_dupctx; 35 static OSSL_FUNC_cipher_set_ctx_params_fn aes_xts_set_ctx_params; 36 static OSSL_FUNC_cipher_settable_ctx_params_fn aes_xts_settable_ctx_params; 37 38 /* 39 * Verify that the two keys are different. 40 * 41 * This addresses the vulnerability described in Rogaway's 42 * September 2004 paper: 43 * 44 * "Efficient Instantiations of Tweakable Blockciphers and 45 * Refinements to Modes OCB and PMAC". 46 * (http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf) 47 * 48 * FIPS 140-2 IG A.9 XTS-AES Key Generation Requirements states 49 * that: 50 * "The check for Key_1 != Key_2 shall be done at any place 51 * BEFORE using the keys in the XTS-AES algorithm to process 52 * data with them." 53 */ 54 static int aes_xts_check_keys_differ(const unsigned char *key, size_t bytes, 55 int enc) 56 { 57 if ((!ossl_aes_xts_allow_insecure_decrypt || enc) 58 && CRYPTO_memcmp(key, key + bytes, bytes) == 0) { 59 ERR_raise(ERR_LIB_PROV, PROV_R_XTS_DUPLICATED_KEYS); 60 return 0; 61 } 62 return 1; 63 } 64 65 #ifdef AES_XTS_S390X 66 # include "cipher_aes_xts_s390x.inc" 67 #endif 68 69 /*- 70 * Provider dispatch functions 71 */ 72 static int aes_xts_init(void *vctx, const unsigned char *key, size_t keylen, 73 const unsigned char *iv, size_t ivlen, 74 const OSSL_PARAM params[], int enc) 75 { 76 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)vctx; 77 PROV_CIPHER_CTX *ctx = &xctx->base; 78 79 if (!ossl_prov_is_running()) 80 return 0; 81 82 ctx->enc = enc; 83 84 if (iv != NULL) { 85 if (!ossl_cipher_generic_initiv(vctx, iv, ivlen)) 86 return 0; 87 } 88 if (key != NULL) { 89 if (keylen != ctx->keylen) { 90 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 91 return 0; 92 } 93 if (!aes_xts_check_keys_differ(key, keylen / 2, enc)) 94 return 0; 95 if (!ctx->hw->init(ctx, key, keylen)) 96 return 0; 97 } 98 return aes_xts_set_ctx_params(ctx, params); 99 } 100 101 static int aes_xts_einit(void *vctx, const unsigned char *key, size_t keylen, 102 const unsigned char *iv, size_t ivlen, 103 const OSSL_PARAM params[]) 104 { 105 #ifdef AES_XTS_S390X 106 if (s390x_aes_xts_einit(vctx, key, keylen, iv, ivlen, params) == 1) 107 return 1; 108 #endif 109 return aes_xts_init(vctx, key, keylen, iv, ivlen, params, 1); 110 } 111 112 static int aes_xts_dinit(void *vctx, const unsigned char *key, size_t keylen, 113 const unsigned char *iv, size_t ivlen, 114 const OSSL_PARAM params[]) 115 { 116 #ifdef AES_XTS_S390X 117 if (s390x_aes_xts_dinit(vctx, key, keylen, iv, ivlen, params) == 1) 118 return 1; 119 #endif 120 return aes_xts_init(vctx, key, keylen, iv, ivlen, params, 0); 121 } 122 123 static void *aes_xts_newctx(void *provctx, unsigned int mode, uint64_t flags, 124 size_t kbits, size_t blkbits, size_t ivbits) 125 { 126 PROV_AES_XTS_CTX *ctx; 127 128 if (!ossl_prov_is_running()) 129 return NULL; 130 131 ctx = OPENSSL_zalloc(sizeof(*ctx)); 132 if (ctx != NULL) { 133 ossl_cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, 134 flags, ossl_prov_cipher_hw_aes_xts(kbits), 135 NULL); 136 } 137 return ctx; 138 } 139 140 static void aes_xts_freectx(void *vctx) 141 { 142 PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; 143 144 ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); 145 OPENSSL_clear_free(ctx, sizeof(*ctx)); 146 } 147 148 static void *aes_xts_dupctx(void *vctx) 149 { 150 PROV_AES_XTS_CTX *in = (PROV_AES_XTS_CTX *)vctx; 151 PROV_AES_XTS_CTX *ret = NULL; 152 153 if (!ossl_prov_is_running()) 154 return NULL; 155 156 #ifdef AES_XTS_S390X 157 if (in->plat.s390x.fc) 158 return s390x_aes_xts_dupctx(vctx); 159 #endif 160 161 if (in->xts.key1 != NULL) { 162 if (in->xts.key1 != &in->ks1) 163 return NULL; 164 } 165 if (in->xts.key2 != NULL) { 166 if (in->xts.key2 != &in->ks2) 167 return NULL; 168 } 169 ret = OPENSSL_malloc(sizeof(*ret)); 170 if (ret == NULL) 171 return NULL; 172 in->base.hw->copyctx(&ret->base, &in->base); 173 return ret; 174 } 175 176 static int aes_xts_cipher(void *vctx, unsigned char *out, size_t *outl, 177 size_t outsize, const unsigned char *in, size_t inl) 178 { 179 PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; 180 181 #ifdef AES_XTS_S390X 182 if (ctx->plat.s390x.fc) 183 return s390x_aes_xts_cipher(vctx, out, outl, outsize, in, inl); 184 #endif 185 186 if (!ossl_prov_is_running() 187 || ctx->xts.key1 == NULL 188 || ctx->xts.key2 == NULL 189 || !ctx->base.iv_set 190 || out == NULL 191 || in == NULL 192 || inl < AES_BLOCK_SIZE) 193 return 0; 194 195 /* 196 * Impose a limit of 2^20 blocks per data unit as specified by 197 * IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007 198 * indicated that this was a SHOULD NOT rather than a MUST NOT. 199 * NIST SP 800-38E mandates the same limit. 200 */ 201 if (inl > XTS_MAX_BLOCKS_PER_DATA_UNIT * AES_BLOCK_SIZE) { 202 ERR_raise(ERR_LIB_PROV, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE); 203 return 0; 204 } 205 206 if (ctx->stream != NULL) 207 (*ctx->stream)(in, out, inl, ctx->xts.key1, ctx->xts.key2, ctx->base.iv); 208 else if (CRYPTO_xts128_encrypt(&ctx->xts, ctx->base.iv, in, out, inl, 209 ctx->base.enc)) 210 return 0; 211 212 *outl = inl; 213 return 1; 214 } 215 216 static int aes_xts_stream_update(void *vctx, unsigned char *out, size_t *outl, 217 size_t outsize, const unsigned char *in, 218 size_t inl) 219 { 220 PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; 221 222 if (outsize < inl) { 223 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 224 return 0; 225 } 226 227 if (!aes_xts_cipher(ctx, out, outl, outsize, in, inl)) { 228 ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); 229 return 0; 230 } 231 232 return 1; 233 } 234 235 static int aes_xts_stream_final(void *vctx, unsigned char *out, size_t *outl, 236 size_t outsize) 237 { 238 if (!ossl_prov_is_running()) 239 return 0; 240 *outl = 0; 241 return 1; 242 } 243 244 static const OSSL_PARAM aes_xts_known_settable_ctx_params[] = { 245 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), 246 OSSL_PARAM_END 247 }; 248 249 static const OSSL_PARAM *aes_xts_settable_ctx_params(ossl_unused void *cctx, 250 ossl_unused void *provctx) 251 { 252 return aes_xts_known_settable_ctx_params; 253 } 254 255 static int aes_xts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 256 { 257 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 258 const OSSL_PARAM *p; 259 260 if (ossl_param_is_empty(params)) 261 return 1; 262 263 p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); 264 if (p != NULL) { 265 size_t keylen; 266 267 if (!OSSL_PARAM_get_size_t(p, &keylen)) { 268 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 269 return 0; 270 } 271 /* The key length can not be modified for xts mode */ 272 if (keylen != ctx->keylen) 273 return 0; 274 } 275 276 return 1; 277 } 278 279 #define IMPLEMENT_cipher(lcmode, UCMODE, kbits, flags) \ 280 static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \ 281 static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ 282 { \ 283 return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ 284 flags, 2 * kbits, AES_XTS_BLOCK_BITS, \ 285 AES_XTS_IV_BITS); \ 286 } \ 287 static OSSL_FUNC_cipher_newctx_fn aes_##kbits##_xts_newctx; \ 288 static void *aes_##kbits##_xts_newctx(void *provctx) \ 289 { \ 290 return aes_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, flags, 2 * kbits, \ 291 AES_XTS_BLOCK_BITS, AES_XTS_IV_BITS); \ 292 } \ 293 const OSSL_DISPATCH ossl_aes##kbits##xts_functions[] = { \ 294 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_xts_newctx }, \ 295 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_xts_einit }, \ 296 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_xts_dinit }, \ 297 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_xts_stream_update }, \ 298 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_xts_stream_final }, \ 299 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_xts_cipher }, \ 300 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_xts_freectx }, \ 301 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_xts_dupctx }, \ 302 { OSSL_FUNC_CIPHER_GET_PARAMS, \ 303 (void (*)(void))aes_##kbits##_##lcmode##_get_params }, \ 304 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ 305 (void (*)(void))ossl_cipher_generic_gettable_params }, \ 306 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ 307 (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ 308 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ 309 (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ 310 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ 311 (void (*)(void))aes_xts_set_ctx_params }, \ 312 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ 313 (void (*)(void))aes_xts_settable_ctx_params }, \ 314 OSSL_DISPATCH_END \ 315 } 316 317 IMPLEMENT_cipher(xts, XTS, 256, AES_XTS_FLAGS); 318 IMPLEMENT_cipher(xts, XTS, 128, AES_XTS_FLAGS); 319