digsig_asymmetric.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (C) 2013 Intel Corporation
  3. *
  4. * Author:
  5. * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, version 2 of the License.
  10. *
  11. */
  12. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13. #include <linux/err.h>
  14. #include <linux/ratelimit.h>
  15. #include <linux/key-type.h>
  16. #include <crypto/public_key.h>
  17. #include <keys/asymmetric-type.h>
  18. #include "integrity.h"
  19. /*
  20. * Request an asymmetric key.
  21. */
  22. static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
  23. {
  24. struct key *key;
  25. char name[12];
  26. sprintf(name, "id:%08x", keyid);
  27. pr_debug("key search: \"%s\"\n", name);
  28. if (keyring) {
  29. /* search in specific keyring */
  30. key_ref_t kref;
  31. kref = keyring_search(make_key_ref(keyring, 1),
  32. &key_type_asymmetric, name);
  33. if (IS_ERR(kref))
  34. key = ERR_CAST(kref);
  35. else
  36. key = key_ref_to_ptr(kref);
  37. } else {
  38. key = request_key(&key_type_asymmetric, name, NULL);
  39. }
  40. if (IS_ERR(key)) {
  41. pr_err_ratelimited("Request for unknown key '%s' err %ld\n",
  42. name, PTR_ERR(key));
  43. switch (PTR_ERR(key)) {
  44. /* Hide some search errors */
  45. case -EACCES:
  46. case -ENOTDIR:
  47. case -EAGAIN:
  48. return ERR_PTR(-ENOKEY);
  49. default:
  50. return key;
  51. }
  52. }
  53. pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key));
  54. return key;
  55. }
  56. int asymmetric_verify(struct key *keyring, const char *sig,
  57. int siglen, const char *data, int datalen)
  58. {
  59. struct public_key_signature pks;
  60. struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
  61. struct key *key;
  62. int ret = -ENOMEM;
  63. if (siglen <= sizeof(*hdr))
  64. return -EBADMSG;
  65. siglen -= sizeof(*hdr);
  66. if (siglen != __be16_to_cpu(hdr->sig_size))
  67. return -EBADMSG;
  68. if (hdr->hash_algo >= PKEY_HASH__LAST)
  69. return -ENOPKG;
  70. key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid));
  71. if (IS_ERR(key))
  72. return PTR_ERR(key);
  73. memset(&pks, 0, sizeof(pks));
  74. pks.pkey_hash_algo = hdr->hash_algo;
  75. pks.digest = (u8 *)data;
  76. pks.digest_size = datalen;
  77. pks.nr_mpi = 1;
  78. pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen);
  79. if (pks.rsa.s)
  80. ret = verify_signature(key, &pks);
  81. mpi_free(pks.rsa.s);
  82. key_put(key);
  83. pr_debug("%s() = %d\n", __func__, ret);
  84. return ret;
  85. }