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