1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Crypto API support for AES block cipher
4 *
5 * Copyright 2026 Google LLC
6 */
7
8 #include <crypto/aes-cbc-macs.h>
9 #include <crypto/aes.h>
10 #include <crypto/algapi.h>
11 #include <crypto/internal/hash.h>
12 #include <linux/module.h>
13
14 static_assert(__alignof__(struct aes_key) <= CRYPTO_MINALIGN);
15
crypto_aes_setkey(struct crypto_tfm * tfm,const u8 * in_key,unsigned int key_len)16 static int crypto_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
17 unsigned int key_len)
18 {
19 struct aes_key *key = crypto_tfm_ctx(tfm);
20
21 return aes_preparekey(key, in_key, key_len);
22 }
23
crypto_aes_encrypt(struct crypto_tfm * tfm,u8 * out,const u8 * in)24 static void crypto_aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
25 {
26 const struct aes_key *key = crypto_tfm_ctx(tfm);
27
28 aes_encrypt(key, out, in);
29 }
30
crypto_aes_decrypt(struct crypto_tfm * tfm,u8 * out,const u8 * in)31 static void crypto_aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
32 {
33 const struct aes_key *key = crypto_tfm_ctx(tfm);
34
35 aes_decrypt(key, out, in);
36 }
37
38 static_assert(__alignof__(struct aes_cmac_key) <= CRYPTO_MINALIGN);
39 #define AES_CMAC_KEY(tfm) ((struct aes_cmac_key *)crypto_shash_ctx(tfm))
40 #define AES_CMAC_CTX(desc) ((struct aes_cmac_ctx *)shash_desc_ctx(desc))
41
crypto_aes_cmac_setkey(struct crypto_shash * tfm,const u8 * in_key,unsigned int key_len)42 static int __maybe_unused crypto_aes_cmac_setkey(struct crypto_shash *tfm,
43 const u8 *in_key,
44 unsigned int key_len)
45 {
46 return aes_cmac_preparekey(AES_CMAC_KEY(tfm), in_key, key_len);
47 }
48
crypto_aes_xcbc_setkey(struct crypto_shash * tfm,const u8 * in_key,unsigned int key_len)49 static int __maybe_unused crypto_aes_xcbc_setkey(struct crypto_shash *tfm,
50 const u8 *in_key,
51 unsigned int key_len)
52 {
53 if (key_len != AES_KEYSIZE_128)
54 return -EINVAL;
55 aes_xcbcmac_preparekey(AES_CMAC_KEY(tfm), in_key);
56 return 0;
57 }
58
crypto_aes_cmac_init(struct shash_desc * desc)59 static int __maybe_unused crypto_aes_cmac_init(struct shash_desc *desc)
60 {
61 aes_cmac_init(AES_CMAC_CTX(desc), AES_CMAC_KEY(desc->tfm));
62 return 0;
63 }
64
crypto_aes_cmac_update(struct shash_desc * desc,const u8 * data,unsigned int len)65 static int __maybe_unused crypto_aes_cmac_update(struct shash_desc *desc,
66 const u8 *data,
67 unsigned int len)
68 {
69 aes_cmac_update(AES_CMAC_CTX(desc), data, len);
70 return 0;
71 }
72
crypto_aes_cmac_final(struct shash_desc * desc,u8 * out)73 static int __maybe_unused crypto_aes_cmac_final(struct shash_desc *desc,
74 u8 *out)
75 {
76 aes_cmac_final(AES_CMAC_CTX(desc), out);
77 return 0;
78 }
79
crypto_aes_cmac_digest(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)80 static int __maybe_unused crypto_aes_cmac_digest(struct shash_desc *desc,
81 const u8 *data,
82 unsigned int len, u8 *out)
83 {
84 aes_cmac(AES_CMAC_KEY(desc->tfm), data, len, out);
85 return 0;
86 }
87
88 static_assert(__alignof__(struct aes_enckey) <= CRYPTO_MINALIGN);
89 #define AES_CBCMAC_KEY(tfm) ((struct aes_enckey *)crypto_shash_ctx(tfm))
90 #define AES_CBCMAC_CTX(desc) ((struct aes_cbcmac_ctx *)shash_desc_ctx(desc))
91
crypto_aes_cbcmac_setkey(struct crypto_shash * tfm,const u8 * in_key,unsigned int key_len)92 static int __maybe_unused crypto_aes_cbcmac_setkey(struct crypto_shash *tfm,
93 const u8 *in_key,
94 unsigned int key_len)
95 {
96 return aes_prepareenckey(AES_CBCMAC_KEY(tfm), in_key, key_len);
97 }
98
crypto_aes_cbcmac_init(struct shash_desc * desc)99 static int __maybe_unused crypto_aes_cbcmac_init(struct shash_desc *desc)
100 {
101 aes_cbcmac_init(AES_CBCMAC_CTX(desc), AES_CBCMAC_KEY(desc->tfm));
102 return 0;
103 }
104
crypto_aes_cbcmac_update(struct shash_desc * desc,const u8 * data,unsigned int len)105 static int __maybe_unused crypto_aes_cbcmac_update(struct shash_desc *desc,
106 const u8 *data,
107 unsigned int len)
108 {
109 aes_cbcmac_update(AES_CBCMAC_CTX(desc), data, len);
110 return 0;
111 }
112
crypto_aes_cbcmac_final(struct shash_desc * desc,u8 * out)113 static int __maybe_unused crypto_aes_cbcmac_final(struct shash_desc *desc,
114 u8 *out)
115 {
116 aes_cbcmac_final(AES_CBCMAC_CTX(desc), out);
117 return 0;
118 }
119
crypto_aes_cbcmac_digest(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)120 static int __maybe_unused crypto_aes_cbcmac_digest(struct shash_desc *desc,
121 const u8 *data,
122 unsigned int len, u8 *out)
123 {
124 aes_cbcmac_init(AES_CBCMAC_CTX(desc), AES_CBCMAC_KEY(desc->tfm));
125 aes_cbcmac_update(AES_CBCMAC_CTX(desc), data, len);
126 aes_cbcmac_final(AES_CBCMAC_CTX(desc), out);
127 return 0;
128 }
129
130 static struct crypto_alg alg = {
131 .cra_name = "aes",
132 .cra_driver_name = "aes-lib",
133 .cra_priority = 100,
134 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
135 .cra_blocksize = AES_BLOCK_SIZE,
136 .cra_ctxsize = sizeof(struct aes_key),
137 .cra_module = THIS_MODULE,
138 .cra_u = { .cipher = { .cia_min_keysize = AES_MIN_KEY_SIZE,
139 .cia_max_keysize = AES_MAX_KEY_SIZE,
140 .cia_setkey = crypto_aes_setkey,
141 .cia_encrypt = crypto_aes_encrypt,
142 .cia_decrypt = crypto_aes_decrypt } }
143 };
144
145 static struct shash_alg mac_algs[] = {
146 #if IS_ENABLED(CONFIG_CRYPTO_CMAC)
147 {
148 .base.cra_name = "cmac(aes)",
149 .base.cra_driver_name = "cmac-aes-lib",
150 .base.cra_priority = 300,
151 .base.cra_blocksize = AES_BLOCK_SIZE,
152 .base.cra_ctxsize = sizeof(struct aes_cmac_key),
153 .base.cra_module = THIS_MODULE,
154 .digestsize = AES_BLOCK_SIZE,
155 .setkey = crypto_aes_cmac_setkey,
156 .init = crypto_aes_cmac_init,
157 .update = crypto_aes_cmac_update,
158 .final = crypto_aes_cmac_final,
159 .digest = crypto_aes_cmac_digest,
160 .descsize = sizeof(struct aes_cmac_ctx),
161 },
162 #endif
163 #if IS_ENABLED(CONFIG_CRYPTO_XCBC)
164 {
165 /*
166 * Note that the only difference between xcbc(aes) and cmac(aes)
167 * is the preparekey function.
168 */
169 .base.cra_name = "xcbc(aes)",
170 .base.cra_driver_name = "xcbc-aes-lib",
171 .base.cra_priority = 300,
172 .base.cra_blocksize = AES_BLOCK_SIZE,
173 .base.cra_ctxsize = sizeof(struct aes_cmac_key),
174 .base.cra_module = THIS_MODULE,
175 .digestsize = AES_BLOCK_SIZE,
176 .setkey = crypto_aes_xcbc_setkey,
177 .init = crypto_aes_cmac_init,
178 .update = crypto_aes_cmac_update,
179 .final = crypto_aes_cmac_final,
180 .digest = crypto_aes_cmac_digest,
181 .descsize = sizeof(struct aes_cmac_ctx),
182 },
183 #endif
184 #if IS_ENABLED(CONFIG_CRYPTO_CCM)
185 {
186 .base.cra_name = "cbcmac(aes)",
187 .base.cra_driver_name = "cbcmac-aes-lib",
188 .base.cra_priority = 300,
189 .base.cra_blocksize = AES_BLOCK_SIZE,
190 .base.cra_ctxsize = sizeof(struct aes_enckey),
191 .base.cra_module = THIS_MODULE,
192 .digestsize = AES_BLOCK_SIZE,
193 .setkey = crypto_aes_cbcmac_setkey,
194 .init = crypto_aes_cbcmac_init,
195 .update = crypto_aes_cbcmac_update,
196 .final = crypto_aes_cbcmac_final,
197 .digest = crypto_aes_cbcmac_digest,
198 .descsize = sizeof(struct aes_cbcmac_ctx),
199 },
200 #endif
201 };
202
crypto_aes_mod_init(void)203 static int __init crypto_aes_mod_init(void)
204 {
205 int err = crypto_register_alg(&alg);
206
207 if (err)
208 return err;
209
210 if (ARRAY_SIZE(mac_algs) > 0) {
211 err = crypto_register_shashes(mac_algs, ARRAY_SIZE(mac_algs));
212 if (err)
213 goto err_unregister_alg;
214 } /* Else, CONFIG_CRYPTO_HASH might not be enabled. */
215 return 0;
216
217 err_unregister_alg:
218 crypto_unregister_alg(&alg);
219 return err;
220 }
221 module_init(crypto_aes_mod_init);
222
crypto_aes_mod_exit(void)223 static void __exit crypto_aes_mod_exit(void)
224 {
225 if (ARRAY_SIZE(mac_algs) > 0)
226 crypto_unregister_shashes(mac_algs, ARRAY_SIZE(mac_algs));
227 crypto_unregister_alg(&alg);
228 }
229 module_exit(crypto_aes_mod_exit);
230
231 MODULE_DESCRIPTION("Crypto API support for AES block cipher");
232 MODULE_IMPORT_NS("CRYPTO_INTERNAL");
233 MODULE_LICENSE("GPL");
234 MODULE_ALIAS_CRYPTO("aes");
235 MODULE_ALIAS_CRYPTO("aes-lib");
236 #if IS_ENABLED(CONFIG_CRYPTO_CMAC)
237 MODULE_ALIAS_CRYPTO("cmac(aes)");
238 MODULE_ALIAS_CRYPTO("cmac-aes-lib");
239 #endif
240 #if IS_ENABLED(CONFIG_CRYPTO_XCBC)
241 MODULE_ALIAS_CRYPTO("xcbc(aes)");
242 MODULE_ALIAS_CRYPTO("xcbc-aes-lib");
243 #endif
244 #if IS_ENABLED(CONFIG_CRYPTO_CCM)
245 MODULE_ALIAS_CRYPTO("cbcmac(aes)");
246 MODULE_ALIAS_CRYPTO("cbcmac-aes-lib");
247 #endif
248