aesbs-glue.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * linux/arch/arm/crypto/aesbs-glue.c - glue code for NEON bit sliced AES
  3. *
  4. * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <asm/neon.h>
  11. #include <crypto/aes.h>
  12. #include <crypto/ablk_helper.h>
  13. #include <crypto/algapi.h>
  14. #include <linux/module.h>
  15. #include <crypto/xts.h>
  16. #include "aes_glue.h"
  17. #define BIT_SLICED_KEY_MAXSIZE (128 * (AES_MAXNR - 1) + 2 * AES_BLOCK_SIZE)
  18. struct BS_KEY {
  19. struct AES_KEY rk;
  20. int converted;
  21. u8 __aligned(8) bs[BIT_SLICED_KEY_MAXSIZE];
  22. } __aligned(8);
  23. asmlinkage void bsaes_enc_key_convert(u8 out[], struct AES_KEY const *in);
  24. asmlinkage void bsaes_dec_key_convert(u8 out[], struct AES_KEY const *in);
  25. asmlinkage void bsaes_cbc_encrypt(u8 const in[], u8 out[], u32 bytes,
  26. struct BS_KEY *key, u8 iv[]);
  27. asmlinkage void bsaes_ctr32_encrypt_blocks(u8 const in[], u8 out[], u32 blocks,
  28. struct BS_KEY *key, u8 const iv[]);
  29. asmlinkage void bsaes_xts_encrypt(u8 const in[], u8 out[], u32 bytes,
  30. struct BS_KEY *key, u8 tweak[]);
  31. asmlinkage void bsaes_xts_decrypt(u8 const in[], u8 out[], u32 bytes,
  32. struct BS_KEY *key, u8 tweak[]);
  33. struct aesbs_cbc_ctx {
  34. struct AES_KEY enc;
  35. struct BS_KEY dec;
  36. };
  37. struct aesbs_ctr_ctx {
  38. struct BS_KEY enc;
  39. };
  40. struct aesbs_xts_ctx {
  41. struct BS_KEY enc;
  42. struct BS_KEY dec;
  43. struct AES_KEY twkey;
  44. };
  45. static int aesbs_cbc_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  46. unsigned int key_len)
  47. {
  48. struct aesbs_cbc_ctx *ctx = crypto_tfm_ctx(tfm);
  49. int bits = key_len * 8;
  50. if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc)) {
  51. tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  52. return -EINVAL;
  53. }
  54. ctx->dec.rk = ctx->enc;
  55. private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk);
  56. ctx->dec.converted = 0;
  57. return 0;
  58. }
  59. static int aesbs_ctr_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  60. unsigned int key_len)
  61. {
  62. struct aesbs_ctr_ctx *ctx = crypto_tfm_ctx(tfm);
  63. int bits = key_len * 8;
  64. if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
  65. tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  66. return -EINVAL;
  67. }
  68. ctx->enc.converted = 0;
  69. return 0;
  70. }
  71. static int aesbs_xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  72. unsigned int key_len)
  73. {
  74. struct aesbs_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  75. int bits = key_len * 4;
  76. int err;
  77. err = xts_check_key(tfm, in_key, key_len);
  78. if (err)
  79. return err;
  80. if (private_AES_set_encrypt_key(in_key, bits, &ctx->enc.rk)) {
  81. tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  82. return -EINVAL;
  83. }
  84. ctx->dec.rk = ctx->enc.rk;
  85. private_AES_set_decrypt_key(in_key, bits, &ctx->dec.rk);
  86. private_AES_set_encrypt_key(in_key + key_len / 2, bits, &ctx->twkey);
  87. ctx->enc.converted = ctx->dec.converted = 0;
  88. return 0;
  89. }
  90. static int aesbs_cbc_encrypt(struct blkcipher_desc *desc,
  91. struct scatterlist *dst,
  92. struct scatterlist *src, unsigned int nbytes)
  93. {
  94. struct aesbs_cbc_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  95. struct blkcipher_walk walk;
  96. int err;
  97. blkcipher_walk_init(&walk, dst, src, nbytes);
  98. err = blkcipher_walk_virt(desc, &walk);
  99. while (walk.nbytes) {
  100. u32 blocks = walk.nbytes / AES_BLOCK_SIZE;
  101. u8 *src = walk.src.virt.addr;
  102. if (walk.dst.virt.addr == walk.src.virt.addr) {
  103. u8 *iv = walk.iv;
  104. do {
  105. crypto_xor(src, iv, AES_BLOCK_SIZE);
  106. AES_encrypt(src, src, &ctx->enc);
  107. iv = src;
  108. src += AES_BLOCK_SIZE;
  109. } while (--blocks);
  110. memcpy(walk.iv, iv, AES_BLOCK_SIZE);
  111. } else {
  112. u8 *dst = walk.dst.virt.addr;
  113. do {
  114. crypto_xor(walk.iv, src, AES_BLOCK_SIZE);
  115. AES_encrypt(walk.iv, dst, &ctx->enc);
  116. memcpy(walk.iv, dst, AES_BLOCK_SIZE);
  117. src += AES_BLOCK_SIZE;
  118. dst += AES_BLOCK_SIZE;
  119. } while (--blocks);
  120. }
  121. err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  122. }
  123. return err;
  124. }
  125. static int aesbs_cbc_decrypt(struct blkcipher_desc *desc,
  126. struct scatterlist *dst,
  127. struct scatterlist *src, unsigned int nbytes)
  128. {
  129. struct aesbs_cbc_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  130. struct blkcipher_walk walk;
  131. int err;
  132. blkcipher_walk_init(&walk, dst, src, nbytes);
  133. err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
  134. while ((walk.nbytes / AES_BLOCK_SIZE) >= 8) {
  135. kernel_neon_begin();
  136. bsaes_cbc_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
  137. walk.nbytes, &ctx->dec, walk.iv);
  138. kernel_neon_end();
  139. err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  140. }
  141. while (walk.nbytes) {
  142. u32 blocks = walk.nbytes / AES_BLOCK_SIZE;
  143. u8 *dst = walk.dst.virt.addr;
  144. u8 *src = walk.src.virt.addr;
  145. u8 bk[2][AES_BLOCK_SIZE];
  146. u8 *iv = walk.iv;
  147. do {
  148. if (walk.dst.virt.addr == walk.src.virt.addr)
  149. memcpy(bk[blocks & 1], src, AES_BLOCK_SIZE);
  150. AES_decrypt(src, dst, &ctx->dec.rk);
  151. crypto_xor(dst, iv, AES_BLOCK_SIZE);
  152. if (walk.dst.virt.addr == walk.src.virt.addr)
  153. iv = bk[blocks & 1];
  154. else
  155. iv = src;
  156. dst += AES_BLOCK_SIZE;
  157. src += AES_BLOCK_SIZE;
  158. } while (--blocks);
  159. err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  160. }
  161. return err;
  162. }
  163. static void inc_be128_ctr(__be32 ctr[], u32 addend)
  164. {
  165. int i;
  166. for (i = 3; i >= 0; i--, addend = 1) {
  167. u32 n = be32_to_cpu(ctr[i]) + addend;
  168. ctr[i] = cpu_to_be32(n);
  169. if (n >= addend)
  170. break;
  171. }
  172. }
  173. static int aesbs_ctr_encrypt(struct blkcipher_desc *desc,
  174. struct scatterlist *dst, struct scatterlist *src,
  175. unsigned int nbytes)
  176. {
  177. struct aesbs_ctr_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  178. struct blkcipher_walk walk;
  179. u32 blocks;
  180. int err;
  181. blkcipher_walk_init(&walk, dst, src, nbytes);
  182. err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
  183. while ((blocks = walk.nbytes / AES_BLOCK_SIZE)) {
  184. u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  185. __be32 *ctr = (__be32 *)walk.iv;
  186. u32 headroom = UINT_MAX - be32_to_cpu(ctr[3]);
  187. /* avoid 32 bit counter overflow in the NEON code */
  188. if (unlikely(headroom < blocks)) {
  189. blocks = headroom + 1;
  190. tail = walk.nbytes - blocks * AES_BLOCK_SIZE;
  191. }
  192. kernel_neon_begin();
  193. bsaes_ctr32_encrypt_blocks(walk.src.virt.addr,
  194. walk.dst.virt.addr, blocks,
  195. &ctx->enc, walk.iv);
  196. kernel_neon_end();
  197. inc_be128_ctr(ctr, blocks);
  198. nbytes -= blocks * AES_BLOCK_SIZE;
  199. if (nbytes && nbytes == tail && nbytes <= AES_BLOCK_SIZE)
  200. break;
  201. err = blkcipher_walk_done(desc, &walk, tail);
  202. }
  203. if (walk.nbytes) {
  204. u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
  205. u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
  206. u8 ks[AES_BLOCK_SIZE];
  207. AES_encrypt(walk.iv, ks, &ctx->enc.rk);
  208. if (tdst != tsrc)
  209. memcpy(tdst, tsrc, nbytes);
  210. crypto_xor(tdst, ks, nbytes);
  211. err = blkcipher_walk_done(desc, &walk, 0);
  212. }
  213. return err;
  214. }
  215. static int aesbs_xts_encrypt(struct blkcipher_desc *desc,
  216. struct scatterlist *dst,
  217. struct scatterlist *src, unsigned int nbytes)
  218. {
  219. struct aesbs_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  220. struct blkcipher_walk walk;
  221. int err;
  222. blkcipher_walk_init(&walk, dst, src, nbytes);
  223. err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
  224. /* generate the initial tweak */
  225. AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
  226. while (walk.nbytes) {
  227. kernel_neon_begin();
  228. bsaes_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
  229. walk.nbytes, &ctx->enc, walk.iv);
  230. kernel_neon_end();
  231. err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  232. }
  233. return err;
  234. }
  235. static int aesbs_xts_decrypt(struct blkcipher_desc *desc,
  236. struct scatterlist *dst,
  237. struct scatterlist *src, unsigned int nbytes)
  238. {
  239. struct aesbs_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  240. struct blkcipher_walk walk;
  241. int err;
  242. blkcipher_walk_init(&walk, dst, src, nbytes);
  243. err = blkcipher_walk_virt_block(desc, &walk, 8 * AES_BLOCK_SIZE);
  244. /* generate the initial tweak */
  245. AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
  246. while (walk.nbytes) {
  247. kernel_neon_begin();
  248. bsaes_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
  249. walk.nbytes, &ctx->dec, walk.iv);
  250. kernel_neon_end();
  251. err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  252. }
  253. return err;
  254. }
  255. static struct crypto_alg aesbs_algs[] = { {
  256. .cra_name = "__cbc-aes-neonbs",
  257. .cra_driver_name = "__driver-cbc-aes-neonbs",
  258. .cra_priority = 0,
  259. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
  260. CRYPTO_ALG_INTERNAL,
  261. .cra_blocksize = AES_BLOCK_SIZE,
  262. .cra_ctxsize = sizeof(struct aesbs_cbc_ctx),
  263. .cra_alignmask = 7,
  264. .cra_type = &crypto_blkcipher_type,
  265. .cra_module = THIS_MODULE,
  266. .cra_blkcipher = {
  267. .min_keysize = AES_MIN_KEY_SIZE,
  268. .max_keysize = AES_MAX_KEY_SIZE,
  269. .ivsize = AES_BLOCK_SIZE,
  270. .setkey = aesbs_cbc_set_key,
  271. .encrypt = aesbs_cbc_encrypt,
  272. .decrypt = aesbs_cbc_decrypt,
  273. },
  274. }, {
  275. .cra_name = "__ctr-aes-neonbs",
  276. .cra_driver_name = "__driver-ctr-aes-neonbs",
  277. .cra_priority = 0,
  278. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
  279. CRYPTO_ALG_INTERNAL,
  280. .cra_blocksize = 1,
  281. .cra_ctxsize = sizeof(struct aesbs_ctr_ctx),
  282. .cra_alignmask = 7,
  283. .cra_type = &crypto_blkcipher_type,
  284. .cra_module = THIS_MODULE,
  285. .cra_blkcipher = {
  286. .min_keysize = AES_MIN_KEY_SIZE,
  287. .max_keysize = AES_MAX_KEY_SIZE,
  288. .ivsize = AES_BLOCK_SIZE,
  289. .setkey = aesbs_ctr_set_key,
  290. .encrypt = aesbs_ctr_encrypt,
  291. .decrypt = aesbs_ctr_encrypt,
  292. },
  293. }, {
  294. .cra_name = "__xts-aes-neonbs",
  295. .cra_driver_name = "__driver-xts-aes-neonbs",
  296. .cra_priority = 0,
  297. .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
  298. CRYPTO_ALG_INTERNAL,
  299. .cra_blocksize = AES_BLOCK_SIZE,
  300. .cra_ctxsize = sizeof(struct aesbs_xts_ctx),
  301. .cra_alignmask = 7,
  302. .cra_type = &crypto_blkcipher_type,
  303. .cra_module = THIS_MODULE,
  304. .cra_blkcipher = {
  305. .min_keysize = 2 * AES_MIN_KEY_SIZE,
  306. .max_keysize = 2 * AES_MAX_KEY_SIZE,
  307. .ivsize = AES_BLOCK_SIZE,
  308. .setkey = aesbs_xts_set_key,
  309. .encrypt = aesbs_xts_encrypt,
  310. .decrypt = aesbs_xts_decrypt,
  311. },
  312. }, {
  313. .cra_name = "cbc(aes)",
  314. .cra_driver_name = "cbc-aes-neonbs",
  315. .cra_priority = 250,
  316. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  317. .cra_blocksize = AES_BLOCK_SIZE,
  318. .cra_ctxsize = sizeof(struct async_helper_ctx),
  319. .cra_alignmask = 7,
  320. .cra_type = &crypto_ablkcipher_type,
  321. .cra_module = THIS_MODULE,
  322. .cra_init = ablk_init,
  323. .cra_exit = ablk_exit,
  324. .cra_ablkcipher = {
  325. .min_keysize = AES_MIN_KEY_SIZE,
  326. .max_keysize = AES_MAX_KEY_SIZE,
  327. .ivsize = AES_BLOCK_SIZE,
  328. .setkey = ablk_set_key,
  329. .encrypt = __ablk_encrypt,
  330. .decrypt = ablk_decrypt,
  331. }
  332. }, {
  333. .cra_name = "ctr(aes)",
  334. .cra_driver_name = "ctr-aes-neonbs",
  335. .cra_priority = 250,
  336. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  337. .cra_blocksize = 1,
  338. .cra_ctxsize = sizeof(struct async_helper_ctx),
  339. .cra_alignmask = 7,
  340. .cra_type = &crypto_ablkcipher_type,
  341. .cra_module = THIS_MODULE,
  342. .cra_init = ablk_init,
  343. .cra_exit = ablk_exit,
  344. .cra_ablkcipher = {
  345. .min_keysize = AES_MIN_KEY_SIZE,
  346. .max_keysize = AES_MAX_KEY_SIZE,
  347. .ivsize = AES_BLOCK_SIZE,
  348. .setkey = ablk_set_key,
  349. .encrypt = ablk_encrypt,
  350. .decrypt = ablk_decrypt,
  351. }
  352. }, {
  353. .cra_name = "xts(aes)",
  354. .cra_driver_name = "xts-aes-neonbs",
  355. .cra_priority = 250,
  356. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  357. .cra_blocksize = AES_BLOCK_SIZE,
  358. .cra_ctxsize = sizeof(struct async_helper_ctx),
  359. .cra_alignmask = 7,
  360. .cra_type = &crypto_ablkcipher_type,
  361. .cra_module = THIS_MODULE,
  362. .cra_init = ablk_init,
  363. .cra_exit = ablk_exit,
  364. .cra_ablkcipher = {
  365. .min_keysize = 2 * AES_MIN_KEY_SIZE,
  366. .max_keysize = 2 * AES_MAX_KEY_SIZE,
  367. .ivsize = AES_BLOCK_SIZE,
  368. .setkey = ablk_set_key,
  369. .encrypt = ablk_encrypt,
  370. .decrypt = ablk_decrypt,
  371. }
  372. } };
  373. static int __init aesbs_mod_init(void)
  374. {
  375. if (!cpu_has_neon())
  376. return -ENODEV;
  377. return crypto_register_algs(aesbs_algs, ARRAY_SIZE(aesbs_algs));
  378. }
  379. static void __exit aesbs_mod_exit(void)
  380. {
  381. crypto_unregister_algs(aesbs_algs, ARRAY_SIZE(aesbs_algs));
  382. }
  383. module_init(aesbs_mod_init);
  384. module_exit(aesbs_mod_exit);
  385. MODULE_DESCRIPTION("Bit sliced AES in CBC/CTR/XTS modes using NEON");
  386. MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  387. MODULE_LICENSE("GPL");