des_glue.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  81. if (encrypt)
  82. des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
  83. else
  84. des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
  85. while ((nbytes = walk.nbytes)) {
  86. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  87. if (likely(block_len)) {
  88. des_sparc64_ecb_crypt((const u64 *)walk.src.virt.addr,
  89. (u64 *) walk.dst.virt.addr,
  90. block_len);
  91. }
  92. nbytes &= DES_BLOCK_SIZE - 1;
  93. err = blkcipher_walk_done(desc, &walk, nbytes);
  94. }
  95. fprs_write(0);
  96. return err;
  97. }
  98. static int ecb_encrypt(struct blkcipher_desc *desc,
  99. struct scatterlist *dst, struct scatterlist *src,
  100. unsigned int nbytes)
  101. {
  102. return __ecb_crypt(desc, dst, src, nbytes, true);
  103. }
  104. static int ecb_decrypt(struct blkcipher_desc *desc,
  105. struct scatterlist *dst, struct scatterlist *src,
  106. unsigned int nbytes)
  107. {
  108. return __ecb_crypt(desc, dst, src, nbytes, false);
  109. }
  110. extern void des_sparc64_cbc_encrypt(const u64 *input, u64 *output,
  111. unsigned int len, u64 *iv);
  112. static int cbc_encrypt(struct blkcipher_desc *desc,
  113. struct scatterlist *dst, struct scatterlist *src,
  114. unsigned int nbytes)
  115. {
  116. struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  117. struct blkcipher_walk walk;
  118. int err;
  119. blkcipher_walk_init(&walk, dst, src, nbytes);
  120. err = blkcipher_walk_virt(desc, &walk);
  121. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  122. des_sparc64_load_keys(&ctx->encrypt_expkey[0]);
  123. while ((nbytes = walk.nbytes)) {
  124. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  125. if (likely(block_len)) {
  126. des_sparc64_cbc_encrypt((const u64 *)walk.src.virt.addr,
  127. (u64 *) walk.dst.virt.addr,
  128. block_len, (u64 *) walk.iv);
  129. }
  130. nbytes &= DES_BLOCK_SIZE - 1;
  131. err = blkcipher_walk_done(desc, &walk, nbytes);
  132. }
  133. fprs_write(0);
  134. return err;
  135. }
  136. extern void des_sparc64_cbc_decrypt(const u64 *input, u64 *output,
  137. unsigned int len, u64 *iv);
  138. static int cbc_decrypt(struct blkcipher_desc *desc,
  139. struct scatterlist *dst, struct scatterlist *src,
  140. unsigned int nbytes)
  141. {
  142. struct des_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  143. struct blkcipher_walk walk;
  144. int err;
  145. blkcipher_walk_init(&walk, dst, src, nbytes);
  146. err = blkcipher_walk_virt(desc, &walk);
  147. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  148. des_sparc64_load_keys(&ctx->decrypt_expkey[0]);
  149. while ((nbytes = walk.nbytes)) {
  150. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  151. if (likely(block_len)) {
  152. des_sparc64_cbc_decrypt((const u64 *)walk.src.virt.addr,
  153. (u64 *) walk.dst.virt.addr,
  154. block_len, (u64 *) walk.iv);
  155. }
  156. nbytes &= DES_BLOCK_SIZE - 1;
  157. err = blkcipher_walk_done(desc, &walk, nbytes);
  158. }
  159. fprs_write(0);
  160. return err;
  161. }
  162. static int des3_ede_set_key(struct crypto_tfm *tfm, const u8 *key,
  163. unsigned int keylen)
  164. {
  165. struct des3_ede_sparc64_ctx *dctx = crypto_tfm_ctx(tfm);
  166. const u32 *K = (const u32 *)key;
  167. u32 *flags = &tfm->crt_flags;
  168. u64 k1[DES_EXPKEY_WORDS / 2];
  169. u64 k2[DES_EXPKEY_WORDS / 2];
  170. u64 k3[DES_EXPKEY_WORDS / 2];
  171. if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
  172. !((K[2] ^ K[4]) | (K[3] ^ K[5]))) &&
  173. (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
  174. *flags |= CRYPTO_TFM_RES_WEAK_KEY;
  175. return -EINVAL;
  176. }
  177. des_sparc64_key_expand((const u32 *)key, k1);
  178. key += DES_KEY_SIZE;
  179. des_sparc64_key_expand((const u32 *)key, k2);
  180. key += DES_KEY_SIZE;
  181. des_sparc64_key_expand((const u32 *)key, k3);
  182. memcpy(&dctx->encrypt_expkey[0], &k1[0], sizeof(k1));
  183. encrypt_to_decrypt(&dctx->encrypt_expkey[DES_EXPKEY_WORDS / 2], &k2[0]);
  184. memcpy(&dctx->encrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
  185. &k3[0], sizeof(k3));
  186. encrypt_to_decrypt(&dctx->decrypt_expkey[0], &k3[0]);
  187. memcpy(&dctx->decrypt_expkey[DES_EXPKEY_WORDS / 2],
  188. &k2[0], sizeof(k2));
  189. encrypt_to_decrypt(&dctx->decrypt_expkey[(DES_EXPKEY_WORDS / 2) * 2],
  190. &k1[0]);
  191. return 0;
  192. }
  193. extern void des3_ede_sparc64_crypt(const u64 *key, const u64 *input,
  194. u64 *output);
  195. static void des3_ede_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  196. {
  197. struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
  198. const u64 *K = ctx->encrypt_expkey;
  199. des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
  200. }
  201. static void des3_ede_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  202. {
  203. struct des3_ede_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
  204. const u64 *K = ctx->decrypt_expkey;
  205. des3_ede_sparc64_crypt(K, (const u64 *) src, (u64 *) dst);
  206. }
  207. extern void des3_ede_sparc64_load_keys(const u64 *key);
  208. extern void des3_ede_sparc64_ecb_crypt(const u64 *expkey, const u64 *input,
  209. u64 *output, unsigned int len);
  210. static int __ecb3_crypt(struct blkcipher_desc *desc,
  211. struct scatterlist *dst, struct scatterlist *src,
  212. unsigned int nbytes, bool encrypt)
  213. {
  214. struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  215. struct blkcipher_walk walk;
  216. const u64 *K;
  217. int err;
  218. blkcipher_walk_init(&walk, dst, src, nbytes);
  219. err = blkcipher_walk_virt(desc, &walk);
  220. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  221. if (encrypt)
  222. K = &ctx->encrypt_expkey[0];
  223. else
  224. K = &ctx->decrypt_expkey[0];
  225. des3_ede_sparc64_load_keys(K);
  226. while ((nbytes = walk.nbytes)) {
  227. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  228. if (likely(block_len)) {
  229. const u64 *src64 = (const u64 *)walk.src.virt.addr;
  230. des3_ede_sparc64_ecb_crypt(K, src64,
  231. (u64 *) walk.dst.virt.addr,
  232. block_len);
  233. }
  234. nbytes &= DES_BLOCK_SIZE - 1;
  235. err = blkcipher_walk_done(desc, &walk, nbytes);
  236. }
  237. fprs_write(0);
  238. return err;
  239. }
  240. static int ecb3_encrypt(struct blkcipher_desc *desc,
  241. struct scatterlist *dst, struct scatterlist *src,
  242. unsigned int nbytes)
  243. {
  244. return __ecb3_crypt(desc, dst, src, nbytes, true);
  245. }
  246. static int ecb3_decrypt(struct blkcipher_desc *desc,
  247. struct scatterlist *dst, struct scatterlist *src,
  248. unsigned int nbytes)
  249. {
  250. return __ecb3_crypt(desc, dst, src, nbytes, false);
  251. }
  252. extern void des3_ede_sparc64_cbc_encrypt(const u64 *expkey, const u64 *input,
  253. u64 *output, unsigned int len,
  254. u64 *iv);
  255. static int cbc3_encrypt(struct blkcipher_desc *desc,
  256. struct scatterlist *dst, struct scatterlist *src,
  257. unsigned int nbytes)
  258. {
  259. struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  260. struct blkcipher_walk walk;
  261. const u64 *K;
  262. int err;
  263. blkcipher_walk_init(&walk, dst, src, nbytes);
  264. err = blkcipher_walk_virt(desc, &walk);
  265. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  266. K = &ctx->encrypt_expkey[0];
  267. des3_ede_sparc64_load_keys(K);
  268. while ((nbytes = walk.nbytes)) {
  269. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  270. if (likely(block_len)) {
  271. const u64 *src64 = (const u64 *)walk.src.virt.addr;
  272. des3_ede_sparc64_cbc_encrypt(K, src64,
  273. (u64 *) walk.dst.virt.addr,
  274. block_len,
  275. (u64 *) walk.iv);
  276. }
  277. nbytes &= DES_BLOCK_SIZE - 1;
  278. err = blkcipher_walk_done(desc, &walk, nbytes);
  279. }
  280. fprs_write(0);
  281. return err;
  282. }
  283. extern void des3_ede_sparc64_cbc_decrypt(const u64 *expkey, const u64 *input,
  284. u64 *output, unsigned int len,
  285. u64 *iv);
  286. static int cbc3_decrypt(struct blkcipher_desc *desc,
  287. struct scatterlist *dst, struct scatterlist *src,
  288. unsigned int nbytes)
  289. {
  290. struct des3_ede_sparc64_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  291. struct blkcipher_walk walk;
  292. const u64 *K;
  293. int err;
  294. blkcipher_walk_init(&walk, dst, src, nbytes);
  295. err = blkcipher_walk_virt(desc, &walk);
  296. desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  297. K = &ctx->decrypt_expkey[0];
  298. des3_ede_sparc64_load_keys(K);
  299. while ((nbytes = walk.nbytes)) {
  300. unsigned int block_len = nbytes & DES_BLOCK_MASK;
  301. if (likely(block_len)) {
  302. const u64 *src64 = (const u64 *)walk.src.virt.addr;
  303. des3_ede_sparc64_cbc_decrypt(K, src64,
  304. (u64 *) walk.dst.virt.addr,
  305. block_len,
  306. (u64 *) walk.iv);
  307. }
  308. nbytes &= DES_BLOCK_SIZE - 1;
  309. err = blkcipher_walk_done(desc, &walk, nbytes);
  310. }
  311. fprs_write(0);
  312. return err;
  313. }
  314. static struct crypto_alg algs[] = { {
  315. .cra_name = "des",
  316. .cra_driver_name = "des-sparc64",
  317. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  318. .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  319. .cra_blocksize = DES_BLOCK_SIZE,
  320. .cra_ctxsize = sizeof(struct des_sparc64_ctx),
  321. .cra_alignmask = 7,
  322. .cra_module = THIS_MODULE,
  323. .cra_u = {
  324. .cipher = {
  325. .cia_min_keysize = DES_KEY_SIZE,
  326. .cia_max_keysize = DES_KEY_SIZE,
  327. .cia_setkey = des_set_key,
  328. .cia_encrypt = des_encrypt,
  329. .cia_decrypt = des_decrypt
  330. }
  331. }
  332. }, {
  333. .cra_name = "ecb(des)",
  334. .cra_driver_name = "ecb-des-sparc64",
  335. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  336. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  337. .cra_blocksize = DES_BLOCK_SIZE,
  338. .cra_ctxsize = sizeof(struct des_sparc64_ctx),
  339. .cra_alignmask = 7,
  340. .cra_type = &crypto_blkcipher_type,
  341. .cra_module = THIS_MODULE,
  342. .cra_u = {
  343. .blkcipher = {
  344. .min_keysize = DES_KEY_SIZE,
  345. .max_keysize = DES_KEY_SIZE,
  346. .setkey = des_set_key,
  347. .encrypt = ecb_encrypt,
  348. .decrypt = ecb_decrypt,
  349. },
  350. },
  351. }, {
  352. .cra_name = "cbc(des)",
  353. .cra_driver_name = "cbc-des-sparc64",
  354. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  355. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  356. .cra_blocksize = DES_BLOCK_SIZE,
  357. .cra_ctxsize = sizeof(struct des_sparc64_ctx),
  358. .cra_alignmask = 7,
  359. .cra_type = &crypto_blkcipher_type,
  360. .cra_module = THIS_MODULE,
  361. .cra_u = {
  362. .blkcipher = {
  363. .min_keysize = DES_KEY_SIZE,
  364. .max_keysize = DES_KEY_SIZE,
  365. .ivsize = DES_BLOCK_SIZE,
  366. .setkey = des_set_key,
  367. .encrypt = cbc_encrypt,
  368. .decrypt = cbc_decrypt,
  369. },
  370. },
  371. }, {
  372. .cra_name = "des3_ede",
  373. .cra_driver_name = "des3_ede-sparc64",
  374. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  375. .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  376. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  377. .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
  378. .cra_alignmask = 7,
  379. .cra_module = THIS_MODULE,
  380. .cra_u = {
  381. .cipher = {
  382. .cia_min_keysize = DES3_EDE_KEY_SIZE,
  383. .cia_max_keysize = DES3_EDE_KEY_SIZE,
  384. .cia_setkey = des3_ede_set_key,
  385. .cia_encrypt = des3_ede_encrypt,
  386. .cia_decrypt = des3_ede_decrypt
  387. }
  388. }
  389. }, {
  390. .cra_name = "ecb(des3_ede)",
  391. .cra_driver_name = "ecb-des3_ede-sparc64",
  392. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  393. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  394. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  395. .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
  396. .cra_alignmask = 7,
  397. .cra_type = &crypto_blkcipher_type,
  398. .cra_module = THIS_MODULE,
  399. .cra_u = {
  400. .blkcipher = {
  401. .min_keysize = DES3_EDE_KEY_SIZE,
  402. .max_keysize = DES3_EDE_KEY_SIZE,
  403. .setkey = des3_ede_set_key,
  404. .encrypt = ecb3_encrypt,
  405. .decrypt = ecb3_decrypt,
  406. },
  407. },
  408. }, {
  409. .cra_name = "cbc(des3_ede)",
  410. .cra_driver_name = "cbc-des3_ede-sparc64",
  411. .cra_priority = SPARC_CR_OPCODE_PRIORITY,
  412. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  413. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  414. .cra_ctxsize = sizeof(struct des3_ede_sparc64_ctx),
  415. .cra_alignmask = 7,
  416. .cra_type = &crypto_blkcipher_type,
  417. .cra_module = THIS_MODULE,
  418. .cra_u = {
  419. .blkcipher = {
  420. .min_keysize = DES3_EDE_KEY_SIZE,
  421. .max_keysize = DES3_EDE_KEY_SIZE,
  422. .ivsize = DES3_EDE_BLOCK_SIZE,
  423. .setkey = des3_ede_set_key,
  424. .encrypt = cbc3_encrypt,
  425. .decrypt = cbc3_decrypt,
  426. },
  427. },
  428. } };
  429. static bool __init sparc64_has_des_opcode(void)
  430. {
  431. unsigned long cfr;
  432. if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO))
  433. return false;
  434. __asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
  435. if (!(cfr & CFR_DES))
  436. return false;
  437. return true;
  438. }
  439. static int __init des_sparc64_mod_init(void)
  440. {
  441. int i;
  442. for (i = 0; i < ARRAY_SIZE(algs); i++)
  443. INIT_LIST_HEAD(&algs[i].cra_list);
  444. if (sparc64_has_des_opcode()) {
  445. pr_info("Using sparc64 des opcodes optimized DES implementation\n");
  446. return crypto_register_algs(algs, ARRAY_SIZE(algs));
  447. }
  448. pr_info("sparc64 des opcodes not available.\n");
  449. return -ENODEV;
  450. }
  451. static void __exit des_sparc64_mod_fini(void)
  452. {
  453. crypto_unregister_algs(algs, ARRAY_SIZE(algs));
  454. }
  455. module_init(des_sparc64_mod_init);
  456. module_exit(des_sparc64_mod_fini);
  457. MODULE_LICENSE("GPL");
  458. MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated");
  459. MODULE_ALIAS_CRYPTO("des");
  460. MODULE_ALIAS_CRYPTO("des3_ede");
  461. #include "crop_devid.c"