public_key.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* In-software asymmetric public-key crypto subtype
  2. *
  3. * See Documentation/crypto/asymmetric-keys.txt
  4. *
  5. * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  6. * Written by David Howells (dhowells@redhat.com)
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public Licence
  10. * as published by the Free Software Foundation; either version
  11. * 2 of the Licence, or (at your option) any later version.
  12. */
  13. #define pr_fmt(fmt) "PKEY: "fmt
  14. #include <linux/module.h>
  15. #include <linux/export.h>
  16. #include <linux/kernel.h>
  17. #include <linux/slab.h>
  18. #include <linux/seq_file.h>
  19. #include <linux/scatterlist.h>
  20. #include <keys/asymmetric-subtype.h>
  21. #include <crypto/public_key.h>
  22. #include <crypto/akcipher.h>
  23. MODULE_DESCRIPTION("In-software asymmetric public-key subtype");
  24. MODULE_AUTHOR("Red Hat, Inc.");
  25. MODULE_LICENSE("GPL");
  26. /*
  27. * Provide a part of a description of the key for /proc/keys.
  28. */
  29. static void public_key_describe(const struct key *asymmetric_key,
  30. struct seq_file *m)
  31. {
  32. struct public_key *key = asymmetric_key->payload.data[asym_crypto];
  33. if (key)
  34. seq_printf(m, "%s.%s", key->id_type, key->pkey_algo);
  35. }
  36. /*
  37. * Destroy a public key algorithm key.
  38. */
  39. void public_key_free(struct public_key *key)
  40. {
  41. if (key) {
  42. kfree(key->key);
  43. kfree(key);
  44. }
  45. }
  46. EXPORT_SYMBOL_GPL(public_key_free);
  47. /*
  48. * Destroy a public key algorithm key.
  49. */
  50. static void public_key_destroy(void *payload0, void *payload3)
  51. {
  52. public_key_free(payload0);
  53. public_key_signature_free(payload3);
  54. }
  55. /*
  56. * Determine the crypto algorithm name.
  57. */
  58. static
  59. int software_key_determine_akcipher(const char *encoding,
  60. const char *hash_algo,
  61. const struct public_key *pkey,
  62. char alg_name[CRYPTO_MAX_ALG_NAME])
  63. {
  64. int n;
  65. if (strcmp(encoding, "pkcs1") == 0) {
  66. /* The data wangled by the RSA algorithm is typically padded
  67. * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
  68. * sec 8.2].
  69. */
  70. if (!hash_algo)
  71. n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
  72. "pkcs1pad(%s)",
  73. pkey->pkey_algo);
  74. else
  75. n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
  76. "pkcs1pad(%s,%s)",
  77. pkey->pkey_algo, hash_algo);
  78. return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
  79. }
  80. if (strcmp(encoding, "raw") == 0) {
  81. strcpy(alg_name, pkey->pkey_algo);
  82. return 0;
  83. }
  84. return -ENOPKG;
  85. }
  86. /*
  87. * Query information about a key.
  88. */
  89. static int software_key_query(const struct kernel_pkey_params *params,
  90. struct kernel_pkey_query *info)
  91. {
  92. struct crypto_akcipher *tfm;
  93. struct public_key *pkey = params->key->payload.data[asym_crypto];
  94. char alg_name[CRYPTO_MAX_ALG_NAME];
  95. int ret, len;
  96. ret = software_key_determine_akcipher(params->encoding,
  97. params->hash_algo,
  98. pkey, alg_name);
  99. if (ret < 0)
  100. return ret;
  101. tfm = crypto_alloc_akcipher(alg_name, 0, 0);
  102. if (IS_ERR(tfm))
  103. return PTR_ERR(tfm);
  104. if (pkey->key_is_private)
  105. ret = crypto_akcipher_set_priv_key(tfm,
  106. pkey->key, pkey->keylen);
  107. else
  108. ret = crypto_akcipher_set_pub_key(tfm,
  109. pkey->key, pkey->keylen);
  110. if (ret < 0)
  111. goto error_free_tfm;
  112. len = crypto_akcipher_maxsize(tfm);
  113. info->key_size = len * 8;
  114. info->max_data_size = len;
  115. info->max_sig_size = len;
  116. info->max_enc_size = len;
  117. info->max_dec_size = len;
  118. info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
  119. KEYCTL_SUPPORTS_VERIFY);
  120. if (pkey->key_is_private)
  121. info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
  122. KEYCTL_SUPPORTS_SIGN);
  123. ret = 0;
  124. error_free_tfm:
  125. crypto_free_akcipher(tfm);
  126. pr_devel("<==%s() = %d\n", __func__, ret);
  127. return ret;
  128. }
  129. /*
  130. * Do encryption, decryption and signing ops.
  131. */
  132. static int software_key_eds_op(struct kernel_pkey_params *params,
  133. const void *in, void *out)
  134. {
  135. const struct public_key *pkey = params->key->payload.data[asym_crypto];
  136. struct akcipher_request *req;
  137. struct crypto_akcipher *tfm;
  138. struct crypto_wait cwait;
  139. struct scatterlist in_sg, out_sg;
  140. char alg_name[CRYPTO_MAX_ALG_NAME];
  141. int ret;
  142. pr_devel("==>%s()\n", __func__);
  143. ret = software_key_determine_akcipher(params->encoding,
  144. params->hash_algo,
  145. pkey, alg_name);
  146. if (ret < 0)
  147. return ret;
  148. tfm = crypto_alloc_akcipher(alg_name, 0, 0);
  149. if (IS_ERR(tfm))
  150. return PTR_ERR(tfm);
  151. req = akcipher_request_alloc(tfm, GFP_KERNEL);
  152. if (!req)
  153. goto error_free_tfm;
  154. if (pkey->key_is_private)
  155. ret = crypto_akcipher_set_priv_key(tfm,
  156. pkey->key, pkey->keylen);
  157. else
  158. ret = crypto_akcipher_set_pub_key(tfm,
  159. pkey->key, pkey->keylen);
  160. if (ret)
  161. goto error_free_req;
  162. sg_init_one(&in_sg, in, params->in_len);
  163. sg_init_one(&out_sg, out, params->out_len);
  164. akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
  165. params->out_len);
  166. crypto_init_wait(&cwait);
  167. akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
  168. CRYPTO_TFM_REQ_MAY_SLEEP,
  169. crypto_req_done, &cwait);
  170. /* Perform the encryption calculation. */
  171. switch (params->op) {
  172. case kernel_pkey_encrypt:
  173. ret = crypto_akcipher_encrypt(req);
  174. break;
  175. case kernel_pkey_decrypt:
  176. ret = crypto_akcipher_decrypt(req);
  177. break;
  178. case kernel_pkey_sign:
  179. ret = crypto_akcipher_sign(req);
  180. break;
  181. default:
  182. BUG();
  183. }
  184. ret = crypto_wait_req(ret, &cwait);
  185. if (ret == 0)
  186. ret = req->dst_len;
  187. error_free_req:
  188. akcipher_request_free(req);
  189. error_free_tfm:
  190. crypto_free_akcipher(tfm);
  191. pr_devel("<==%s() = %d\n", __func__, ret);
  192. return ret;
  193. }
  194. /*
  195. * Verify a signature using a public key.
  196. */
  197. int public_key_verify_signature(const struct public_key *pkey,
  198. const struct public_key_signature *sig)
  199. {
  200. struct crypto_wait cwait;
  201. struct crypto_akcipher *tfm;
  202. struct akcipher_request *req;
  203. struct scatterlist sig_sg, digest_sg;
  204. char alg_name[CRYPTO_MAX_ALG_NAME];
  205. void *output;
  206. unsigned int outlen;
  207. int ret;
  208. pr_devel("==>%s()\n", __func__);
  209. BUG_ON(!pkey);
  210. BUG_ON(!sig);
  211. BUG_ON(!sig->s);
  212. ret = software_key_determine_akcipher(sig->encoding,
  213. sig->hash_algo,
  214. pkey, alg_name);
  215. if (ret < 0)
  216. return ret;
  217. tfm = crypto_alloc_akcipher(alg_name, 0, 0);
  218. if (IS_ERR(tfm))
  219. return PTR_ERR(tfm);
  220. ret = -ENOMEM;
  221. req = akcipher_request_alloc(tfm, GFP_KERNEL);
  222. if (!req)
  223. goto error_free_tfm;
  224. if (pkey->key_is_private)
  225. ret = crypto_akcipher_set_priv_key(tfm,
  226. pkey->key, pkey->keylen);
  227. else
  228. ret = crypto_akcipher_set_pub_key(tfm,
  229. pkey->key, pkey->keylen);
  230. if (ret)
  231. goto error_free_req;
  232. ret = -ENOMEM;
  233. outlen = crypto_akcipher_maxsize(tfm);
  234. output = kmalloc(outlen, GFP_KERNEL);
  235. if (!output)
  236. goto error_free_req;
  237. sg_init_one(&sig_sg, sig->s, sig->s_size);
  238. sg_init_one(&digest_sg, output, outlen);
  239. akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig->s_size,
  240. outlen);
  241. crypto_init_wait(&cwait);
  242. akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
  243. CRYPTO_TFM_REQ_MAY_SLEEP,
  244. crypto_req_done, &cwait);
  245. /* Perform the verification calculation. This doesn't actually do the
  246. * verification, but rather calculates the hash expected by the
  247. * signature and returns that to us.
  248. */
  249. ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
  250. if (ret)
  251. goto out_free_output;
  252. /* Do the actual verification step. */
  253. if (req->dst_len != sig->digest_size ||
  254. memcmp(sig->digest, output, sig->digest_size) != 0)
  255. ret = -EKEYREJECTED;
  256. out_free_output:
  257. kfree(output);
  258. error_free_req:
  259. akcipher_request_free(req);
  260. error_free_tfm:
  261. crypto_free_akcipher(tfm);
  262. pr_devel("<==%s() = %d\n", __func__, ret);
  263. if (WARN_ON_ONCE(ret > 0))
  264. ret = -EINVAL;
  265. return ret;
  266. }
  267. EXPORT_SYMBOL_GPL(public_key_verify_signature);
  268. static int public_key_verify_signature_2(const struct key *key,
  269. const struct public_key_signature *sig)
  270. {
  271. const struct public_key *pk = key->payload.data[asym_crypto];
  272. return public_key_verify_signature(pk, sig);
  273. }
  274. /*
  275. * Public key algorithm asymmetric key subtype
  276. */
  277. struct asymmetric_key_subtype public_key_subtype = {
  278. .owner = THIS_MODULE,
  279. .name = "public_key",
  280. .name_len = sizeof("public_key") - 1,
  281. .describe = public_key_describe,
  282. .destroy = public_key_destroy,
  283. .query = software_key_query,
  284. .eds_op = software_key_eds_op,
  285. .verify_signature = public_key_verify_signature_2,
  286. };
  287. EXPORT_SYMBOL_GPL(public_key_subtype);