cptvf_algs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * Copyright (C) 2016 Cavium, Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of version 2 of the GNU General Public License
  6. * as published by the Free Software Foundation.
  7. */
  8. #include <crypto/aes.h>
  9. #include <crypto/algapi.h>
  10. #include <crypto/authenc.h>
  11. #include <crypto/cryptd.h>
  12. #include <crypto/crypto_wq.h>
  13. #include <crypto/des.h>
  14. #include <crypto/xts.h>
  15. #include <linux/crypto.h>
  16. #include <linux/err.h>
  17. #include <linux/list.h>
  18. #include <linux/scatterlist.h>
  19. #include "cptvf.h"
  20. #include "cptvf_algs.h"
  21. struct cpt_device_handle {
  22. void *cdev[MAX_DEVICES];
  23. u32 dev_count;
  24. };
  25. static struct cpt_device_handle dev_handle;
  26. static void cvm_callback(u32 status, void *arg)
  27. {
  28. struct crypto_async_request *req = (struct crypto_async_request *)arg;
  29. req->complete(req, !status);
  30. }
  31. static inline void update_input_iv(struct cpt_request_info *req_info,
  32. u8 *iv, u32 enc_iv_len,
  33. u32 *argcnt)
  34. {
  35. /* Setting the iv information */
  36. req_info->in[*argcnt].vptr = (void *)iv;
  37. req_info->in[*argcnt].size = enc_iv_len;
  38. req_info->req.dlen += enc_iv_len;
  39. ++(*argcnt);
  40. }
  41. static inline void update_output_iv(struct cpt_request_info *req_info,
  42. u8 *iv, u32 enc_iv_len,
  43. u32 *argcnt)
  44. {
  45. /* Setting the iv information */
  46. req_info->out[*argcnt].vptr = (void *)iv;
  47. req_info->out[*argcnt].size = enc_iv_len;
  48. req_info->rlen += enc_iv_len;
  49. ++(*argcnt);
  50. }
  51. static inline void update_input_data(struct cpt_request_info *req_info,
  52. struct scatterlist *inp_sg,
  53. u32 nbytes, u32 *argcnt)
  54. {
  55. req_info->req.dlen += nbytes;
  56. while (nbytes) {
  57. u32 len = min(nbytes, inp_sg->length);
  58. u8 *ptr = sg_virt(inp_sg);
  59. req_info->in[*argcnt].vptr = (void *)ptr;
  60. req_info->in[*argcnt].size = len;
  61. nbytes -= len;
  62. ++(*argcnt);
  63. ++inp_sg;
  64. }
  65. }
  66. static inline void update_output_data(struct cpt_request_info *req_info,
  67. struct scatterlist *outp_sg,
  68. u32 nbytes, u32 *argcnt)
  69. {
  70. req_info->rlen += nbytes;
  71. while (nbytes) {
  72. u32 len = min(nbytes, outp_sg->length);
  73. u8 *ptr = sg_virt(outp_sg);
  74. req_info->out[*argcnt].vptr = (void *)ptr;
  75. req_info->out[*argcnt].size = len;
  76. nbytes -= len;
  77. ++(*argcnt);
  78. ++outp_sg;
  79. }
  80. }
  81. static inline u32 create_ctx_hdr(struct ablkcipher_request *req, u32 enc,
  82. u32 cipher_type, u32 aes_key_type,
  83. u32 *argcnt)
  84. {
  85. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  86. struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  87. struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
  88. struct fc_context *fctx = &rctx->fctx;
  89. u64 *offset_control = &rctx->control_word;
  90. u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm);
  91. struct cpt_request_info *req_info = &rctx->cpt_req;
  92. u64 *ctrl_flags = NULL;
  93. req_info->ctrl.s.grp = 0;
  94. req_info->ctrl.s.dma_mode = DMA_GATHER_SCATTER;
  95. req_info->ctrl.s.se_req = SE_CORE_REQ;
  96. req_info->req.opcode.s.major = MAJOR_OP_FC |
  97. DMA_MODE_FLAG(DMA_GATHER_SCATTER);
  98. if (enc)
  99. req_info->req.opcode.s.minor = 2;
  100. else
  101. req_info->req.opcode.s.minor = 3;
  102. req_info->req.param1 = req->nbytes; /* Encryption Data length */
  103. req_info->req.param2 = 0; /*Auth data length */
  104. fctx->enc.enc_ctrl.e.enc_cipher = cipher_type;
  105. fctx->enc.enc_ctrl.e.aes_key = aes_key_type;
  106. fctx->enc.enc_ctrl.e.iv_source = FROM_DPTR;
  107. if (cipher_type == AES_XTS)
  108. memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len * 2);
  109. else
  110. memcpy(fctx->enc.encr_key, ctx->enc_key, ctx->key_len);
  111. ctrl_flags = (u64 *)&fctx->enc.enc_ctrl.flags;
  112. *ctrl_flags = cpu_to_be64(*ctrl_flags);
  113. *offset_control = cpu_to_be64(((u64)(enc_iv_len) << 16));
  114. /* Storing Packet Data Information in offset
  115. * Control Word First 8 bytes
  116. */
  117. req_info->in[*argcnt].vptr = (u8 *)offset_control;
  118. req_info->in[*argcnt].size = CONTROL_WORD_LEN;
  119. req_info->req.dlen += CONTROL_WORD_LEN;
  120. ++(*argcnt);
  121. req_info->in[*argcnt].vptr = (u8 *)fctx;
  122. req_info->in[*argcnt].size = sizeof(struct fc_context);
  123. req_info->req.dlen += sizeof(struct fc_context);
  124. ++(*argcnt);
  125. return 0;
  126. }
  127. static inline u32 create_input_list(struct ablkcipher_request *req, u32 enc,
  128. u32 cipher_type, u32 aes_key_type,
  129. u32 enc_iv_len)
  130. {
  131. struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
  132. struct cpt_request_info *req_info = &rctx->cpt_req;
  133. u32 argcnt = 0;
  134. create_ctx_hdr(req, enc, cipher_type, aes_key_type, &argcnt);
  135. update_input_iv(req_info, req->info, enc_iv_len, &argcnt);
  136. update_input_data(req_info, req->src, req->nbytes, &argcnt);
  137. req_info->incnt = argcnt;
  138. return 0;
  139. }
  140. static inline void store_cb_info(struct ablkcipher_request *req,
  141. struct cpt_request_info *req_info)
  142. {
  143. req_info->callback = (void *)cvm_callback;
  144. req_info->callback_arg = (void *)&req->base;
  145. }
  146. static inline void create_output_list(struct ablkcipher_request *req,
  147. u32 cipher_type,
  148. u32 enc_iv_len)
  149. {
  150. struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
  151. struct cpt_request_info *req_info = &rctx->cpt_req;
  152. u32 argcnt = 0;
  153. /* OUTPUT Buffer Processing
  154. * AES encryption/decryption output would be
  155. * received in the following format
  156. *
  157. * ------IV--------|------ENCRYPTED/DECRYPTED DATA-----|
  158. * [ 16 Bytes/ [ Request Enc/Dec/ DATA Len AES CBC ]
  159. */
  160. /* Reading IV information */
  161. update_output_iv(req_info, req->info, enc_iv_len, &argcnt);
  162. update_output_data(req_info, req->dst, req->nbytes, &argcnt);
  163. req_info->outcnt = argcnt;
  164. }
  165. static inline int cvm_enc_dec(struct ablkcipher_request *req, u32 enc,
  166. u32 cipher_type)
  167. {
  168. struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
  169. struct cvm_enc_ctx *ctx = crypto_ablkcipher_ctx(tfm);
  170. u32 key_type = AES_128_BIT;
  171. struct cvm_req_ctx *rctx = ablkcipher_request_ctx(req);
  172. u32 enc_iv_len = crypto_ablkcipher_ivsize(tfm);
  173. struct fc_context *fctx = &rctx->fctx;
  174. struct cpt_request_info *req_info = &rctx->cpt_req;
  175. void *cdev = NULL;
  176. int status;
  177. switch (ctx->key_len) {
  178. case 16:
  179. key_type = AES_128_BIT;
  180. break;
  181. case 24:
  182. key_type = AES_192_BIT;
  183. break;
  184. case 32:
  185. if (cipher_type == AES_XTS)
  186. key_type = AES_128_BIT;
  187. else
  188. key_type = AES_256_BIT;
  189. break;
  190. case 64:
  191. if (cipher_type == AES_XTS)
  192. key_type = AES_256_BIT;
  193. else
  194. return -EINVAL;
  195. break;
  196. default:
  197. return -EINVAL;
  198. }
  199. if (cipher_type == DES3_CBC)
  200. key_type = 0;
  201. memset(req_info, 0, sizeof(struct cpt_request_info));
  202. memset(fctx, 0, sizeof(struct fc_context));
  203. create_input_list(req, enc, cipher_type, key_type, enc_iv_len);
  204. create_output_list(req, cipher_type, enc_iv_len);
  205. store_cb_info(req, req_info);
  206. cdev = dev_handle.cdev[smp_processor_id()];
  207. status = cptvf_do_request(cdev, req_info);
  208. /* We perform an asynchronous send and once
  209. * the request is completed the driver would
  210. * intimate through registered call back functions
  211. */
  212. if (status)
  213. return status;
  214. else
  215. return -EINPROGRESS;
  216. }
  217. int cvm_des3_encrypt_cbc(struct ablkcipher_request *req)
  218. {
  219. return cvm_enc_dec(req, true, DES3_CBC);
  220. }
  221. int cvm_des3_decrypt_cbc(struct ablkcipher_request *req)
  222. {
  223. return cvm_enc_dec(req, false, DES3_CBC);
  224. }
  225. int cvm_aes_encrypt_xts(struct ablkcipher_request *req)
  226. {
  227. return cvm_enc_dec(req, true, AES_XTS);
  228. }
  229. int cvm_aes_decrypt_xts(struct ablkcipher_request *req)
  230. {
  231. return cvm_enc_dec(req, false, AES_XTS);
  232. }
  233. int cvm_aes_encrypt_cbc(struct ablkcipher_request *req)
  234. {
  235. return cvm_enc_dec(req, true, AES_CBC);
  236. }
  237. int cvm_aes_decrypt_cbc(struct ablkcipher_request *req)
  238. {
  239. return cvm_enc_dec(req, false, AES_CBC);
  240. }
  241. int cvm_xts_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
  242. u32 keylen)
  243. {
  244. struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
  245. struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
  246. int err;
  247. const u8 *key1 = key;
  248. const u8 *key2 = key + (keylen / 2);
  249. err = xts_check_key(tfm, key, keylen);
  250. if (err)
  251. return err;
  252. ctx->key_len = keylen;
  253. memcpy(ctx->enc_key, key1, keylen / 2);
  254. memcpy(ctx->enc_key + KEY2_OFFSET, key2, keylen / 2);
  255. return 0;
  256. }
  257. int cvm_enc_dec_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
  258. u32 keylen)
  259. {
  260. struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
  261. struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
  262. if ((keylen == 16) || (keylen == 24) || (keylen == 32)) {
  263. ctx->key_len = keylen;
  264. memcpy(ctx->enc_key, key, keylen);
  265. return 0;
  266. }
  267. crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
  268. return -EINVAL;
  269. }
  270. int cvm_enc_dec_init(struct crypto_tfm *tfm)
  271. {
  272. struct cvm_enc_ctx *ctx = crypto_tfm_ctx(tfm);
  273. memset(ctx, 0, sizeof(*ctx));
  274. tfm->crt_ablkcipher.reqsize = sizeof(struct cvm_req_ctx) +
  275. sizeof(struct ablkcipher_request);
  276. /* Additional memory for ablkcipher_request is
  277. * allocated since the cryptd daemon uses
  278. * this memory for request_ctx information
  279. */
  280. return 0;
  281. }
  282. struct crypto_alg algs[] = { {
  283. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  284. .cra_blocksize = AES_BLOCK_SIZE,
  285. .cra_ctxsize = sizeof(struct cvm_enc_ctx),
  286. .cra_alignmask = 7,
  287. .cra_priority = 4001,
  288. .cra_name = "xts(aes)",
  289. .cra_driver_name = "cavium-xts-aes",
  290. .cra_type = &crypto_ablkcipher_type,
  291. .cra_u = {
  292. .ablkcipher = {
  293. .ivsize = AES_BLOCK_SIZE,
  294. .min_keysize = 2 * AES_MIN_KEY_SIZE,
  295. .max_keysize = 2 * AES_MAX_KEY_SIZE,
  296. .setkey = cvm_xts_setkey,
  297. .encrypt = cvm_aes_encrypt_xts,
  298. .decrypt = cvm_aes_decrypt_xts,
  299. },
  300. },
  301. .cra_init = cvm_enc_dec_init,
  302. .cra_module = THIS_MODULE,
  303. }, {
  304. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  305. .cra_blocksize = AES_BLOCK_SIZE,
  306. .cra_ctxsize = sizeof(struct cvm_enc_ctx),
  307. .cra_alignmask = 7,
  308. .cra_priority = 4001,
  309. .cra_name = "cbc(aes)",
  310. .cra_driver_name = "cavium-cbc-aes",
  311. .cra_type = &crypto_ablkcipher_type,
  312. .cra_u = {
  313. .ablkcipher = {
  314. .ivsize = AES_BLOCK_SIZE,
  315. .min_keysize = AES_MIN_KEY_SIZE,
  316. .max_keysize = AES_MAX_KEY_SIZE,
  317. .setkey = cvm_enc_dec_setkey,
  318. .encrypt = cvm_aes_encrypt_cbc,
  319. .decrypt = cvm_aes_decrypt_cbc,
  320. },
  321. },
  322. .cra_init = cvm_enc_dec_init,
  323. .cra_module = THIS_MODULE,
  324. }, {
  325. .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
  326. .cra_blocksize = DES3_EDE_BLOCK_SIZE,
  327. .cra_ctxsize = sizeof(struct cvm_des3_ctx),
  328. .cra_alignmask = 7,
  329. .cra_priority = 4001,
  330. .cra_name = "cbc(des3_ede)",
  331. .cra_driver_name = "cavium-cbc-des3_ede",
  332. .cra_type = &crypto_ablkcipher_type,
  333. .cra_u = {
  334. .ablkcipher = {
  335. .min_keysize = DES3_EDE_KEY_SIZE,
  336. .max_keysize = DES3_EDE_KEY_SIZE,
  337. .ivsize = DES_BLOCK_SIZE,
  338. .setkey = cvm_enc_dec_setkey,
  339. .encrypt = cvm_des3_encrypt_cbc,
  340. .decrypt = cvm_des3_decrypt_cbc,
  341. },
  342. },
  343. .cra_init = cvm_enc_dec_init,
  344. .cra_module = THIS_MODULE,
  345. } };
  346. static inline int cav_register_algs(void)
  347. {
  348. int err = 0;
  349. err = crypto_register_algs(algs, ARRAY_SIZE(algs));
  350. if (err)
  351. return err;
  352. return 0;
  353. }
  354. static inline void cav_unregister_algs(void)
  355. {
  356. crypto_unregister_algs(algs, ARRAY_SIZE(algs));
  357. }
  358. int cvm_crypto_init(struct cpt_vf *cptvf)
  359. {
  360. struct pci_dev *pdev = cptvf->pdev;
  361. u32 dev_count;
  362. dev_count = dev_handle.dev_count;
  363. dev_handle.cdev[dev_count] = cptvf;
  364. dev_handle.dev_count++;
  365. if (dev_count == 3) {
  366. if (cav_register_algs()) {
  367. dev_err(&pdev->dev, "Error in registering crypto algorithms\n");
  368. return -EINVAL;
  369. }
  370. }
  371. return 0;
  372. }
  373. void cvm_crypto_exit(void)
  374. {
  375. u32 dev_count;
  376. dev_count = --dev_handle.dev_count;
  377. if (!dev_count)
  378. cav_unregister_algs();
  379. }