1 2 /* 3 * Copyright 2019-2021 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 /*- 66 * Provider dispatch functions 67 */ 68 static int aes_xts_init(void *vctx, const unsigned char *key, size_t keylen, 69 const unsigned char *iv, size_t ivlen, 70 const OSSL_PARAM params[], int enc) 71 { 72 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)vctx; 73 PROV_CIPHER_CTX *ctx = &xctx->base; 74 75 if (!ossl_prov_is_running()) 76 return 0; 77 78 ctx->enc = enc; 79 80 if (iv != NULL) { 81 if (!ossl_cipher_generic_initiv(vctx, iv, ivlen)) 82 return 0; 83 } 84 if (key != NULL) { 85 if (keylen != ctx->keylen) { 86 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 87 return 0; 88 } 89 if (!aes_xts_check_keys_differ(key, keylen / 2, enc)) 90 return 0; 91 if (!ctx->hw->init(ctx, key, keylen)) 92 return 0; 93 } 94 return aes_xts_set_ctx_params(ctx, params); 95 } 96 97 static int aes_xts_einit(void *vctx, const unsigned char *key, size_t keylen, 98 const unsigned char *iv, size_t ivlen, 99 const OSSL_PARAM params[]) 100 { 101 return aes_xts_init(vctx, key, keylen, iv, ivlen, params, 1); 102 } 103 104 static int aes_xts_dinit(void *vctx, const unsigned char *key, size_t keylen, 105 const unsigned char *iv, size_t ivlen, 106 const OSSL_PARAM params[]) 107 { 108 return aes_xts_init(vctx, key, keylen, iv, ivlen, params, 0); 109 } 110 111 static void *aes_xts_newctx(void *provctx, unsigned int mode, uint64_t flags, 112 size_t kbits, size_t blkbits, size_t ivbits) 113 { 114 PROV_AES_XTS_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); 115 116 if (ctx != NULL) { 117 ossl_cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, 118 flags, ossl_prov_cipher_hw_aes_xts(kbits), 119 NULL); 120 } 121 return ctx; 122 } 123 124 static void aes_xts_freectx(void *vctx) 125 { 126 PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; 127 128 ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); 129 OPENSSL_clear_free(ctx, sizeof(*ctx)); 130 } 131 132 static void *aes_xts_dupctx(void *vctx) 133 { 134 PROV_AES_XTS_CTX *in = (PROV_AES_XTS_CTX *)vctx; 135 PROV_AES_XTS_CTX *ret = NULL; 136 137 if (!ossl_prov_is_running()) 138 return NULL; 139 140 if (in->xts.key1 != NULL) { 141 if (in->xts.key1 != &in->ks1) 142 return NULL; 143 } 144 if (in->xts.key2 != NULL) { 145 if (in->xts.key2 != &in->ks2) 146 return NULL; 147 } 148 ret = OPENSSL_malloc(sizeof(*ret)); 149 if (ret == NULL) { 150 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 151 return NULL; 152 } 153 in->base.hw->copyctx(&ret->base, &in->base); 154 return ret; 155 } 156 157 static int aes_xts_cipher(void *vctx, unsigned char *out, size_t *outl, 158 size_t outsize, const unsigned char *in, size_t inl) 159 { 160 PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; 161 162 if (!ossl_prov_is_running() 163 || ctx->xts.key1 == NULL 164 || ctx->xts.key2 == NULL 165 || !ctx->base.iv_set 166 || out == NULL 167 || in == NULL 168 || inl < AES_BLOCK_SIZE) 169 return 0; 170 171 /* 172 * Impose a limit of 2^20 blocks per data unit as specified by 173 * IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007 174 * indicated that this was a SHOULD NOT rather than a MUST NOT. 175 * NIST SP 800-38E mandates the same limit. 176 */ 177 if (inl > XTS_MAX_BLOCKS_PER_DATA_UNIT * AES_BLOCK_SIZE) { 178 ERR_raise(ERR_LIB_PROV, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE); 179 return 0; 180 } 181 182 if (ctx->stream != NULL) 183 (*ctx->stream)(in, out, inl, ctx->xts.key1, ctx->xts.key2, ctx->base.iv); 184 else if (CRYPTO_xts128_encrypt(&ctx->xts, ctx->base.iv, in, out, inl, 185 ctx->base.enc)) 186 return 0; 187 188 *outl = inl; 189 return 1; 190 } 191 192 static int aes_xts_stream_update(void *vctx, unsigned char *out, size_t *outl, 193 size_t outsize, const unsigned char *in, 194 size_t inl) 195 { 196 PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; 197 198 if (outsize < inl) { 199 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 200 return 0; 201 } 202 203 if (!aes_xts_cipher(ctx, out, outl, outsize, in, inl)) { 204 ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); 205 return 0; 206 } 207 208 return 1; 209 } 210 211 static int aes_xts_stream_final(void *vctx, unsigned char *out, size_t *outl, 212 size_t outsize) 213 { 214 if (!ossl_prov_is_running()) 215 return 0; 216 *outl = 0; 217 return 1; 218 } 219 220 static const OSSL_PARAM aes_xts_known_settable_ctx_params[] = { 221 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), 222 OSSL_PARAM_END 223 }; 224 225 static const OSSL_PARAM *aes_xts_settable_ctx_params(ossl_unused void *cctx, 226 ossl_unused void *provctx) 227 { 228 return aes_xts_known_settable_ctx_params; 229 } 230 231 static int aes_xts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 232 { 233 PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; 234 const OSSL_PARAM *p; 235 236 if (params == NULL) 237 return 1; 238 239 p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); 240 if (p != NULL) { 241 size_t keylen; 242 243 if (!OSSL_PARAM_get_size_t(p, &keylen)) { 244 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 245 return 0; 246 } 247 /* The key length can not be modified for xts mode */ 248 if (keylen != ctx->keylen) 249 return 0; 250 } 251 252 return 1; 253 } 254 255 #define IMPLEMENT_cipher(lcmode, UCMODE, kbits, flags) \ 256 static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \ 257 static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ 258 { \ 259 return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ 260 flags, 2 * kbits, AES_XTS_BLOCK_BITS, \ 261 AES_XTS_IV_BITS); \ 262 } \ 263 static OSSL_FUNC_cipher_newctx_fn aes_##kbits##_xts_newctx; \ 264 static void *aes_##kbits##_xts_newctx(void *provctx) \ 265 { \ 266 return aes_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, flags, 2 * kbits, \ 267 AES_XTS_BLOCK_BITS, AES_XTS_IV_BITS); \ 268 } \ 269 const OSSL_DISPATCH ossl_aes##kbits##xts_functions[] = { \ 270 { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_xts_newctx }, \ 271 { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_xts_einit }, \ 272 { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_xts_dinit }, \ 273 { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_xts_stream_update }, \ 274 { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_xts_stream_final }, \ 275 { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_xts_cipher }, \ 276 { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_xts_freectx }, \ 277 { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_xts_dupctx }, \ 278 { OSSL_FUNC_CIPHER_GET_PARAMS, \ 279 (void (*)(void))aes_##kbits##_##lcmode##_get_params }, \ 280 { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ 281 (void (*)(void))ossl_cipher_generic_gettable_params }, \ 282 { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ 283 (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ 284 { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ 285 (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ 286 { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ 287 (void (*)(void))aes_xts_set_ctx_params }, \ 288 { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ 289 (void (*)(void))aes_xts_settable_ctx_params }, \ 290 { 0, NULL } \ 291 } 292 293 IMPLEMENT_cipher(xts, XTS, 256, AES_XTS_FLAGS); 294 IMPLEMENT_cipher(xts, XTS, 128, AES_XTS_FLAGS); 295