xref: /linux/include/crypto/aes-xts.h (revision d47db9bf50d28647689e6743ee93c45cb755ffc3)
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