xref: /linux/crypto/aes.c (revision 370c3883195566ee3e7d79e0146c3d735a406573)
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