--- a/sys/crypto/cryptoapi/cryptoapi.c +++ b/sys/crypto/cryptoapi/cryptoapi.c @@ -410,21 +410,23 @@ } static inline void -aes_xts_reinit(struct aes_xts_ctx *ctx, const uint8_t *iv) +aes_xts_reinit(struct aes_xts_ctx *ctx, const uint8_t *iv, uint8_t *tweak) { -#if 0 /* * Prepare tweak as E_k2(IV). IV is specified as LE representation * of a 64-bit block number which we allow to be passed in directly. + * + * The tweak is built in a CALLER-SUPPLIED buffer: the session ctx + * may be shared by concurrent cryptoapi_cipher_crypt() calls (e.g. + * dm_target_crypt bio submission from several CPUs), and the XTS + * tweak mutates per data block, so a ctx->tweak field would race. */ - /* XXX: possibly use htole64? */ -#endif - memcpy(ctx->tweak, iv, AES_XTS_IV_LEN); + memcpy(tweak, iv, AES_XTS_IV_LEN); /* Last 64 bits of IV are always zero */ - bzero(ctx->tweak + AES_XTS_IV_LEN, AES_XTS_IV_LEN); + bzero(tweak + AES_XTS_IV_LEN, AES_XTS_IV_LEN); - rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak); + rijndael_encrypt(&ctx->key2, tweak, tweak); } static void @@ -432,11 +434,12 @@ bool encrypt) { uint8_t block[AES_XTS_BLOCK_LEN]; + uint8_t tweak[AES_XTS_BLOCK_LEN]; struct aes_xts_ctx *ctx = _ctx; - aes_xts_reinit(ctx, iv); + aes_xts_reinit(ctx, iv, tweak); - crypt_data_xts(&ctx->key1, data, datalen, ctx->tweak, + crypt_data_xts(&ctx->key1, data, datalen, tweak, encrypt ? rijndael_encrypt_wrap : rijndael_decrypt_wrap, block, AES_XTS_BLOCK_LEN, AES_XTS_ALPHA); } @@ -729,25 +732,16 @@ }; static inline void -twofish_xts_reinit(struct twofish_xts_ctx *ctx, const uint8_t *iv) +twofish_xts_reinit(struct twofish_xts_ctx *ctx, const uint8_t *iv, + uint8_t *tweak) { -#if 0 - u_int64_t blocknum; -#endif - -#if 0 - /* - * Prepare tweak as E_k2(IV). IV is specified as LE representation - * of a 64-bit block number which we allow to be passed in directly. - */ - /* XXX: possibly use htole64? */ -#endif - memcpy(ctx->tweak, iv, TWOFISH_XTS_IV_LEN); + /* tweak is per-call: see aes_xts_reinit() */ + memcpy(tweak, iv, TWOFISH_XTS_IV_LEN); /* Last 64 bits of IV are always zero */ - bzero(ctx->tweak + TWOFISH_XTS_IV_LEN, TWOFISH_XTS_IV_LEN); + bzero(tweak + TWOFISH_XTS_IV_LEN, TWOFISH_XTS_IV_LEN); - twofish_encrypt(&ctx->key2, ctx->tweak, ctx->tweak); + twofish_encrypt(&ctx->key2, tweak, tweak); } static int @@ -782,11 +776,12 @@ bool encrypt) { uint8_t block[TWOFISH_XTS_BLOCK_LEN]; + uint8_t tweak[TWOFISH_XTS_BLOCK_LEN]; struct twofish_xts_ctx *ctx = _ctx; - twofish_xts_reinit(ctx, iv); + twofish_xts_reinit(ctx, iv, tweak); - crypt_data_xts(&ctx->key1, data, datalen, ctx->tweak, + crypt_data_xts(&ctx->key1, data, datalen, tweak, encrypt ? twofish_encrypt_wrap : twofish_decrypt_wrap, block, TWOFISH_XTS_BLOCK_LEN, AES_XTS_ALPHA); } @@ -892,27 +887,16 @@ }; static inline void -serpent_xts_reinit(struct serpent_xts_ctx *ctx, const uint8_t *iv) +serpent_xts_reinit(struct serpent_xts_ctx *ctx, const uint8_t *iv, + uint8_t *tweak) { -#if 0 - u_int64_t blocknum; - u_int i; -#endif - -#if 0 - /* - * Prepare tweak as E_k2(IV). IV is specified as LE representation - * of a 64-bit block number which we allow to be passed in directly. - */ - /* XXX: possibly use htole64? */ -#endif - - memcpy(ctx->tweak, iv, SERPENT_XTS_IV_LEN); + /* tweak is per-call: see aes_xts_reinit() */ + memcpy(tweak, iv, SERPENT_XTS_IV_LEN); /* Last 64 bits of IV are always zero */ - bzero(ctx->tweak + SERPENT_XTS_IV_LEN, SERPENT_XTS_IV_LEN); + bzero(tweak + SERPENT_XTS_IV_LEN, SERPENT_XTS_IV_LEN); - serpent_encrypt(&ctx->key2, ctx->tweak, ctx->tweak); + serpent_encrypt(&ctx->key2, tweak, tweak); } static int @@ -947,11 +931,12 @@ bool encrypt) { uint8_t block[SERPENT_XTS_BLOCK_LEN]; + uint8_t tweak[SERPENT_XTS_BLOCK_LEN]; struct serpent_xts_ctx *ctx = _ctx; - serpent_xts_reinit(ctx, iv); + serpent_xts_reinit(ctx, iv, tweak); - crypt_data_xts(&ctx->key1, data, datalen, ctx->tweak, + crypt_data_xts(&ctx->key1, data, datalen, tweak, encrypt ? serpent_encrypt_wrap : serpent_decrypt_wrap, block, SERPENT_XTS_BLOCK_LEN, AES_XTS_ALPHA); }