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 */ 28static OSSL_FUNC_cipher_encrypt_init_fn aes_xts_einit; 29static OSSL_FUNC_cipher_decrypt_init_fn aes_xts_dinit; 30static OSSL_FUNC_cipher_update_fn aes_xts_stream_update; 31static OSSL_FUNC_cipher_final_fn aes_xts_stream_final; 32static OSSL_FUNC_cipher_cipher_fn aes_xts_cipher; 33static OSSL_FUNC_cipher_freectx_fn aes_xts_freectx; 34static OSSL_FUNC_cipher_dupctx_fn aes_xts_dupctx; 35static OSSL_FUNC_cipher_set_ctx_params_fn aes_xts_set_ctx_params; 36static 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 */ 54static 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 */ 68static 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 97static 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 104static 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 111static 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 124static 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 132static 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 157static 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 192static 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 211static 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 220static 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 225static 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 231static 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) \ 256static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \ 257static 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} \ 263static OSSL_FUNC_cipher_newctx_fn aes_##kbits##_xts_newctx; \ 264static 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} \ 269const 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 293IMPLEMENT_cipher(xts, XTS, 256, AES_XTS_FLAGS); 294IMPLEMENT_cipher(xts, XTS, 128, AES_XTS_FLAGS); 295