cast6_avx_glue.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * Glue Code for the AVX assembler implemention of the Cast6 Cipher
  3. *
  4. * Copyright (C) 2012 Johannes Goetzfried
  5. * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
  6. *
  7. * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  22. * USA
  23. *
  24. */
  25. #include <linux/module.h>
  26. #include <linux/types.h>
  27. #include <linux/crypto.h>
  28. #include <linux/err.h>
  29. #include <crypto/algapi.h>
  30. #include <crypto/cast6.h>
  31. #include <crypto/internal/simd.h>
  32. #include <crypto/xts.h>
  33. #include <asm/crypto/glue_helper.h>
  34. #define CAST6_PARALLEL_BLOCKS 8
  35. asmlinkage void cast6_ecb_enc_8way(struct cast6_ctx *ctx, u8 *dst,
  36. const u8 *src);
  37. asmlinkage void cast6_ecb_dec_8way(struct cast6_ctx *ctx, u8 *dst,
  38. const u8 *src);
  39. asmlinkage void cast6_cbc_dec_8way(struct cast6_ctx *ctx, u8 *dst,
  40. const u8 *src);
  41. asmlinkage void cast6_ctr_8way(struct cast6_ctx *ctx, u8 *dst, const u8 *src,
  42. le128 *iv);
  43. asmlinkage void cast6_xts_enc_8way(struct cast6_ctx *ctx, u8 *dst,
  44. const u8 *src, le128 *iv);
  45. asmlinkage void cast6_xts_dec_8way(struct cast6_ctx *ctx, u8 *dst,
  46. const u8 *src, le128 *iv);
  47. static int cast6_setkey_skcipher(struct crypto_skcipher *tfm,
  48. const u8 *key, unsigned int keylen)
  49. {
  50. return cast6_setkey(&tfm->base, key, keylen);
  51. }
  52. static void cast6_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv)
  53. {
  54. glue_xts_crypt_128bit_one(ctx, dst, src, iv,
  55. GLUE_FUNC_CAST(__cast6_encrypt));
  56. }
  57. static void cast6_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv)
  58. {
  59. glue_xts_crypt_128bit_one(ctx, dst, src, iv,
  60. GLUE_FUNC_CAST(__cast6_decrypt));
  61. }
  62. static void cast6_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv)
  63. {
  64. be128 ctrblk;
  65. le128_to_be128(&ctrblk, iv);
  66. le128_inc(iv);
  67. __cast6_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk);
  68. u128_xor(dst, src, (u128 *)&ctrblk);
  69. }
  70. static const struct common_glue_ctx cast6_enc = {
  71. .num_funcs = 2,
  72. .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  73. .funcs = { {
  74. .num_blocks = CAST6_PARALLEL_BLOCKS,
  75. .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_ecb_enc_8way) }
  76. }, {
  77. .num_blocks = 1,
  78. .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_encrypt) }
  79. } }
  80. };
  81. static const struct common_glue_ctx cast6_ctr = {
  82. .num_funcs = 2,
  83. .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  84. .funcs = { {
  85. .num_blocks = CAST6_PARALLEL_BLOCKS,
  86. .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_ctr_8way) }
  87. }, {
  88. .num_blocks = 1,
  89. .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_crypt_ctr) }
  90. } }
  91. };
  92. static const struct common_glue_ctx cast6_enc_xts = {
  93. .num_funcs = 2,
  94. .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  95. .funcs = { {
  96. .num_blocks = CAST6_PARALLEL_BLOCKS,
  97. .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_enc_8way) }
  98. }, {
  99. .num_blocks = 1,
  100. .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_enc) }
  101. } }
  102. };
  103. static const struct common_glue_ctx cast6_dec = {
  104. .num_funcs = 2,
  105. .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  106. .funcs = { {
  107. .num_blocks = CAST6_PARALLEL_BLOCKS,
  108. .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_ecb_dec_8way) }
  109. }, {
  110. .num_blocks = 1,
  111. .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_decrypt) }
  112. } }
  113. };
  114. static const struct common_glue_ctx cast6_dec_cbc = {
  115. .num_funcs = 2,
  116. .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  117. .funcs = { {
  118. .num_blocks = CAST6_PARALLEL_BLOCKS,
  119. .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(cast6_cbc_dec_8way) }
  120. }, {
  121. .num_blocks = 1,
  122. .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__cast6_decrypt) }
  123. } }
  124. };
  125. static const struct common_glue_ctx cast6_dec_xts = {
  126. .num_funcs = 2,
  127. .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  128. .funcs = { {
  129. .num_blocks = CAST6_PARALLEL_BLOCKS,
  130. .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_dec_8way) }
  131. }, {
  132. .num_blocks = 1,
  133. .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_dec) }
  134. } }
  135. };
  136. static int ecb_encrypt(struct skcipher_request *req)
  137. {
  138. return glue_ecb_req_128bit(&cast6_enc, req);
  139. }
  140. static int ecb_decrypt(struct skcipher_request *req)
  141. {
  142. return glue_ecb_req_128bit(&cast6_dec, req);
  143. }
  144. static int cbc_encrypt(struct skcipher_request *req)
  145. {
  146. return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(__cast6_encrypt),
  147. req);
  148. }
  149. static int cbc_decrypt(struct skcipher_request *req)
  150. {
  151. return glue_cbc_decrypt_req_128bit(&cast6_dec_cbc, req);
  152. }
  153. static int ctr_crypt(struct skcipher_request *req)
  154. {
  155. return glue_ctr_req_128bit(&cast6_ctr, req);
  156. }
  157. struct cast6_xts_ctx {
  158. struct cast6_ctx tweak_ctx;
  159. struct cast6_ctx crypt_ctx;
  160. };
  161. static int xts_cast6_setkey(struct crypto_skcipher *tfm, const u8 *key,
  162. unsigned int keylen)
  163. {
  164. struct cast6_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
  165. u32 *flags = &tfm->base.crt_flags;
  166. int err;
  167. err = xts_verify_key(tfm, key, keylen);
  168. if (err)
  169. return err;
  170. /* first half of xts-key is for crypt */
  171. err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
  172. if (err)
  173. return err;
  174. /* second half of xts-key is for tweak */
  175. return __cast6_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2,
  176. flags);
  177. }
  178. static int xts_encrypt(struct skcipher_request *req)
  179. {
  180. struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
  181. struct cast6_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
  182. return glue_xts_req_128bit(&cast6_enc_xts, req,
  183. XTS_TWEAK_CAST(__cast6_encrypt),
  184. &ctx->tweak_ctx, &ctx->crypt_ctx);
  185. }
  186. static int xts_decrypt(struct skcipher_request *req)
  187. {
  188. struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
  189. struct cast6_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
  190. return glue_xts_req_128bit(&cast6_dec_xts, req,
  191. XTS_TWEAK_CAST(__cast6_encrypt),
  192. &ctx->tweak_ctx, &ctx->crypt_ctx);
  193. }
  194. static struct skcipher_alg cast6_algs[] = {
  195. {
  196. .base.cra_name = "__ecb(cast6)",
  197. .base.cra_driver_name = "__ecb-cast6-avx",
  198. .base.cra_priority = 200,
  199. .base.cra_flags = CRYPTO_ALG_INTERNAL,
  200. .base.cra_blocksize = CAST6_BLOCK_SIZE,
  201. .base.cra_ctxsize = sizeof(struct cast6_ctx),
  202. .base.cra_module = THIS_MODULE,
  203. .min_keysize = CAST6_MIN_KEY_SIZE,
  204. .max_keysize = CAST6_MAX_KEY_SIZE,
  205. .setkey = cast6_setkey_skcipher,
  206. .encrypt = ecb_encrypt,
  207. .decrypt = ecb_decrypt,
  208. }, {
  209. .base.cra_name = "__cbc(cast6)",
  210. .base.cra_driver_name = "__cbc-cast6-avx",
  211. .base.cra_priority = 200,
  212. .base.cra_flags = CRYPTO_ALG_INTERNAL,
  213. .base.cra_blocksize = CAST6_BLOCK_SIZE,
  214. .base.cra_ctxsize = sizeof(struct cast6_ctx),
  215. .base.cra_module = THIS_MODULE,
  216. .min_keysize = CAST6_MIN_KEY_SIZE,
  217. .max_keysize = CAST6_MAX_KEY_SIZE,
  218. .ivsize = CAST6_BLOCK_SIZE,
  219. .setkey = cast6_setkey_skcipher,
  220. .encrypt = cbc_encrypt,
  221. .decrypt = cbc_decrypt,
  222. }, {
  223. .base.cra_name = "__ctr(cast6)",
  224. .base.cra_driver_name = "__ctr-cast6-avx",
  225. .base.cra_priority = 200,
  226. .base.cra_flags = CRYPTO_ALG_INTERNAL,
  227. .base.cra_blocksize = 1,
  228. .base.cra_ctxsize = sizeof(struct cast6_ctx),
  229. .base.cra_module = THIS_MODULE,
  230. .min_keysize = CAST6_MIN_KEY_SIZE,
  231. .max_keysize = CAST6_MAX_KEY_SIZE,
  232. .ivsize = CAST6_BLOCK_SIZE,
  233. .chunksize = CAST6_BLOCK_SIZE,
  234. .setkey = cast6_setkey_skcipher,
  235. .encrypt = ctr_crypt,
  236. .decrypt = ctr_crypt,
  237. }, {
  238. .base.cra_name = "__xts(cast6)",
  239. .base.cra_driver_name = "__xts-cast6-avx",
  240. .base.cra_priority = 200,
  241. .base.cra_flags = CRYPTO_ALG_INTERNAL,
  242. .base.cra_blocksize = CAST6_BLOCK_SIZE,
  243. .base.cra_ctxsize = sizeof(struct cast6_xts_ctx),
  244. .base.cra_module = THIS_MODULE,
  245. .min_keysize = 2 * CAST6_MIN_KEY_SIZE,
  246. .max_keysize = 2 * CAST6_MAX_KEY_SIZE,
  247. .ivsize = CAST6_BLOCK_SIZE,
  248. .setkey = xts_cast6_setkey,
  249. .encrypt = xts_encrypt,
  250. .decrypt = xts_decrypt,
  251. },
  252. };
  253. static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)];
  254. static int __init cast6_init(void)
  255. {
  256. const char *feature_name;
  257. if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
  258. &feature_name)) {
  259. pr_info("CPU feature '%s' is not supported.\n", feature_name);
  260. return -ENODEV;
  261. }
  262. return simd_register_skciphers_compat(cast6_algs,
  263. ARRAY_SIZE(cast6_algs),
  264. cast6_simd_algs);
  265. }
  266. static void __exit cast6_exit(void)
  267. {
  268. simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
  269. cast6_simd_algs);
  270. }
  271. module_init(cast6_init);
  272. module_exit(cast6_exit);
  273. MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
  274. MODULE_LICENSE("GPL");
  275. MODULE_ALIAS_CRYPTO("cast6");