diff options
Diffstat (limited to 'arch/s390/crypto/aes_s390.c')
-rw-r--r-- | arch/s390/crypto/aes_s390.c | 285 |
1 files changed, 194 insertions, 91 deletions
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 5713c7e5bd16..15c9eec02928 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -16,9 +16,9 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <crypto/algapi.h> | ||
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/crypto.h> | ||
22 | #include "crypt_s390.h" | 22 | #include "crypt_s390.h" |
23 | 23 | ||
24 | #define AES_MIN_KEY_SIZE 16 | 24 | #define AES_MIN_KEY_SIZE 16 |
@@ -34,13 +34,16 @@ int has_aes_256 = 0; | |||
34 | struct s390_aes_ctx { | 34 | struct s390_aes_ctx { |
35 | u8 iv[AES_BLOCK_SIZE]; | 35 | u8 iv[AES_BLOCK_SIZE]; |
36 | u8 key[AES_MAX_KEY_SIZE]; | 36 | u8 key[AES_MAX_KEY_SIZE]; |
37 | long enc; | ||
38 | long dec; | ||
37 | int key_len; | 39 | int key_len; |
38 | }; | 40 | }; |
39 | 41 | ||
40 | static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 42 | static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, |
41 | unsigned int key_len, u32 *flags) | 43 | unsigned int key_len) |
42 | { | 44 | { |
43 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); | 45 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); |
46 | u32 *flags = &tfm->crt_flags; | ||
44 | 47 | ||
45 | switch (key_len) { | 48 | switch (key_len) { |
46 | case 16: | 49 | case 16: |
@@ -110,133 +113,206 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | |||
110 | } | 113 | } |
111 | } | 114 | } |
112 | 115 | ||
113 | static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, | ||
114 | const u8 *in, unsigned int nbytes) | ||
115 | { | ||
116 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | ||
117 | int ret; | ||
118 | 116 | ||
119 | /* only use complete blocks */ | 117 | static struct crypto_alg aes_alg = { |
120 | nbytes &= ~(AES_BLOCK_SIZE - 1); | 118 | .cra_name = "aes", |
119 | .cra_driver_name = "aes-s390", | ||
120 | .cra_priority = CRYPT_S390_PRIORITY, | ||
121 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
122 | .cra_blocksize = AES_BLOCK_SIZE, | ||
123 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | ||
124 | .cra_module = THIS_MODULE, | ||
125 | .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), | ||
126 | .cra_u = { | ||
127 | .cipher = { | ||
128 | .cia_min_keysize = AES_MIN_KEY_SIZE, | ||
129 | .cia_max_keysize = AES_MAX_KEY_SIZE, | ||
130 | .cia_setkey = aes_set_key, | ||
131 | .cia_encrypt = aes_encrypt, | ||
132 | .cia_decrypt = aes_decrypt, | ||
133 | } | ||
134 | } | ||
135 | }; | ||
136 | |||
137 | static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | ||
138 | unsigned int key_len) | ||
139 | { | ||
140 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); | ||
121 | 141 | ||
122 | switch (sctx->key_len) { | 142 | switch (key_len) { |
123 | case 16: | 143 | case 16: |
124 | ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); | 144 | sctx->enc = KM_AES_128_ENCRYPT; |
125 | BUG_ON((ret < 0) || (ret != nbytes)); | 145 | sctx->dec = KM_AES_128_DECRYPT; |
126 | break; | 146 | break; |
127 | case 24: | 147 | case 24: |
128 | ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); | 148 | sctx->enc = KM_AES_192_ENCRYPT; |
129 | BUG_ON((ret < 0) || (ret != nbytes)); | 149 | sctx->dec = KM_AES_192_DECRYPT; |
130 | break; | 150 | break; |
131 | case 32: | 151 | case 32: |
132 | ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); | 152 | sctx->enc = KM_AES_256_ENCRYPT; |
133 | BUG_ON((ret < 0) || (ret != nbytes)); | 153 | sctx->dec = KM_AES_256_DECRYPT; |
134 | break; | 154 | break; |
135 | } | 155 | } |
136 | return nbytes; | 156 | |
157 | return aes_set_key(tfm, in_key, key_len); | ||
137 | } | 158 | } |
138 | 159 | ||
139 | static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, | 160 | static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param, |
140 | const u8 *in, unsigned int nbytes) | 161 | struct blkcipher_walk *walk) |
141 | { | 162 | { |
142 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 163 | int ret = blkcipher_walk_virt(desc, walk); |
143 | int ret; | 164 | unsigned int nbytes; |
144 | 165 | ||
145 | /* only use complete blocks */ | 166 | while ((nbytes = walk->nbytes)) { |
146 | nbytes &= ~(AES_BLOCK_SIZE - 1); | 167 | /* only use complete blocks */ |
168 | unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1); | ||
169 | u8 *out = walk->dst.virt.addr; | ||
170 | u8 *in = walk->src.virt.addr; | ||
147 | 171 | ||
148 | switch (sctx->key_len) { | 172 | ret = crypt_s390_km(func, param, out, in, n); |
149 | case 16: | 173 | BUG_ON((ret < 0) || (ret != n)); |
150 | ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); | 174 | |
151 | BUG_ON((ret < 0) || (ret != nbytes)); | 175 | nbytes &= AES_BLOCK_SIZE - 1; |
152 | break; | 176 | ret = blkcipher_walk_done(desc, walk, nbytes); |
153 | case 24: | ||
154 | ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes); | ||
155 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
156 | break; | ||
157 | case 32: | ||
158 | ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes); | ||
159 | BUG_ON((ret < 0) || (ret != nbytes)); | ||
160 | break; | ||
161 | } | 177 | } |
162 | return nbytes; | 178 | |
179 | return ret; | ||
163 | } | 180 | } |
164 | 181 | ||
165 | static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, | 182 | static int ecb_aes_encrypt(struct blkcipher_desc *desc, |
166 | const u8 *in, unsigned int nbytes) | 183 | struct scatterlist *dst, struct scatterlist *src, |
184 | unsigned int nbytes) | ||
167 | { | 185 | { |
168 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 186 | struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); |
169 | int ret; | 187 | struct blkcipher_walk walk; |
170 | 188 | ||
171 | /* only use complete blocks */ | 189 | blkcipher_walk_init(&walk, dst, src, nbytes); |
172 | nbytes &= ~(AES_BLOCK_SIZE - 1); | 190 | return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk); |
191 | } | ||
173 | 192 | ||
174 | memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); | 193 | static int ecb_aes_decrypt(struct blkcipher_desc *desc, |
175 | switch (sctx->key_len) { | 194 | struct scatterlist *dst, struct scatterlist *src, |
195 | unsigned int nbytes) | ||
196 | { | ||
197 | struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | ||
198 | struct blkcipher_walk walk; | ||
199 | |||
200 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
201 | return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk); | ||
202 | } | ||
203 | |||
204 | static struct crypto_alg ecb_aes_alg = { | ||
205 | .cra_name = "ecb(aes)", | ||
206 | .cra_driver_name = "ecb-aes-s390", | ||
207 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | ||
208 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
209 | .cra_blocksize = AES_BLOCK_SIZE, | ||
210 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | ||
211 | .cra_type = &crypto_blkcipher_type, | ||
212 | .cra_module = THIS_MODULE, | ||
213 | .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list), | ||
214 | .cra_u = { | ||
215 | .blkcipher = { | ||
216 | .min_keysize = AES_MIN_KEY_SIZE, | ||
217 | .max_keysize = AES_MAX_KEY_SIZE, | ||
218 | .setkey = ecb_aes_set_key, | ||
219 | .encrypt = ecb_aes_encrypt, | ||
220 | .decrypt = ecb_aes_decrypt, | ||
221 | } | ||
222 | } | ||
223 | }; | ||
224 | |||
225 | static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | ||
226 | unsigned int key_len) | ||
227 | { | ||
228 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); | ||
229 | |||
230 | switch (key_len) { | ||
176 | case 16: | 231 | case 16: |
177 | ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); | 232 | sctx->enc = KMC_AES_128_ENCRYPT; |
178 | BUG_ON((ret < 0) || (ret != nbytes)); | 233 | sctx->dec = KMC_AES_128_DECRYPT; |
179 | break; | 234 | break; |
180 | case 24: | 235 | case 24: |
181 | ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); | 236 | sctx->enc = KMC_AES_192_ENCRYPT; |
182 | BUG_ON((ret < 0) || (ret != nbytes)); | 237 | sctx->dec = KMC_AES_192_DECRYPT; |
183 | break; | 238 | break; |
184 | case 32: | 239 | case 32: |
185 | ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); | 240 | sctx->enc = KMC_AES_256_ENCRYPT; |
186 | BUG_ON((ret < 0) || (ret != nbytes)); | 241 | sctx->dec = KMC_AES_256_DECRYPT; |
187 | break; | 242 | break; |
188 | } | 243 | } |
189 | memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE); | ||
190 | 244 | ||
191 | return nbytes; | 245 | return aes_set_key(tfm, in_key, key_len); |
192 | } | 246 | } |
193 | 247 | ||
194 | static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, | 248 | static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param, |
195 | const u8 *in, unsigned int nbytes) | 249 | struct blkcipher_walk *walk) |
196 | { | 250 | { |
197 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); | 251 | int ret = blkcipher_walk_virt(desc, walk); |
198 | int ret; | 252 | unsigned int nbytes = walk->nbytes; |
199 | 253 | ||
200 | /* only use complete blocks */ | 254 | if (!nbytes) |
201 | nbytes &= ~(AES_BLOCK_SIZE - 1); | 255 | goto out; |
202 | 256 | ||
203 | memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); | 257 | memcpy(param, walk->iv, AES_BLOCK_SIZE); |
204 | switch (sctx->key_len) { | 258 | do { |
205 | case 16: | 259 | /* only use complete blocks */ |
206 | ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); | 260 | unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1); |
207 | BUG_ON((ret < 0) || (ret != nbytes)); | 261 | u8 *out = walk->dst.virt.addr; |
208 | break; | 262 | u8 *in = walk->src.virt.addr; |
209 | case 24: | 263 | |
210 | ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); | 264 | ret = crypt_s390_kmc(func, param, out, in, n); |
211 | BUG_ON((ret < 0) || (ret != nbytes)); | 265 | BUG_ON((ret < 0) || (ret != n)); |
212 | break; | 266 | |
213 | case 32: | 267 | nbytes &= AES_BLOCK_SIZE - 1; |
214 | ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); | 268 | ret = blkcipher_walk_done(desc, walk, nbytes); |
215 | BUG_ON((ret < 0) || (ret != nbytes)); | 269 | } while ((nbytes = walk->nbytes)); |
216 | break; | 270 | memcpy(walk->iv, param, AES_BLOCK_SIZE); |
217 | } | 271 | |
218 | return nbytes; | 272 | out: |
273 | return ret; | ||
219 | } | 274 | } |
220 | 275 | ||
276 | static int cbc_aes_encrypt(struct blkcipher_desc *desc, | ||
277 | struct scatterlist *dst, struct scatterlist *src, | ||
278 | unsigned int nbytes) | ||
279 | { | ||
280 | struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | ||
281 | struct blkcipher_walk walk; | ||
221 | 282 | ||
222 | static struct crypto_alg aes_alg = { | 283 | blkcipher_walk_init(&walk, dst, src, nbytes); |
223 | .cra_name = "aes", | 284 | return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk); |
224 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | 285 | } |
286 | |||
287 | static int cbc_aes_decrypt(struct blkcipher_desc *desc, | ||
288 | struct scatterlist *dst, struct scatterlist *src, | ||
289 | unsigned int nbytes) | ||
290 | { | ||
291 | struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | ||
292 | struct blkcipher_walk walk; | ||
293 | |||
294 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
295 | return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk); | ||
296 | } | ||
297 | |||
298 | static struct crypto_alg cbc_aes_alg = { | ||
299 | .cra_name = "cbc(aes)", | ||
300 | .cra_driver_name = "cbc-aes-s390", | ||
301 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | ||
302 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
225 | .cra_blocksize = AES_BLOCK_SIZE, | 303 | .cra_blocksize = AES_BLOCK_SIZE, |
226 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | 304 | .cra_ctxsize = sizeof(struct s390_aes_ctx), |
305 | .cra_type = &crypto_blkcipher_type, | ||
227 | .cra_module = THIS_MODULE, | 306 | .cra_module = THIS_MODULE, |
228 | .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), | 307 | .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list), |
229 | .cra_u = { | 308 | .cra_u = { |
230 | .cipher = { | 309 | .blkcipher = { |
231 | .cia_min_keysize = AES_MIN_KEY_SIZE, | 310 | .min_keysize = AES_MIN_KEY_SIZE, |
232 | .cia_max_keysize = AES_MAX_KEY_SIZE, | 311 | .max_keysize = AES_MAX_KEY_SIZE, |
233 | .cia_setkey = aes_set_key, | 312 | .ivsize = AES_BLOCK_SIZE, |
234 | .cia_encrypt = aes_encrypt, | 313 | .setkey = cbc_aes_set_key, |
235 | .cia_decrypt = aes_decrypt, | 314 | .encrypt = cbc_aes_encrypt, |
236 | .cia_encrypt_ecb = aes_encrypt_ecb, | 315 | .decrypt = cbc_aes_decrypt, |
237 | .cia_decrypt_ecb = aes_decrypt_ecb, | ||
238 | .cia_encrypt_cbc = aes_encrypt_cbc, | ||
239 | .cia_decrypt_cbc = aes_decrypt_cbc, | ||
240 | } | 316 | } |
241 | } | 317 | } |
242 | }; | 318 | }; |
@@ -256,13 +332,40 @@ static int __init aes_init(void) | |||
256 | return -ENOSYS; | 332 | return -ENOSYS; |
257 | 333 | ||
258 | ret = crypto_register_alg(&aes_alg); | 334 | ret = crypto_register_alg(&aes_alg); |
259 | if (ret != 0) | 335 | if (ret != 0) { |
260 | printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n"); | 336 | printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n"); |
337 | goto aes_err; | ||
338 | } | ||
339 | |||
340 | ret = crypto_register_alg(&ecb_aes_alg); | ||
341 | if (ret != 0) { | ||
342 | printk(KERN_INFO | ||
343 | "crypt_s390: ecb-aes-s390 couldn't be loaded.\n"); | ||
344 | goto ecb_aes_err; | ||
345 | } | ||
346 | |||
347 | ret = crypto_register_alg(&cbc_aes_alg); | ||
348 | if (ret != 0) { | ||
349 | printk(KERN_INFO | ||
350 | "crypt_s390: cbc-aes-s390 couldn't be loaded.\n"); | ||
351 | goto cbc_aes_err; | ||
352 | } | ||
353 | |||
354 | out: | ||
261 | return ret; | 355 | return ret; |
356 | |||
357 | cbc_aes_err: | ||
358 | crypto_unregister_alg(&ecb_aes_alg); | ||
359 | ecb_aes_err: | ||
360 | crypto_unregister_alg(&aes_alg); | ||
361 | aes_err: | ||
362 | goto out; | ||
262 | } | 363 | } |
263 | 364 | ||
264 | static void __exit aes_fini(void) | 365 | static void __exit aes_fini(void) |
265 | { | 366 | { |
367 | crypto_unregister_alg(&cbc_aes_alg); | ||
368 | crypto_unregister_alg(&ecb_aes_alg); | ||
266 | crypto_unregister_alg(&aes_alg); | 369 | crypto_unregister_alg(&aes_alg); |
267 | } | 370 | } |
268 | 371 | ||