digsig_asymmetric.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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/key-type.h>
  15. #include <crypto/public_key.h>
  16. #include <keys/asymmetric-type.h>
  17. #include "integrity.h"
  18. /*
  19. * Request an asymmetric key.
  20. */
  21. static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
  22. {
  23. struct key *key;
  24. char name[12];
  25. sprintf(name, "id:%x", keyid);
  26. pr_debug("key search: \"%s\"\n", name);
  27. if (keyring) {
  28. /* search in specific keyring */
  29. key_ref_t kref;
  30. kref = keyring_search(make_key_ref(keyring, 1),
  31. &key_type_asymmetric, name);
  32. if (IS_ERR(kref))
  33. key = ERR_CAST(kref);
  34. else
  35. key = key_ref_to_ptr(kref);
  36. } else {
  37. key = request_key(&key_type_asymmetric, name, NULL);
  38. }
  39. if (IS_ERR(key)) {
  40. pr_warn("Request for unknown key '%s' err %ld\n",
  41. name, PTR_ERR(key));
  42. switch (PTR_ERR(key)) {
  43. /* Hide some search errors */
  44. case -EACCES:
  45. case -ENOTDIR:
  46. case -EAGAIN:
  47. return ERR_PTR(-ENOKEY);
  48. default:
  49. return key;
  50. }
  51. }
  52. pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key));
  53. return key;
  54. }
  55. int asymmetric_verify(struct key *keyring, const char *sig,
  56. int siglen, const char *data, int datalen)
  57. {
  58. struct public_key_signature pks;
  59. struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
  60. struct key *key;
  61. int ret = -ENOMEM;
  62. if (siglen <= sizeof(*hdr))
  63. return -EBADMSG;
  64. siglen -= sizeof(*hdr);
  65. if (siglen != __be16_to_cpu(hdr->sig_size))
  66. return -EBADMSG;
  67. if (hdr->hash_algo >= PKEY_HASH__LAST)
  68. return -ENOPKG;
  69. key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid));
  70. if (IS_ERR(key))
  71. return PTR_ERR(key);
  72. memset(&pks, 0, sizeof(pks));
  73. pks.pkey_hash_algo = hdr->hash_algo;
  74. pks.digest = (u8 *)data;
  75. pks.digest_size = datalen;
  76. pks.nr_mpi = 1;
  77. pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen);
  78. if (pks.rsa.s)
  79. ret = verify_signature(key, &pks);
  80. mpi_free(pks.rsa.s);
  81. key_put(key);
  82. pr_debug("%s() = %d\n", __func__, ret);
  83. return ret;
  84. }