xref: /linux/include/crypto/aes-ccm.h (revision 59e6295fac26b8e85c1ea859cdd89fa1e47519d7)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * AES-CCM authenticated encryption and decryption
4  *
5  * Copyright 2026 Google LLC
6  */
7 #ifndef _CRYPTO_AES_CCM_H
8 #define _CRYPTO_AES_CCM_H
9 
10 #include <crypto/aes.h>
11 
12 /**
13  * struct aes_ccm_key - A key prepared for AES-CCM encryption and decryption
14  */
15 struct aes_ccm_key {
16 	/* private: */
17 	struct aes_enckey aes;
18 	size_t authtag_len; /* Length of authentication tags in bytes */
19 };
20 
21 /**
22  * struct aes_ccm_ctx - Context for incrementally en/decrypting a message
23  */
24 struct aes_ccm_ctx {
25 	/* private: */
26 	/*
27 	 * Pointer to the key, which is assumed to live at least as long as this
28 	 * struct.
29 	 */
30 	const struct aes_ccm_key *key;
31 	/*
32 	 * The current CBC-MAC chaining value.  When not on a block boundary,
33 	 * the partial block has been XOR'ed into this.  The number of partial
34 	 * bytes is 'partial_len'.
35 	 */
36 	u8 mac[AES_BLOCK_SIZE] __aligned(__alignof__(__be64));
37 	/* The current counter, a 128-bit big endian value */
38 	u8 ctr[AES_BLOCK_SIZE] __aligned(__alignof__(__be64));
39 	/* Buffered keystream for partial block updates */
40 	u8 keystream[AES_BLOCK_SIZE] __aligned(__alignof__(__be64));
41 	/* Encrypted counter of 0.  This gets XOR'ed with the tag at the end. */
42 	u8 s0[AES_BLOCK_SIZE] __aligned(__alignof__(__be64));
43 	/* Number of associated data bytes remaining to be provided */
44 	u64 ad_remaining;
45 	/* Number of en/decrypted data bytes remaining to be provided */
46 	u64 data_remaining;
47 	/* Current partial block length, 0 <= partial_len < AES_BLOCK_SIZE */
48 	u32 partial_len;
49 	/* True if associated data padding has been done */
50 	bool ad_padded;
51 };
52 
53 /**
54  * aes_ccm_preparekey() - Prepare a key for AES-CCM encryption and decryption
55  * @key: (output) The key structure to initialize
56  * @in_key: The raw AES-CCM key
57  * @key_len: Length of the raw key in bytes: 16, 24, or 32
58  * @authtag_len: Length of the authentication tag in bytes:
59  *		 4, 6, 8, 10, 12, 14, or 16.  16 is recommended.
60  *
61  * Users should use memzero_explicit() to zeroize the key struct at the end of
62  * its lifetime.  (But if this function fails, zeroization is unnecessary.)
63  *
64  * Context: Any context.
65  * Return:
66  * * 0 on success
67  * * -EINVAL if either of the lengths is invalid
68  */
69 int __must_check aes_ccm_preparekey(struct aes_ccm_key *key, const u8 *in_key,
70 				    size_t key_len, size_t authtag_len);
71 
72 /**
73  * aes_ccm_encrypt() - Encrypt a message with AES-CCM
74  * @dst: The destination ciphertext data.  Can be in-place or out-of-place.
75  *	 For other overlaps the behavior is unspecified.
76  * @src: The source plaintext data
77  * @data_len: Length of plaintext in bytes (and ciphertext excluding the tag):
78  *	      at most 2^(120 - (8 * @nonce_len)) - 1
79  * @authtag: The output authentication tag.  Length is the authtag_len that was
80  *	     passed to aes_ccm_preparekey().  Usually protocols using AES-CCM
81  *	     put the tag at the end of the ciphertext, in which case this should
82  *	     be set to @dst + @data_len and @dst must have room for the tag.
83  * @ad: The associated data
84  * @ad_len: Length of associated data in bytes
85  * @nonce: The nonce.  All (key, nonce) pairs used MUST be distinct.
86  * @nonce_len: Length of the nonce in bytes: between 7 and 13 inclusive
87  * @key: The key, already prepared using aes_ccm_preparekey()
88  *
89  * Context: Any context.
90  * Return:
91  * * 0 on success
92  * * -EINVAL if @nonce_len is invalid
93  * * -EOVERFLOW if @data_len is too large for the selected @nonce_len
94  */
95 int __must_check aes_ccm_encrypt(u8 *dst, const u8 *src, size_t data_len,
96 				 u8 *authtag, const u8 *ad, size_t ad_len,
97 				 const u8 *nonce, size_t nonce_len,
98 				 const struct aes_ccm_key *key);
99 
100 /**
101  * aes_ccm_decrypt() - Decrypt a message with AES-CCM
102  * @dst: The destination plaintext data.  Can be in-place or out-of-place.
103  *	 For other overlaps the behavior is unspecified.
104  * @src: The source ciphertext data
105  * @data_len: Length of plaintext in bytes (and ciphertext excluding the tag):
106  *	      at most 2^(120 - (8 * @nonce_len)) - 1
107  * @authtag: The stored authentication tag.  Length is the authtag_len that was
108  *	     passed to aes_ccm_preparekey().  Usually protocols using AES-CCM
109  *	     put the tag at the end of the ciphertext, in which case this should
110  *	     be set to @src + @data_len and @src must have room for the tag.
111  * @ad: The associated data
112  * @ad_len: Length of associated data in bytes
113  * @nonce: The nonce
114  * @nonce_len: Length of the nonce in bytes: between 7 and 13 inclusive
115  * @key: The key, already prepared using aes_ccm_preparekey()
116  *
117  * Context: Any context.
118  * Return:
119  * * 0 on success.  This is the only case where any decrypted or associated data
120  *   can be used.
121  * * -EBADMSG if the message is inauthentic
122  * * -EINVAL if @nonce_len is invalid
123  * * -EOVERFLOW if @data_len is too large for the selected @nonce_len
124  */
125 int __must_check aes_ccm_decrypt(u8 *dst, const u8 *src, size_t data_len,
126 				 const u8 *authtag, const u8 *ad, size_t ad_len,
127 				 const u8 *nonce, size_t nonce_len,
128 				 const struct aes_ccm_key *key);
129 
130 /**
131  * aes_ccm_init() - Initialize context for incremental AES-CCM encryption or
132  *		    decryption
133  * @ctx: The context to initialize
134  * @data_len: Length of the en/decrypted data that will be provided in bytes:
135  *	      at most 2^(120 - (8 * @nonce_len)) - 1
136  * @ad_len: Length of the associated data that will be provided in bytes
137  * @nonce: The nonce.  All (key, nonce) pairs used for encryption MUST be
138  *	   distinct.
139  * @nonce_len: Length of the nonce in bytes: between 7 and 13 inclusive
140  * @key: The key, already prepared using aes_ccm_preparekey().  Note that a
141  *	 pointer to the key is saved in the context, so the key must live at
142  *	 least as long as the context.
143  *
144  * Unlike AES-GCM, AES-CCM requires the total lengths of the associated data and
145  * the en/decrypted data to be known during initialization.  Callers MUST ensure
146  * that these lengths are correct.
147  *
148  * If this function returns success, the context should be zeroized at the end
149  * of its lifetime.  Normally that happens in aes_ccm_encrypt_final() or
150  * aes_ccm_decrypt_final(), but callers that abandon a context without
151  * finalizing it should explicitly zeroize it.
152  *
153  * IMPORTANT: Callers that are decrypting MUST NOT assume that any decrypted or
154  * associated data is authentic until the authentication tag has been verified.
155  * This incremental API is provided solely to support callers that can't
156  * efficiently use the one-shot functions due to using a nonlinear data layout.
157  *
158  * For incremental AES-CCM encryption, use:
159  *
160  * 1. aes_ccm_init()
161  * 2. aes_ccm_auth_update() (any number of times)
162  * 3. aes_ccm_encrypt_update() (any number of times)
163  * 4. aes_ccm_encrypt_final()
164  *
165  * For incremental AES-CCM decryption, use:
166  *
167  * 1. aes_ccm_init()
168  * 2. aes_ccm_auth_update() (any number of times)
169  * 3. aes_ccm_decrypt_update() (any number of times)
170  * 4. aes_ccm_decrypt_final()
171  *
172  * Context: Any context.
173  * Return:
174  * * 0 on success
175  * * -EINVAL if @nonce_len is invalid
176  * * -EOVERFLOW if @data_len is too large for the selected @nonce_len
177  */
178 int __must_check aes_ccm_init(struct aes_ccm_ctx *ctx, u64 data_len, u64 ad_len,
179 			      const u8 *nonce, size_t nonce_len,
180 			      const struct aes_ccm_key *key);
181 
182 /**
183  * aes_ccm_auth_update() - Incrementally process AES-CCM associated data
184  * @ctx: An AES-CCM context
185  * @ad: The associated data
186  * @len: Length of the associated data in bytes
187  *
188  * IMPORTANT: Callers MUST NOT assume that any decrypted or associated data is
189  * authentic until the authentication tag has been verified.
190  *
191  * The total length of the associated data (over all calls to this function)
192  * MUST match the ad_len that was passed to aes_ccm_init().
193  *
194  * Context: Any context.
195  */
196 void aes_ccm_auth_update(struct aes_ccm_ctx *ctx, const u8 *ad, size_t len);
197 
198 /**
199  * aes_ccm_encrypt_update() - Incrementally encrypt data with AES-CCM
200  * @ctx: An AES-CCM context
201  * @dst: The destination buffer.  Can be in-place or out-of-place.  For other
202  *	 overlaps the behavior is unspecified.
203  * @src: The source plaintext data
204  * @len: Number of bytes to encrypt
205  *
206  * This can be called only after all associated data has been processed.
207  *
208  * The total length of the encrypted data (over all calls to this function) MUST
209  * match the data_len that was passed to aes_ccm_init().
210  *
211  * Context: Any context.
212  */
213 void aes_ccm_encrypt_update(struct aes_ccm_ctx *ctx, u8 *dst, const u8 *src,
214 			    size_t len);
215 
216 /**
217  * aes_ccm_decrypt_update() - Incrementally decrypt data with AES-CCM
218  * @ctx: An AES-CCM context
219  * @dst: The destination buffer.  Can be in-place or out-of-place.  For other
220  *	 overlaps the behavior is unspecified.
221  * @src: The source ciphertext data (not including auth tag)
222  * @len: Number of bytes to decrypt
223  *
224  * This can be called only after all associated data has been processed.
225  *
226  * The total length of the decrypted data (over all calls to this function) MUST
227  * match the data_len that was passed to aes_ccm_init().
228  *
229  * IMPORTANT: Callers MUST NOT assume that any decrypted or associated data is
230  * authentic until the authentication tag has been verified.
231  *
232  * Context: Any context.
233  */
234 void aes_ccm_decrypt_update(struct aes_ccm_ctx *ctx, u8 *dst, const u8 *src,
235 			    size_t len);
236 
237 /**
238  * aes_ccm_encrypt_final() - Finish encrypting a message with AES-CCM
239  * @ctx: An AES-CCM context
240  * @authtag: The output authentication tag.  Length is the authtag_len that was
241  *	     passed to aes_ccm_preparekey().
242  *
243  * This also zeroizes @ctx, so the caller doesn't need to do it.
244  *
245  * Context: Any context.
246  */
247 void aes_ccm_encrypt_final(struct aes_ccm_ctx *ctx, u8 *authtag);
248 
249 /**
250  * aes_ccm_decrypt_final() - Finish decrypting a message with AES-CCM
251  * @ctx: An AES-CCM context
252  * @authtag: The stored authentication tag.  Length is the authtag_len that was
253  *	     passed to aes_ccm_preparekey().
254  *
255  * This also zeroizes @ctx, so the caller doesn't need to do it.
256  *
257  * Context: Any context.
258  * Return:
259  * * 0 on success.  This is the only case where any decrypted or associated data
260  *   can be used.
261  * * -EBADMSG if the message is inauthentic
262  */
263 int __must_check aes_ccm_decrypt_final(struct aes_ccm_ctx *ctx,
264 				       const u8 *authtag);
265 
266 #endif /* _CRYPTO_AES_CCM_H */
267