1*de9cccc5SEric Biggers /* SPDX-License-Identifier: GPL-2.0 */ 2*de9cccc5SEric Biggers /* 3*de9cccc5SEric Biggers * AES-XTS unauthenticated encryption and decryption 4*de9cccc5SEric Biggers * 5*de9cccc5SEric Biggers * Copyright 2026 Google LLC 6*de9cccc5SEric Biggers */ 7*de9cccc5SEric Biggers #ifndef _CRYPTO_AES_XTS_H 8*de9cccc5SEric Biggers #define _CRYPTO_AES_XTS_H 9*de9cccc5SEric Biggers 10*de9cccc5SEric Biggers #include <crypto/aes.h> 11*de9cccc5SEric Biggers #include <crypto/xts.h> 12*de9cccc5SEric Biggers 13*de9cccc5SEric Biggers /** 14*de9cccc5SEric Biggers * struct aes_xts_key - A key prepared for AES-XTS encryption and decryption 15*de9cccc5SEric Biggers * 16*de9cccc5SEric Biggers * Note that (depending on the architecture) this typically is around 768 bytes, 17*de9cccc5SEric Biggers * which makes it a bit too large to allocate on the stack in most cases. 18*de9cccc5SEric Biggers */ 19*de9cccc5SEric Biggers struct aes_xts_key { 20*de9cccc5SEric Biggers /* private: */ 21*de9cccc5SEric Biggers struct aes_key main_key; 22*de9cccc5SEric Biggers struct aes_enckey tweak_key; 23*de9cccc5SEric Biggers }; 24*de9cccc5SEric Biggers 25*de9cccc5SEric Biggers /** 26*de9cccc5SEric Biggers * aes_xts_preparekey() - Prepare a key for AES-XTS encryption and decryption 27*de9cccc5SEric Biggers * @key: (output) The key structure to initialize 28*de9cccc5SEric Biggers * @in_key: The raw AES-XTS key 29*de9cccc5SEric Biggers * @key_len: Length of the raw key in bytes 30*de9cccc5SEric Biggers * @flags: Optional flag XTS_FORBID_WEAK_KEYS to forbid keys whose two halves 31*de9cccc5SEric Biggers * are the same. 32*de9cccc5SEric Biggers * 33*de9cccc5SEric Biggers * Users should use memzero_explicit() to zeroize the key struct at the end of 34*de9cccc5SEric Biggers * its lifetime. (But if this function fails, zeroization is unnecessary.) 35*de9cccc5SEric Biggers * 36*de9cccc5SEric Biggers * Context: Any context. 37*de9cccc5SEric Biggers * Return: 38*de9cccc5SEric Biggers * * 0 on success 39*de9cccc5SEric Biggers * * -EINVAL if the key is rejected because its length isn't 32, 64, or (when 40*de9cccc5SEric Biggers * FIPS mode isn't enabled) 48; or because its two halves are the same and 41*de9cccc5SEric Biggers * either XTS_FORBID_WEAK_KEYS is given or FIPS mode is enabled. 42*de9cccc5SEric Biggers */ 43*de9cccc5SEric Biggers int __must_check aes_xts_preparekey(struct aes_xts_key *key, const u8 *in_key, 44*de9cccc5SEric Biggers size_t key_len, int flags); 45*de9cccc5SEric Biggers 46*de9cccc5SEric Biggers /** 47*de9cccc5SEric Biggers * aes_xts_encrypt() - Encrypt data using AES-XTS 48*de9cccc5SEric Biggers * @dst: The destination buffer. Can be in-place or out-of-place. For other 49*de9cccc5SEric Biggers * overlaps the behavior is unspecified. 50*de9cccc5SEric Biggers * @src: The source data 51*de9cccc5SEric Biggers * @len: Number of bytes to encrypt. On non-final calls it must be a nonzero 52*de9cccc5SEric Biggers * multiple of AES_BLOCK_SIZE. On the final call it can be any value >= 53*de9cccc5SEric Biggers * AES_BLOCK_SIZE, i.e. ciphertext stealing is supported. 54*de9cccc5SEric Biggers * @tweak: The tweak. It is updated with the next value, unless @len isn't a 55*de9cccc5SEric Biggers * multiple of AES_BLOCK_SIZE in which case the value is unspecified. 56*de9cccc5SEric Biggers * @key: The key, already prepared using aes_xts_preparekey() 57*de9cccc5SEric Biggers * @cont: %false to begin encrypting a new message (do the tweak encryption); 58*de9cccc5SEric Biggers * %true to continue encrypting a message (skip tweak encryption) 59*de9cccc5SEric Biggers * 60*de9cccc5SEric Biggers * This supports both one-shot and incremental encryption. On the first call, 61*de9cccc5SEric Biggers * pass @cont = %false. On any later calls, pass @cont = %true and the updated 62*de9cccc5SEric Biggers * @tweak; all earlier @len must have been multiples of AES_BLOCK_SIZE. 63*de9cccc5SEric Biggers * 64*de9cccc5SEric Biggers * Context: Any context. 65*de9cccc5SEric Biggers */ 66*de9cccc5SEric Biggers void aes_xts_encrypt(u8 *dst, const u8 *src, size_t len, 67*de9cccc5SEric Biggers u8 tweak[at_least AES_BLOCK_SIZE], 68*de9cccc5SEric Biggers const struct aes_xts_key *key, bool cont); 69*de9cccc5SEric Biggers 70*de9cccc5SEric Biggers /** 71*de9cccc5SEric Biggers * aes_xts_decrypt() - Decrypt data using AES-XTS 72*de9cccc5SEric Biggers * @dst: The destination buffer. Can be in-place or out-of-place. For other 73*de9cccc5SEric Biggers * overlaps the behavior is unspecified. 74*de9cccc5SEric Biggers * @src: The source data 75*de9cccc5SEric Biggers * @len: Number of bytes to decrypt. On non-final calls it must be a nonzero 76*de9cccc5SEric Biggers * multiple of AES_BLOCK_SIZE. On the final call it can be any value >= 77*de9cccc5SEric Biggers * AES_BLOCK_SIZE, i.e. ciphertext stealing is supported. 78*de9cccc5SEric Biggers * @tweak: The tweak. It is updated with the next value, unless @len isn't a 79*de9cccc5SEric Biggers * multiple of AES_BLOCK_SIZE in which case the value is unspecified. 80*de9cccc5SEric Biggers * @key: The key, already prepared using aes_xts_preparekey() 81*de9cccc5SEric Biggers * @cont: %false to begin decrypting a new message (do the tweak encryption); 82*de9cccc5SEric Biggers * %true to continue decrypting a message (skip tweak encryption) 83*de9cccc5SEric Biggers * 84*de9cccc5SEric Biggers * This supports both one-shot and incremental decryption. On the first call, 85*de9cccc5SEric Biggers * pass @cont = %false. On any later calls, pass @cont = %true and the updated 86*de9cccc5SEric Biggers * @tweak; all earlier @len must have been multiples of AES_BLOCK_SIZE. 87*de9cccc5SEric Biggers * 88*de9cccc5SEric Biggers * Context: Any context. 89*de9cccc5SEric Biggers */ 90*de9cccc5SEric Biggers void aes_xts_decrypt(u8 *dst, const u8 *src, size_t len, 91*de9cccc5SEric Biggers u8 tweak[at_least AES_BLOCK_SIZE], 92*de9cccc5SEric Biggers const struct aes_xts_key *key, bool cont); 93*de9cccc5SEric Biggers 94*de9cccc5SEric Biggers #endif /* _CRYPTO_AES_XTS_H */ 95