keyctl_pkey.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /* Public-key operation keyctls
  2. *
  3. * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, or (at your option) any later version.
  10. */
  11. #include <linux/slab.h>
  12. #include <linux/err.h>
  13. #include <linux/key.h>
  14. #include <linux/keyctl.h>
  15. #include <linux/parser.h>
  16. #include <linux/uaccess.h>
  17. #include <keys/user-type.h>
  18. #include "internal.h"
  19. static void keyctl_pkey_params_free(struct kernel_pkey_params *params)
  20. {
  21. kfree(params->info);
  22. key_put(params->key);
  23. }
  24. enum {
  25. Opt_err,
  26. Opt_enc, /* "enc=<encoding>" eg. "enc=oaep" */
  27. Opt_hash, /* "hash=<digest-name>" eg. "hash=sha1" */
  28. };
  29. static const match_table_t param_keys = {
  30. { Opt_enc, "enc=%s" },
  31. { Opt_hash, "hash=%s" },
  32. { Opt_err, NULL }
  33. };
  34. /*
  35. * Parse the information string which consists of key=val pairs.
  36. */
  37. static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
  38. {
  39. unsigned long token_mask = 0;
  40. substring_t args[MAX_OPT_ARGS];
  41. char *c = params->info, *p, *q;
  42. int token;
  43. while ((p = strsep(&c, " \t"))) {
  44. if (*p == '\0' || *p == ' ' || *p == '\t')
  45. continue;
  46. token = match_token(p, param_keys, args);
  47. if (__test_and_set_bit(token, &token_mask))
  48. return -EINVAL;
  49. q = args[0].from;
  50. if (!q[0])
  51. return -EINVAL;
  52. switch (token) {
  53. case Opt_enc:
  54. params->encoding = q;
  55. break;
  56. case Opt_hash:
  57. params->hash_algo = q;
  58. break;
  59. default:
  60. return -EINVAL;
  61. }
  62. }
  63. return 0;
  64. }
  65. /*
  66. * Interpret parameters. Callers must always call the free function
  67. * on params, even if an error is returned.
  68. */
  69. static int keyctl_pkey_params_get(key_serial_t id,
  70. const char __user *_info,
  71. struct kernel_pkey_params *params)
  72. {
  73. key_ref_t key_ref;
  74. void *p;
  75. int ret;
  76. memset(params, 0, sizeof(*params));
  77. params->encoding = "raw";
  78. p = strndup_user(_info, PAGE_SIZE);
  79. if (IS_ERR(p))
  80. return PTR_ERR(p);
  81. params->info = p;
  82. ret = keyctl_pkey_params_parse(params);
  83. if (ret < 0)
  84. return ret;
  85. key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
  86. if (IS_ERR(key_ref))
  87. return PTR_ERR(key_ref);
  88. params->key = key_ref_to_ptr(key_ref);
  89. if (!params->key->type->asym_query)
  90. return -EOPNOTSUPP;
  91. return 0;
  92. }
  93. /*
  94. * Get parameters from userspace. Callers must always call the free function
  95. * on params, even if an error is returned.
  96. */
  97. static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_params,
  98. const char __user *_info,
  99. int op,
  100. struct kernel_pkey_params *params)
  101. {
  102. struct keyctl_pkey_params uparams;
  103. struct kernel_pkey_query info;
  104. int ret;
  105. memset(params, 0, sizeof(*params));
  106. params->encoding = "raw";
  107. if (copy_from_user(&uparams, _params, sizeof(uparams)) != 0)
  108. return -EFAULT;
  109. ret = keyctl_pkey_params_get(uparams.key_id, _info, params);
  110. if (ret < 0)
  111. return ret;
  112. ret = params->key->type->asym_query(params, &info);
  113. if (ret < 0)
  114. return ret;
  115. switch (op) {
  116. case KEYCTL_PKEY_ENCRYPT:
  117. case KEYCTL_PKEY_DECRYPT:
  118. if (uparams.in_len > info.max_enc_size ||
  119. uparams.out_len > info.max_dec_size)
  120. return -EINVAL;
  121. break;
  122. case KEYCTL_PKEY_SIGN:
  123. case KEYCTL_PKEY_VERIFY:
  124. if (uparams.in_len > info.max_sig_size ||
  125. uparams.out_len > info.max_data_size)
  126. return -EINVAL;
  127. break;
  128. default:
  129. BUG();
  130. }
  131. params->in_len = uparams.in_len;
  132. params->out_len = uparams.out_len;
  133. return 0;
  134. }
  135. /*
  136. * Query information about an asymmetric key.
  137. */
  138. long keyctl_pkey_query(key_serial_t id,
  139. const char __user *_info,
  140. struct keyctl_pkey_query __user *_res)
  141. {
  142. struct kernel_pkey_params params;
  143. struct kernel_pkey_query res;
  144. long ret;
  145. memset(&params, 0, sizeof(params));
  146. ret = keyctl_pkey_params_get(id, _info, &params);
  147. if (ret < 0)
  148. goto error;
  149. ret = params.key->type->asym_query(&params, &res);
  150. if (ret < 0)
  151. goto error;
  152. ret = -EFAULT;
  153. if (copy_to_user(_res, &res, sizeof(res)) == 0 &&
  154. clear_user(_res->__spare, sizeof(_res->__spare)) == 0)
  155. ret = 0;
  156. error:
  157. keyctl_pkey_params_free(&params);
  158. return ret;
  159. }
  160. /*
  161. * Encrypt/decrypt/sign
  162. *
  163. * Encrypt data, decrypt data or sign data using a public key.
  164. *
  165. * _info is a string of supplementary information in key=val format. For
  166. * instance, it might contain:
  167. *
  168. * "enc=pkcs1 hash=sha256"
  169. *
  170. * where enc= specifies the encoding and hash= selects the OID to go in that
  171. * particular encoding if required. If enc= isn't supplied, it's assumed that
  172. * the caller is supplying raw values.
  173. *
  174. * If successful, the amount of data written into the output buffer is
  175. * returned.
  176. */
  177. long keyctl_pkey_e_d_s(int op,
  178. const struct keyctl_pkey_params __user *_params,
  179. const char __user *_info,
  180. const void __user *_in,
  181. void __user *_out)
  182. {
  183. struct kernel_pkey_params params;
  184. void *in, *out;
  185. long ret;
  186. ret = keyctl_pkey_params_get_2(_params, _info, op, &params);
  187. if (ret < 0)
  188. goto error_params;
  189. ret = -EOPNOTSUPP;
  190. if (!params.key->type->asym_eds_op)
  191. goto error_params;
  192. switch (op) {
  193. case KEYCTL_PKEY_ENCRYPT:
  194. params.op = kernel_pkey_encrypt;
  195. break;
  196. case KEYCTL_PKEY_DECRYPT:
  197. params.op = kernel_pkey_decrypt;
  198. break;
  199. case KEYCTL_PKEY_SIGN:
  200. params.op = kernel_pkey_sign;
  201. break;
  202. default:
  203. BUG();
  204. }
  205. in = memdup_user(_in, params.in_len);
  206. if (IS_ERR(in)) {
  207. ret = PTR_ERR(in);
  208. goto error_params;
  209. }
  210. ret = -ENOMEM;
  211. out = kmalloc(params.out_len, GFP_KERNEL);
  212. if (!out)
  213. goto error_in;
  214. ret = params.key->type->asym_eds_op(&params, in, out);
  215. if (ret < 0)
  216. goto error_out;
  217. if (copy_to_user(_out, out, ret) != 0)
  218. ret = -EFAULT;
  219. error_out:
  220. kfree(out);
  221. error_in:
  222. kfree(in);
  223. error_params:
  224. keyctl_pkey_params_free(&params);
  225. return ret;
  226. }
  227. /*
  228. * Verify a signature.
  229. *
  230. * Verify a public key signature using the given key, or if not given, search
  231. * for a matching key.
  232. *
  233. * _info is a string of supplementary information in key=val format. For
  234. * instance, it might contain:
  235. *
  236. * "enc=pkcs1 hash=sha256"
  237. *
  238. * where enc= specifies the signature blob encoding and hash= selects the OID
  239. * to go in that particular encoding. If enc= isn't supplied, it's assumed
  240. * that the caller is supplying raw values.
  241. *
  242. * If successful, 0 is returned.
  243. */
  244. long keyctl_pkey_verify(const struct keyctl_pkey_params __user *_params,
  245. const char __user *_info,
  246. const void __user *_in,
  247. const void __user *_in2)
  248. {
  249. struct kernel_pkey_params params;
  250. void *in, *in2;
  251. long ret;
  252. ret = keyctl_pkey_params_get_2(_params, _info, KEYCTL_PKEY_VERIFY,
  253. &params);
  254. if (ret < 0)
  255. goto error_params;
  256. ret = -EOPNOTSUPP;
  257. if (!params.key->type->asym_verify_signature)
  258. goto error_params;
  259. in = memdup_user(_in, params.in_len);
  260. if (IS_ERR(in)) {
  261. ret = PTR_ERR(in);
  262. goto error_params;
  263. }
  264. in2 = memdup_user(_in2, params.in2_len);
  265. if (IS_ERR(in2)) {
  266. ret = PTR_ERR(in2);
  267. goto error_in;
  268. }
  269. params.op = kernel_pkey_verify;
  270. ret = params.key->type->asym_verify_signature(&params, in, in2);
  271. kfree(in2);
  272. error_in:
  273. kfree(in);
  274. error_params:
  275. keyctl_pkey_params_free(&params);
  276. return ret;
  277. }