1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Glue code for DES encryption optimized for sparc64 crypto opcodes.
4 * Copyright (C) 2012 David S. Miller <davem@davemloft.net>
7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 #include <linux/crypto.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <crypto/algapi.h>
15 #include <crypto/internal/des.h>
17 #include <asm/fpumacro.h>
18 #include <asm/pstate.h>
23 struct des_sparc64_ctx {
24 u64 encrypt_expkey[DES_EXPKEY_WORDS / 2];
25 u64 decrypt_expkey[DES_EXPKEY_WORDS / 2];
28 struct des3_ede_sparc64_ctx {
29 u64 encrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2];
30 u64 decrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2];
33 static void encrypt_to_decrypt(u64 *d, const u64 *e)
35 const u64 *s = e + (DES_EXPKEY_WORDS / 2) - 1;
38 for (i = 0; i < DES_EXPKEY_WORDS / 2; i++)
42 extern void des_sparc64_key_expand(const u32 *input_key, u64 *key);
44 static int des_set_key(struct crypto_tfm *tfm, const u8 *key,
47 struct des_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
50 /* Even though we have special instructions for key expansion,
51 * we call des_verify_key() so that we don't have to write our own
52 * weak key detection code.
54 err = crypto_des_verify_key(tfm, key);
58 des_sparc64_key_expand((const u32 *) key, &dctx->encrypt_expkey[0]);
59 encrypt_to_decrypt(&dctx->decrypt_expkey[0], &dctx->encrypt_expkey[0]);
64 extern void des_sparc64_crypt(const u64 *key, const u64 *input,
67 static void sparc_des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
69 struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
70 const u64 *K = ctx->encrypt_expkey;
72 des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
75 static void sparc_des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
77 struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
78 const u64 *K = ctx->decrypt_expkey;
80 des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
83 extern void des_sparc64_load_keys(const u64 *key);
85 extern void des_sparc64_ecb_crypt(const u64 *input, u64 *output,
88 #define DES_BLOCK_MASK (~(DES_BLOCK_SIZE - 1))
90 static int __ecb_crypt(struct blkcipher_desc *desc,
91 struct scatterlist *dst, struct scatterlist *src,
92 unsigned int nbytes, bool encrypt)
94 struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
95 struct blkcipher_walk walk;
98 blkcipher_walk_init(&walk, dst, src, nbytes);
99 err = blkcipher_walk_virt(desc, &walk);
100 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
103 des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
105 des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
106 while ((nbytes = walk.nbytes)) {
107 unsigned int block_len = nbytes & DES_BLOCK_MASK;
109 if (likely(block_len)) {
110 des_sparc64_ecb_crypt((const u64 *)walk.src.virt.addr,
111 (u64 *) walk.dst.virt.addr,
114 nbytes &= DES_BLOCK_SIZE - 1;
115 err = blkcipher_walk_done(desc, &walk, nbytes);
121 static int ecb_encrypt(struct blkcipher_desc *desc,
122 struct scatterlist *dst, struct scatterlist *src,
125 return __ecb_crypt(desc, dst, src, nbytes, true);
128 static int ecb_decrypt(struct blkcipher_desc *desc,
129 struct scatterlist *dst, struct scatterlist *src,
132 return __ecb_crypt(desc, dst, src, nbytes, false);
135 extern void des_sparc64_cbc_encrypt(const u64 *input, u64 *output,
136 unsigned int len, u64 *iv);
138 static int cbc_encrypt(struct blkcipher_desc *desc,
139 struct scatterlist *dst, struct scatterlist *src,
142 struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
143 struct blkcipher_walk walk;
146 blkcipher_walk_init(&walk, dst, src, nbytes);
147 err = blkcipher_walk_virt(desc, &walk);
148 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
150 des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
151 while ((nbytes = walk.nbytes)) {
152 unsigned int block_len = nbytes & DES_BLOCK_MASK;
154 if (likely(block_len)) {
155 des_sparc64_cbc_encrypt((const u64 *)walk.src.virt.addr,
156 (u64 *) walk.dst.virt.addr,
157 block_len, (u64 *) walk.iv);
159 nbytes &= DES_BLOCK_SIZE - 1;
160 err = blkcipher_walk_done(desc, &walk, nbytes);
166 extern void des_sparc64_cbc_decrypt(const u64 *input, u64 *output,
167 unsigned int len, u64 *iv);
169 static int cbc_decrypt(struct blkcipher_desc *desc,
170 struct scatterlist *dst, struct scatterlist *src,
173 struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
174 struct blkcipher_walk walk;
177 blkcipher_walk_init(&walk, dst, src, nbytes);
178 err = blkcipher_walk_virt(desc, &walk);
179 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
181 des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
182 while ((nbytes = walk.nbytes)) {
183 unsigned int block_len = nbytes & DES_BLOCK_MASK;
185 if (likely(block_len)) {
186 des_sparc64_cbc_decrypt((const u64 *)walk.src.virt.addr,
187 (u64 *) walk.dst.virt.addr,
188 block_len, (u64 *) walk.iv);
190 nbytes &= DES_BLOCK_SIZE - 1;
191 err = blkcipher_walk_done(desc, &walk, nbytes);
197 static int des3_ede_set_key(struct crypto_tfm *tfm, const u8 *key,
200 struct des3_ede_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
201 u64 k1[DES_EXPKEY_WORDS / 2];
202 u64 k2[DES_EXPKEY_WORDS / 2];
203 u64 k3[DES_EXPKEY_WORDS / 2];
206 err = crypto_des3_ede_verify_key(tfm, key);
210 des_sparc64_key_expand((const u32 *)key, k1);
212 des_sparc64_key_expand((const u32 *)key, k2);
214 des_sparc64_key_expand((const u32 *)key, k3);
216 memcpy(&dctx->encrypt_expkey[0], &k1[0], sizeof(k1));
217 encrypt_to_decrypt(&dctx->encrypt_expkey[DES_EXPKEY_WORDS / 2], &k2[0]);
218 memcpy(&dctx->encrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
221 encrypt_to_decrypt(&dctx->decrypt_expkey[0], &k3[0]);
222 memcpy(&dctx->decrypt_expkey[DES_EXPKEY_WORDS / 2],
224 encrypt_to_decrypt(&dctx->decrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
230 extern void des3_ede_sparc64_crypt(const u64 *key, const u64 *input,
233 static void sparc_des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
235 struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
236 const u64 *K = ctx->encrypt_expkey;
238 des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
241 static void sparc_des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
243 struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
244 const u64 *K = ctx->decrypt_expkey;
246 des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
249 extern void des3_ede_sparc64_load_keys(const u64 *key);
251 extern void des3_ede_sparc64_ecb_crypt(const u64 *expkey, const u64 *input,
252 u64 *output, unsigned int len);
254 static int __ecb3_crypt(struct blkcipher_desc *desc,
255 struct scatterlist *dst, struct scatterlist *src,
256 unsigned int nbytes, bool encrypt)
258 struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
259 struct blkcipher_walk walk;
263 blkcipher_walk_init(&walk, dst, src, nbytes);
264 err = blkcipher_walk_virt(desc, &walk);
265 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
268 K = &ctx->encrypt_expkey[0];
270 K = &ctx->decrypt_expkey[0];
271 des3_ede_sparc64_load_keys(K);
272 while ((nbytes = walk.nbytes)) {
273 unsigned int block_len = nbytes & DES_BLOCK_MASK;
275 if (likely(block_len)) {
276 const u64 *src64 = (const u64 *)walk.src.virt.addr;
277 des3_ede_sparc64_ecb_crypt(K, src64,
278 (u64 *) walk.dst.virt.addr,
281 nbytes &= DES_BLOCK_SIZE - 1;
282 err = blkcipher_walk_done(desc, &walk, nbytes);
288 static int ecb3_encrypt(struct blkcipher_desc *desc,
289 struct scatterlist *dst, struct scatterlist *src,
292 return __ecb3_crypt(desc, dst, src, nbytes, true);
295 static int ecb3_decrypt(struct blkcipher_desc *desc,
296 struct scatterlist *dst, struct scatterlist *src,
299 return __ecb3_crypt(desc, dst, src, nbytes, false);
302 extern void des3_ede_sparc64_cbc_encrypt(const u64 *expkey, const u64 *input,
303 u64 *output, unsigned int len,
306 static int cbc3_encrypt(struct blkcipher_desc *desc,
307 struct scatterlist *dst, struct scatterlist *src,
310 struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
311 struct blkcipher_walk walk;
315 blkcipher_walk_init(&walk, dst, src, nbytes);
316 err = blkcipher_walk_virt(desc, &walk);
317 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
319 K = &ctx->encrypt_expkey[0];
320 des3_ede_sparc64_load_keys(K);
321 while ((nbytes = walk.nbytes)) {
322 unsigned int block_len = nbytes & DES_BLOCK_MASK;
324 if (likely(block_len)) {
325 const u64 *src64 = (const u64 *)walk.src.virt.addr;
326 des3_ede_sparc64_cbc_encrypt(K, src64,
327 (u64 *) walk.dst.virt.addr,
331 nbytes &= DES_BLOCK_SIZE - 1;
332 err = blkcipher_walk_done(desc, &walk, nbytes);
338 extern void des3_ede_sparc64_cbc_decrypt(const u64 *expkey, const u64 *input,
339 u64 *output, unsigned int len,
342 static int cbc3_decrypt(struct blkcipher_desc *desc,
343 struct scatterlist *dst, struct scatterlist *src,
346 struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
347 struct blkcipher_walk walk;
351 blkcipher_walk_init(&walk, dst, src, nbytes);
352 err = blkcipher_walk_virt(desc, &walk);
353 desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
355 K = &ctx->decrypt_expkey[0];
356 des3_ede_sparc64_load_keys(K);
357 while ((nbytes = walk.nbytes)) {
358 unsigned int block_len = nbytes & DES_BLOCK_MASK;
360 if (likely(block_len)) {
361 const u64 *src64 = (const u64 *)walk.src.virt.addr;
362 des3_ede_sparc64_cbc_decrypt(K, src64,
363 (u64 *) walk.dst.virt.addr,
367 nbytes &= DES_BLOCK_SIZE - 1;
368 err = blkcipher_walk_done(desc, &walk, nbytes);
374 static struct crypto_alg algs[] = { {
376 .cra_driver_name = "des-sparc64",
377 .cra_priority = SPARC_CR_OPCODE_PRIORITY,
378 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
379 .cra_blocksize = DES_BLOCK_SIZE,
380 .cra_ctxsize = sizeof(struct des_sparc64_ctx),
382 .cra_module = THIS_MODULE,
385 .cia_min_keysize = DES_KEY_SIZE,
386 .cia_max_keysize = DES_KEY_SIZE,
387 .cia_setkey = des_set_key,
388 .cia_encrypt = sparc_des_encrypt,
389 .cia_decrypt = sparc_des_decrypt
393 .cra_name = "ecb(des)",
394 .cra_driver_name = "ecb-des-sparc64",
395 .cra_priority = SPARC_CR_OPCODE_PRIORITY,
396 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
397 .cra_blocksize = DES_BLOCK_SIZE,
398 .cra_ctxsize = sizeof(struct des_sparc64_ctx),
400 .cra_type = &crypto_blkcipher_type,
401 .cra_module = THIS_MODULE,
404 .min_keysize = DES_KEY_SIZE,
405 .max_keysize = DES_KEY_SIZE,
406 .setkey = des_set_key,
407 .encrypt = ecb_encrypt,
408 .decrypt = ecb_decrypt,
412 .cra_name = "cbc(des)",
413 .cra_driver_name = "cbc-des-sparc64",
414 .cra_priority = SPARC_CR_OPCODE_PRIORITY,
415 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
416 .cra_blocksize = DES_BLOCK_SIZE,
417 .cra_ctxsize = sizeof(struct des_sparc64_ctx),
419 .cra_type = &crypto_blkcipher_type,
420 .cra_module = THIS_MODULE,
423 .min_keysize = DES_KEY_SIZE,
424 .max_keysize = DES_KEY_SIZE,
425 .ivsize = DES_BLOCK_SIZE,
426 .setkey = des_set_key,
427 .encrypt = cbc_encrypt,
428 .decrypt = cbc_decrypt,
432 .cra_name = "des3_ede",
433 .cra_driver_name = "des3_ede-sparc64",
434 .cra_priority = SPARC_CR_OPCODE_PRIORITY,
435 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
436 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
437 .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
439 .cra_module = THIS_MODULE,
442 .cia_min_keysize = DES3_EDE_KEY_SIZE,
443 .cia_max_keysize = DES3_EDE_KEY_SIZE,
444 .cia_setkey = des3_ede_set_key,
445 .cia_encrypt = sparc_des3_ede_encrypt,
446 .cia_decrypt = sparc_des3_ede_decrypt
450 .cra_name = "ecb(des3_ede)",
451 .cra_driver_name = "ecb-des3_ede-sparc64",
452 .cra_priority = SPARC_CR_OPCODE_PRIORITY,
453 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
454 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
455 .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
457 .cra_type = &crypto_blkcipher_type,
458 .cra_module = THIS_MODULE,
461 .min_keysize = DES3_EDE_KEY_SIZE,
462 .max_keysize = DES3_EDE_KEY_SIZE,
463 .setkey = des3_ede_set_key,
464 .encrypt = ecb3_encrypt,
465 .decrypt = ecb3_decrypt,
469 .cra_name = "cbc(des3_ede)",
470 .cra_driver_name = "cbc-des3_ede-sparc64",
471 .cra_priority = SPARC_CR_OPCODE_PRIORITY,
472 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
473 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
474 .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
476 .cra_type = &crypto_blkcipher_type,
477 .cra_module = THIS_MODULE,
480 .min_keysize = DES3_EDE_KEY_SIZE,
481 .max_keysize = DES3_EDE_KEY_SIZE,
482 .ivsize = DES3_EDE_BLOCK_SIZE,
483 .setkey = des3_ede_set_key,
484 .encrypt = cbc3_encrypt,
485 .decrypt = cbc3_decrypt,
490 static bool __init sparc64_has_des_opcode(void)
494 if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
497 __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
498 if (!(cfr & CFR_DES))
504 static int __init des_sparc64_mod_init(void)
506 if (sparc64_has_des_opcode()) {
507 pr_info("Using sparc64 des opcodes optimized DES implementation\n");
508 return crypto_register_algs(algs, ARRAY_SIZE(algs));
510 pr_info("sparc64 des opcodes not available.\n");
514 static void __exit des_sparc64_mod_fini(void)
516 crypto_unregister_algs(algs, ARRAY_SIZE(algs));
519 module_init(des_sparc64_mod_init);
520 module_exit(des_sparc64_mod_fini);
522 MODULE_LICENSE("GPL");
523 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
525 MODULE_ALIAS_CRYPTO("des");
526 MODULE_ALIAS_CRYPTO("des3_ede");
528 #include "crop_devid.c"