des_glue.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /* Glue code for DES encryption optimized for sparc64 crypto opcodes.
  2. *
  3. * Copyright (C) 2012 David S. Miller <davem@davemloft.net>
  4. */
  5. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  6. #include <linux/crypto.h>
  7. #include <linux/init.h>
  8. #include <linux/module.h>
  9. #include <linux/mm.h>
  10. #include <linux/types.h>
  11. #include <crypto/algapi.h>
  12. #include <crypto/des.h>
  13. #include <asm/fpumacro.h>
  14. #include <asm/pstate.h>
  15. #include <asm/elf.h>
  16. #include "opcodes.h"
  17. struct des_sparc64_ctx {
  18. u64 encrypt_expkey[DES_EXPKEY_WORDS / 2];
  19. u64 decrypt_expkey[DES_EXPKEY_WORDS / 2];
  20. };
  21. struct des3_ede_sparc64_ctx {
  22. u64 encrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2];
  23. u64 decrypt_expkey[DES3_EDE_EXPKEY_WORDS / 2];
  24. };
  25. static void encrypt_to_decrypt(u64 *d, const u64 *e)
  26. {
  27. const u64 *s = e + (DES_EXPKEY_WORDS / 2) - 1;
  28. int i;
  29. for (i = 0; i < DES_EXPKEY_WORDS / 2; i++)
  30. *d++ = *s--;
  31. }
  32. extern void des_sparc64_key_expand(const u32 *input_key, u64 *key);
  33. static int des_set_key(struct crypto_tfm *tfm, const u8 *key,
  34. unsigned int keylen)
  35. {
  36. struct des_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
  37. u32 *flags = &tfm->crt_flags;
  38. u32 tmp[DES_EXPKEY_WORDS];
  39. int ret;
  40. /* Even though we have special instructions for key expansion,
  41. * we call des_ekey() so that we don't have to write our own
  42. * weak key detection code.
  43. */
  44. ret = des_ekey(tmp, key);
  45. if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
  46. *flags |= CRYPTO_TFM_RES_WEAK_KEY;
  47. return -EINVAL;
  48. }
  49. des_sparc64_key_expand((const u32 *) key, &dctx->encrypt_expkey[0]);
  50. encrypt_to_decrypt(&dctx->decrypt_expkey[0], &dctx->encrypt_expkey[0]);
  51. return 0;
  52. }
  53. extern void des_sparc64_crypt(const u64 *key, const u64 *input,
  54. u64 *output);
  55. static void des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  56. {
  57. struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
  58. const u64 *K = ctx->encrypt_expkey;
  59. des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
  60. }
  61. static void des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  62. {
  63. struct des_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
  64. const u64 *K = ctx->decrypt_expkey;
  65. des_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
  66. }
  67. extern void des_sparc64_load_keys(const u64 *key);
  68. extern void des_sparc64_ecb_crypt(const u64 *input, u64 *output,
  69. unsigned int len);
  70. #define DES_BLOCK_MASK (~(DES_BLOCK_SIZE - 1))
  71. static int __ecb_crypt(struct blkcipher_desc *desc,
  72. struct scatterlist *dst, struct scatterlist *src,
  73. unsigned int nbytes, bool encrypt)
  74. {
  75. struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  76. struct blkcipher_walk walk;
  77. int err;
  78. blkcipher_walk_init(&walk, dst, src, nbytes);
  79. err = blkcipher_walk_virt(desc, &walk);
  80. if (encrypt)
  81. des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
  82. else
  83. des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
  84. while ((nbytes = walk.nbytes)) {
  85. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  86. if (likely(block_len)) {
  87. des_sparc64_ecb_crypt((const u64 *)walk.src.virt.addr,
  88. (u64 *) walk.dst.virt.addr,
  89. block_len);
  90. }
  91. nbytes &= DES_BLOCK_SIZE - 1;
  92. err = blkcipher_walk_done(desc, &walk, nbytes);
  93. }
  94. fprs_write(0);
  95. return err;
  96. }
  97. static int ecb_encrypt(struct blkcipher_desc *desc,
  98. struct scatterlist *dst, struct scatterlist *src,
  99. unsigned int nbytes)
  100. {
  101. return __ecb_crypt(desc, dst, src, nbytes, true);
  102. }
  103. static int ecb_decrypt(struct blkcipher_desc *desc,
  104. struct scatterlist *dst, struct scatterlist *src,
  105. unsigned int nbytes)
  106. {
  107. return __ecb_crypt(desc, dst, src, nbytes, false);
  108. }
  109. extern void des_sparc64_cbc_encrypt(const u64 *input, u64 *output,
  110. unsigned int len, u64 *iv);
  111. static int cbc_encrypt(struct blkcipher_desc *desc,
  112. struct scatterlist *dst, struct scatterlist *src,
  113. unsigned int nbytes)
  114. {
  115. struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  116. struct blkcipher_walk walk;
  117. int err;
  118. blkcipher_walk_init(&walk, dst, src, nbytes);
  119. err = blkcipher_walk_virt(desc, &walk);
  120. des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
  121. while ((nbytes = walk.nbytes)) {
  122. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  123. if (likely(block_len)) {
  124. des_sparc64_cbc_encrypt((const u64 *)walk.src.virt.addr,
  125. (u64 *) walk.dst.virt.addr,
  126. block_len, (u64 *) walk.iv);
  127. }
  128. nbytes &= DES_BLOCK_SIZE - 1;
  129. err = blkcipher_walk_done(desc, &walk, nbytes);
  130. }
  131. fprs_write(0);
  132. return err;
  133. }
  134. extern void des_sparc64_cbc_decrypt(const u64 *input, u64 *output,
  135. unsigned int len, u64 *iv);
  136. static int cbc_decrypt(struct blkcipher_desc *desc,
  137. struct scatterlist *dst, struct scatterlist *src,
  138. unsigned int nbytes)
  139. {
  140. struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  141. struct blkcipher_walk walk;
  142. int err;
  143. blkcipher_walk_init(&walk, dst, src, nbytes);
  144. err = blkcipher_walk_virt(desc, &walk);
  145. des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
  146. while ((nbytes = walk.nbytes)) {
  147. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  148. if (likely(block_len)) {
  149. des_sparc64_cbc_decrypt((const u64 *)walk.src.virt.addr,
  150. (u64 *) walk.dst.virt.addr,
  151. block_len, (u64 *) walk.iv);
  152. }
  153. nbytes &= DES_BLOCK_SIZE - 1;
  154. err = blkcipher_walk_done(desc, &walk, nbytes);
  155. }
  156. fprs_write(0);
  157. return err;
  158. }
  159. static int des3_ede_set_key(struct crypto_tfm *tfm, const u8 *key,
  160. unsigned int keylen)
  161. {
  162. struct des3_ede_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
  163. const u32 *K = (const u32 *)key;
  164. u32 *flags = &tfm->crt_flags;
  165. u64 k1[DES_EXPKEY_WORDS / 2];
  166. u64 k2[DES_EXPKEY_WORDS / 2];
  167. u64 k3[DES_EXPKEY_WORDS / 2];
  168. if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
  169. !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
  170. (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
  171. *flags |= CRYPTO_TFM_RES_WEAK_KEY;
  172. return -EINVAL;
  173. }
  174. des_sparc64_key_expand((const u32 *)key, k1);
  175. key += DES_KEY_SIZE;
  176. des_sparc64_key_expand((const u32 *)key, k2);
  177. key += DES_KEY_SIZE;
  178. des_sparc64_key_expand((const u32 *)key, k3);
  179. memcpy(&dctx->encrypt_expkey[0], &k1[0], sizeof(k1));
  180. encrypt_to_decrypt(&dctx->encrypt_expkey[DES_EXPKEY_WORDS / 2], &k2[0]);
  181. memcpy(&dctx->encrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
  182. &k3[0], sizeof(k3));
  183. encrypt_to_decrypt(&dctx->decrypt_expkey[0], &k3[0]);
  184. memcpy(&dctx->decrypt_expkey[DES_EXPKEY_WORDS / 2],
  185. &k2[0], sizeof(k2));
  186. encrypt_to_decrypt(&dctx->decrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
  187. &k1[0]);
  188. return 0;
  189. }
  190. extern void des3_ede_sparc64_crypt(const u64 *key, const u64 *input,
  191. u64 *output);
  192. static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  193. {
  194. struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
  195. const u64 *K = ctx->encrypt_expkey;
  196. des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
  197. }
  198. static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  199. {
  200. struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
  201. const u64 *K = ctx->decrypt_expkey;
  202. des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
  203. }
  204. extern void des3_ede_sparc64_load_keys(const u64 *key);
  205. extern void des3_ede_sparc64_ecb_crypt(const u64 *expkey, const u64 *input,
  206. u64 *output, unsigned int len);
  207. static int __ecb3_crypt(struct blkcipher_desc *desc,
  208. struct scatterlist *dst, struct scatterlist *src,
  209. unsigned int nbytes, bool encrypt)
  210. {
  211. struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  212. struct blkcipher_walk walk;
  213. const u64 *K;
  214. int err;
  215. blkcipher_walk_init(&walk, dst, src, nbytes);
  216. err = blkcipher_walk_virt(desc, &walk);
  217. if (encrypt)
  218. K = &ctx->encrypt_expkey[0];
  219. else
  220. K = &ctx->decrypt_expkey[0];
  221. des3_ede_sparc64_load_keys(K);
  222. while ((nbytes = walk.nbytes)) {
  223. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  224. if (likely(block_len)) {
  225. const u64 *src64 = (const u64 *)walk.src.virt.addr;
  226. des3_ede_sparc64_ecb_crypt(K, src64,
  227. (u64 *) walk.dst.virt.addr,
  228. block_len);
  229. }
  230. nbytes &= DES_BLOCK_SIZE - 1;
  231. err = blkcipher_walk_done(desc, &walk, nbytes);
  232. }
  233. fprs_write(0);
  234. return err;
  235. }
  236. static int ecb3_encrypt(struct blkcipher_desc *desc,
  237. struct scatterlist *dst, struct scatterlist *src,
  238. unsigned int nbytes)
  239. {
  240. return __ecb3_crypt(desc, dst, src, nbytes, true);
  241. }
  242. static int ecb3_decrypt(struct blkcipher_desc *desc,
  243. struct scatterlist *dst, struct scatterlist *src,
  244. unsigned int nbytes)
  245. {
  246. return __ecb3_crypt(desc, dst, src, nbytes, false);
  247. }
  248. extern void des3_ede_sparc64_cbc_encrypt(const u64 *expkey, const u64 *input,
  249. u64 *output, unsigned int len,
  250. u64 *iv);
  251. static int cbc3_encrypt(struct blkcipher_desc *desc,
  252. struct scatterlist *dst, struct scatterlist *src,
  253. unsigned int nbytes)
  254. {
  255. struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  256. struct blkcipher_walk walk;
  257. const u64 *K;
  258. int err;
  259. blkcipher_walk_init(&walk, dst, src, nbytes);
  260. err = blkcipher_walk_virt(desc, &walk);
  261. K = &ctx->encrypt_expkey[0];
  262. des3_ede_sparc64_load_keys(K);
  263. while ((nbytes = walk.nbytes)) {
  264. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  265. if (likely(block_len)) {
  266. const u64 *src64 = (const u64 *)walk.src.virt.addr;
  267. des3_ede_sparc64_cbc_encrypt(K, src64,
  268. (u64 *) walk.dst.virt.addr,
  269. block_len,
  270. (u64 *) walk.iv);
  271. }
  272. nbytes &= DES_BLOCK_SIZE - 1;
  273. err = blkcipher_walk_done(desc, &walk, nbytes);
  274. }
  275. fprs_write(0);
  276. return err;
  277. }
  278. extern void des3_ede_sparc64_cbc_decrypt(const u64 *expkey, const u64 *input,
  279. u64 *output, unsigned int len,
  280. u64 *iv);
  281. static int cbc3_decrypt(struct blkcipher_desc *desc,
  282. struct scatterlist *dst, struct scatterlist *src,
  283. unsigned int nbytes)
  284. {
  285. struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  286. struct blkcipher_walk walk;
  287. const u64 *K;
  288. int err;
  289. blkcipher_walk_init(&walk, dst, src, nbytes);
  290. err = blkcipher_walk_virt(desc, &walk);
  291. K = &ctx->decrypt_expkey[0];
  292. des3_ede_sparc64_load_keys(K);
  293. while ((nbytes = walk.nbytes)) {
  294. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  295. if (likely(block_len)) {
  296. const u64 *src64 = (const u64 *)walk.src.virt.addr;
  297. des3_ede_sparc64_cbc_decrypt(K, src64,
  298. (u64 *) walk.dst.virt.addr,
  299. block_len,
  300. (u64 *) walk.iv);
  301. }
  302. nbytes &= DES_BLOCK_SIZE - 1;
  303. err = blkcipher_walk_done(desc, &walk, nbytes);
  304. }
  305. fprs_write(0);
  306. return err;
  307. }
  308. static struct crypto_alg algs[] = { {
  309. .cra_name = "des",
  310. .cra_driver_name = "des-sparc64",
  311. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  312. .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  313. .cra_blocksize = DES_BLOCK_SIZE,
  314. .cra_ctxsize = sizeof(struct des_sparc64_ctx),
  315. .cra_alignmask = 7,
  316. .cra_module = THIS_MODULE,
  317. .cra_u = {
  318. .cipher = {
  319. .cia_min_keysize = DES_KEY_SIZE,
  320. .cia_max_keysize = DES_KEY_SIZE,
  321. .cia_setkey = des_set_key,
  322. .cia_encrypt = des_encrypt,
  323. .cia_decrypt = des_decrypt
  324. }
  325. }
  326. }, {
  327. .cra_name = "ecb(des)",
  328. .cra_driver_name = "ecb-des-sparc64",
  329. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  330. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  331. .cra_blocksize = DES_BLOCK_SIZE,
  332. .cra_ctxsize = sizeof(struct des_sparc64_ctx),
  333. .cra_alignmask = 7,
  334. .cra_type = &crypto_blkcipher_type,
  335. .cra_module = THIS_MODULE,
  336. .cra_u = {
  337. .blkcipher = {
  338. .min_keysize = DES_KEY_SIZE,
  339. .max_keysize = DES_KEY_SIZE,
  340. .setkey = des_set_key,
  341. .encrypt = ecb_encrypt,
  342. .decrypt = ecb_decrypt,
  343. },
  344. },
  345. }, {
  346. .cra_name = "cbc(des)",
  347. .cra_driver_name = "cbc-des-sparc64",
  348. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  349. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  350. .cra_blocksize = DES_BLOCK_SIZE,
  351. .cra_ctxsize = sizeof(struct des_sparc64_ctx),
  352. .cra_alignmask = 7,
  353. .cra_type = &crypto_blkcipher_type,
  354. .cra_module = THIS_MODULE,
  355. .cra_u = {
  356. .blkcipher = {
  357. .min_keysize = DES_KEY_SIZE,
  358. .max_keysize = DES_KEY_SIZE,
  359. .setkey = des_set_key,
  360. .encrypt = cbc_encrypt,
  361. .decrypt = cbc_decrypt,
  362. },
  363. },
  364. }, {
  365. .cra_name = "des3_ede",
  366. .cra_driver_name = "des3_ede-sparc64",
  367. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  368. .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  369. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  370. .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
  371. .cra_alignmask = 7,
  372. .cra_module = THIS_MODULE,
  373. .cra_u = {
  374. .cipher = {
  375. .cia_min_keysize = DES3_EDE_KEY_SIZE,
  376. .cia_max_keysize = DES3_EDE_KEY_SIZE,
  377. .cia_setkey = des3_ede_set_key,
  378. .cia_encrypt = des3_ede_encrypt,
  379. .cia_decrypt = des3_ede_decrypt
  380. }
  381. }
  382. }, {
  383. .cra_name = "ecb(des3_ede)",
  384. .cra_driver_name = "ecb-des3_ede-sparc64",
  385. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  386. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  387. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  388. .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
  389. .cra_alignmask = 7,
  390. .cra_type = &crypto_blkcipher_type,
  391. .cra_module = THIS_MODULE,
  392. .cra_u = {
  393. .blkcipher = {
  394. .min_keysize = DES3_EDE_KEY_SIZE,
  395. .max_keysize = DES3_EDE_KEY_SIZE,
  396. .setkey = des3_ede_set_key,
  397. .encrypt = ecb3_encrypt,
  398. .decrypt = ecb3_decrypt,
  399. },
  400. },
  401. }, {
  402. .cra_name = "cbc(des3_ede)",
  403. .cra_driver_name = "cbc-des3_ede-sparc64",
  404. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  405. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  406. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  407. .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
  408. .cra_alignmask = 7,
  409. .cra_type = &crypto_blkcipher_type,
  410. .cra_module = THIS_MODULE,
  411. .cra_u = {
  412. .blkcipher = {
  413. .min_keysize = DES3_EDE_KEY_SIZE,
  414. .max_keysize = DES3_EDE_KEY_SIZE,
  415. .setkey = des3_ede_set_key,
  416. .encrypt = cbc3_encrypt,
  417. .decrypt = cbc3_decrypt,
  418. },
  419. },
  420. } };
  421. static bool __init sparc64_has_des_opcode(void)
  422. {
  423. unsigned long cfr;
  424. if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
  425. return false;
  426. __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
  427. if (!(cfr & CFR_DES))
  428. return false;
  429. return true;
  430. }
  431. static int __init des_sparc64_mod_init(void)
  432. {
  433. int i;
  434. for (i = 0; i < ARRAY_SIZE(algs); i++)
  435. INIT_LIST_HEAD(&algs[i].cra_list);
  436. if (sparc64_has_des_opcode()) {
  437. pr_info("Using sparc64 des opcodes optimized DES implementation\n");
  438. return crypto_register_algs(algs, ARRAY_SIZE(algs));
  439. }
  440. pr_info("sparc64 des opcodes not available.\n");
  441. return -ENODEV;
  442. }
  443. static void __exit des_sparc64_mod_fini(void)
  444. {
  445. crypto_unregister_algs(algs, ARRAY_SIZE(algs));
  446. }
  447. module_init(des_sparc64_mod_init);
  448. module_exit(des_sparc64_mod_fini);
  449. MODULE_LICENSE("GPL");
  450. MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
  451. MODULE_ALIAS("des");