ccp-crypto-rsa.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
  4. *
  5. * Copyright (C) 2017 Advanced Micro Devices, Inc.
  6. *
  7. * Author: Gary R Hook <gary.hook@amd.com>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/sched.h>
  11. #include <linux/scatterlist.h>
  12. #include <linux/crypto.h>
  13. #include <crypto/algapi.h>
  14. #include <crypto/internal/rsa.h>
  15. #include <crypto/internal/akcipher.h>
  16. #include <crypto/akcipher.h>
  17. #include <crypto/scatterwalk.h>
  18. #include "ccp-crypto.h"
  19. static inline struct akcipher_request *akcipher_request_cast(
  20. struct crypto_async_request *req)
  21. {
  22. return container_of(req, struct akcipher_request, base);
  23. }
  24. static inline int ccp_copy_and_save_keypart(u8 **kpbuf, unsigned int *kplen,
  25. const u8 *buf, size_t sz)
  26. {
  27. int nskip;
  28. for (nskip = 0; nskip < sz; nskip++)
  29. if (buf[nskip])
  30. break;
  31. *kplen = sz - nskip;
  32. *kpbuf = kmemdup(buf + nskip, *kplen, GFP_KERNEL);
  33. if (!*kpbuf)
  34. return -ENOMEM;
  35. return 0;
  36. }
  37. static int ccp_rsa_complete(struct crypto_async_request *async_req, int ret)
  38. {
  39. struct akcipher_request *req = akcipher_request_cast(async_req);
  40. struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
  41. if (ret)
  42. return ret;
  43. req->dst_len = rctx->cmd.u.rsa.key_size >> 3;
  44. return 0;
  45. }
  46. static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
  47. {
  48. struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
  49. return ctx->u.rsa.n_len;
  50. }
  51. static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
  52. {
  53. struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
  54. struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
  55. struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx(req);
  56. int ret = 0;
  57. memset(&rctx->cmd, 0, sizeof(rctx->cmd));
  58. INIT_LIST_HEAD(&rctx->cmd.entry);
  59. rctx->cmd.engine = CCP_ENGINE_RSA;
  60. rctx->cmd.u.rsa.key_size = ctx->u.rsa.key_len; /* in bits */
  61. if (encrypt) {
  62. rctx->cmd.u.rsa.exp = &ctx->u.rsa.e_sg;
  63. rctx->cmd.u.rsa.exp_len = ctx->u.rsa.e_len;
  64. } else {
  65. rctx->cmd.u.rsa.exp = &ctx->u.rsa.d_sg;
  66. rctx->cmd.u.rsa.exp_len = ctx->u.rsa.d_len;
  67. }
  68. rctx->cmd.u.rsa.mod = &ctx->u.rsa.n_sg;
  69. rctx->cmd.u.rsa.mod_len = ctx->u.rsa.n_len;
  70. rctx->cmd.u.rsa.src = req->src;
  71. rctx->cmd.u.rsa.src_len = req->src_len;
  72. rctx->cmd.u.rsa.dst = req->dst;
  73. ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd);
  74. return ret;
  75. }
  76. static int ccp_rsa_encrypt(struct akcipher_request *req)
  77. {
  78. return ccp_rsa_crypt(req, true);
  79. }
  80. static int ccp_rsa_decrypt(struct akcipher_request *req)
  81. {
  82. return ccp_rsa_crypt(req, false);
  83. }
  84. static int ccp_check_key_length(unsigned int len)
  85. {
  86. /* In bits */
  87. if (len < 8 || len > 4096)
  88. return -EINVAL;
  89. return 0;
  90. }
  91. static void ccp_rsa_free_key_bufs(struct ccp_ctx *ctx)
  92. {
  93. /* Clean up old key data */
  94. kzfree(ctx->u.rsa.e_buf);
  95. ctx->u.rsa.e_buf = NULL;
  96. ctx->u.rsa.e_len = 0;
  97. kzfree(ctx->u.rsa.n_buf);
  98. ctx->u.rsa.n_buf = NULL;
  99. ctx->u.rsa.n_len = 0;
  100. kzfree(ctx->u.rsa.d_buf);
  101. ctx->u.rsa.d_buf = NULL;
  102. ctx->u.rsa.d_len = 0;
  103. }
  104. static int ccp_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
  105. unsigned int keylen, bool private)
  106. {
  107. struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
  108. struct rsa_key raw_key;
  109. int ret;
  110. ccp_rsa_free_key_bufs(ctx);
  111. memset(&raw_key, 0, sizeof(raw_key));
  112. /* Code borrowed from crypto/rsa.c */
  113. if (private)
  114. ret = rsa_parse_priv_key(&raw_key, key, keylen);
  115. else
  116. ret = rsa_parse_pub_key(&raw_key, key, keylen);
  117. if (ret)
  118. goto n_key;
  119. ret = ccp_copy_and_save_keypart(&ctx->u.rsa.n_buf, &ctx->u.rsa.n_len,
  120. raw_key.n, raw_key.n_sz);
  121. if (ret)
  122. goto key_err;
  123. sg_init_one(&ctx->u.rsa.n_sg, ctx->u.rsa.n_buf, ctx->u.rsa.n_len);
  124. ctx->u.rsa.key_len = ctx->u.rsa.n_len << 3; /* convert to bits */
  125. if (ccp_check_key_length(ctx->u.rsa.key_len)) {
  126. ret = -EINVAL;
  127. goto key_err;
  128. }
  129. ret = ccp_copy_and_save_keypart(&ctx->u.rsa.e_buf, &ctx->u.rsa.e_len,
  130. raw_key.e, raw_key.e_sz);
  131. if (ret)
  132. goto key_err;
  133. sg_init_one(&ctx->u.rsa.e_sg, ctx->u.rsa.e_buf, ctx->u.rsa.e_len);
  134. if (private) {
  135. ret = ccp_copy_and_save_keypart(&ctx->u.rsa.d_buf,
  136. &ctx->u.rsa.d_len,
  137. raw_key.d, raw_key.d_sz);
  138. if (ret)
  139. goto key_err;
  140. sg_init_one(&ctx->u.rsa.d_sg,
  141. ctx->u.rsa.d_buf, ctx->u.rsa.d_len);
  142. }
  143. return 0;
  144. key_err:
  145. ccp_rsa_free_key_bufs(ctx);
  146. n_key:
  147. return ret;
  148. }
  149. static int ccp_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,
  150. unsigned int keylen)
  151. {
  152. return ccp_rsa_setkey(tfm, key, keylen, true);
  153. }
  154. static int ccp_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,
  155. unsigned int keylen)
  156. {
  157. return ccp_rsa_setkey(tfm, key, keylen, false);
  158. }
  159. static int ccp_rsa_init_tfm(struct crypto_akcipher *tfm)
  160. {
  161. struct ccp_ctx *ctx = akcipher_tfm_ctx(tfm);
  162. akcipher_set_reqsize(tfm, sizeof(struct ccp_rsa_req_ctx));
  163. ctx->complete = ccp_rsa_complete;
  164. return 0;
  165. }
  166. static void ccp_rsa_exit_tfm(struct crypto_akcipher *tfm)
  167. {
  168. struct ccp_ctx *ctx = crypto_tfm_ctx(&tfm->base);
  169. ccp_rsa_free_key_bufs(ctx);
  170. }
  171. static struct akcipher_alg ccp_rsa_defaults = {
  172. .encrypt = ccp_rsa_encrypt,
  173. .decrypt = ccp_rsa_decrypt,
  174. .set_pub_key = ccp_rsa_setpubkey,
  175. .set_priv_key = ccp_rsa_setprivkey,
  176. .max_size = ccp_rsa_maxsize,
  177. .init = ccp_rsa_init_tfm,
  178. .exit = ccp_rsa_exit_tfm,
  179. .base = {
  180. .cra_name = "rsa",
  181. .cra_driver_name = "rsa-ccp",
  182. .cra_priority = CCP_CRA_PRIORITY,
  183. .cra_module = THIS_MODULE,
  184. .cra_ctxsize = 2 * sizeof(struct ccp_ctx),
  185. },
  186. };
  187. struct ccp_rsa_def {
  188. unsigned int version;
  189. const char *name;
  190. const char *driver_name;
  191. unsigned int reqsize;
  192. struct akcipher_alg *alg_defaults;
  193. };
  194. static struct ccp_rsa_def rsa_algs[] = {
  195. {
  196. .version = CCP_VERSION(3, 0),
  197. .name = "rsa",
  198. .driver_name = "rsa-ccp",
  199. .reqsize = sizeof(struct ccp_rsa_req_ctx),
  200. .alg_defaults = &ccp_rsa_defaults,
  201. }
  202. };
  203. static int ccp_register_rsa_alg(struct list_head *head,
  204. const struct ccp_rsa_def *def)
  205. {
  206. struct ccp_crypto_akcipher_alg *ccp_alg;
  207. struct akcipher_alg *alg;
  208. int ret;
  209. ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL);
  210. if (!ccp_alg)
  211. return -ENOMEM;
  212. INIT_LIST_HEAD(&ccp_alg->entry);
  213. alg = &ccp_alg->alg;
  214. *alg = *def->alg_defaults;
  215. snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
  216. snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
  217. def->driver_name);
  218. ret = crypto_register_akcipher(alg);
  219. if (ret) {
  220. pr_err("%s akcipher algorithm registration error (%d)\n",
  221. alg->base.cra_name, ret);
  222. kfree(ccp_alg);
  223. return ret;
  224. }
  225. list_add(&ccp_alg->entry, head);
  226. return 0;
  227. }
  228. int ccp_register_rsa_algs(struct list_head *head)
  229. {
  230. int i, ret;
  231. unsigned int ccpversion = ccp_version();
  232. /* Register the RSA algorithm in standard mode
  233. * This works for CCP v3 and later
  234. */
  235. for (i = 0; i < ARRAY_SIZE(rsa_algs); i++) {
  236. if (rsa_algs[i].version > ccpversion)
  237. continue;
  238. ret = ccp_register_rsa_alg(head, &rsa_algs[i]);
  239. if (ret)
  240. return ret;
  241. }
  242. return 0;
  243. }