digsig_asymmetric.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2013 Intel Corporation
  4. *
  5. * Author:
  6. * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
  7. */
  8. #include <linux/err.h>
  9. #include <linux/ratelimit.h>
  10. #include <linux/key-type.h>
  11. #include <crypto/public_key.h>
  12. #include <crypto/hash_info.h>
  13. #include <keys/asymmetric-type.h>
  14. #include <keys/system_keyring.h>
  15. #include "integrity.h"
  16. /*
  17. * Request an asymmetric key.
  18. */
  19. static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
  20. {
  21. struct key *key;
  22. char name[12];
  23. sprintf(name, "id:%08x", keyid);
  24. pr_debug("key search: \"%s\"\n", name);
  25. key = get_ima_blacklist_keyring();
  26. if (key) {
  27. key_ref_t kref;
  28. kref = keyring_search(make_key_ref(key, 1),
  29. &key_type_asymmetric, name, true);
  30. if (!IS_ERR(kref)) {
  31. pr_err("Key '%s' is in ima_blacklist_keyring\n", name);
  32. return ERR_PTR(-EKEYREJECTED);
  33. }
  34. }
  35. if (keyring) {
  36. /* search in specific keyring */
  37. key_ref_t kref;
  38. kref = keyring_search(make_key_ref(keyring, 1),
  39. &key_type_asymmetric, name, true);
  40. if (IS_ERR(kref))
  41. key = ERR_CAST(kref);
  42. else
  43. key = key_ref_to_ptr(kref);
  44. } else {
  45. key = request_key(&key_type_asymmetric, name, NULL);
  46. }
  47. if (IS_ERR(key)) {
  48. if (keyring)
  49. pr_err_ratelimited("Request for unknown key '%s' in '%s' keyring. err %ld\n",
  50. name, keyring->description,
  51. PTR_ERR(key));
  52. else
  53. pr_err_ratelimited("Request for unknown key '%s' err %ld\n",
  54. name, PTR_ERR(key));
  55. switch (PTR_ERR(key)) {
  56. /* Hide some search errors */
  57. case -EACCES:
  58. case -ENOTDIR:
  59. case -EAGAIN:
  60. return ERR_PTR(-ENOKEY);
  61. default:
  62. return key;
  63. }
  64. }
  65. pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key));
  66. return key;
  67. }
  68. int asymmetric_verify(struct key *keyring, const char *sig,
  69. int siglen, const char *data, int datalen)
  70. {
  71. struct public_key_signature pks;
  72. struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
  73. const struct public_key *pk;
  74. struct key *key;
  75. int ret;
  76. if (siglen <= sizeof(*hdr))
  77. return -EBADMSG;
  78. siglen -= sizeof(*hdr);
  79. if (siglen != be16_to_cpu(hdr->sig_size))
  80. return -EBADMSG;
  81. if (hdr->hash_algo >= HASH_ALGO__LAST)
  82. return -ENOPKG;
  83. key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
  84. if (IS_ERR(key))
  85. return PTR_ERR(key);
  86. memset(&pks, 0, sizeof(pks));
  87. pks.hash_algo = hash_algo_name[hdr->hash_algo];
  88. pk = asymmetric_key_public_key(key);
  89. pks.pkey_algo = pk->pkey_algo;
  90. if (!strcmp(pk->pkey_algo, "rsa")) {
  91. pks.encoding = "pkcs1";
  92. } else if (!strncmp(pk->pkey_algo, "ecdsa-", 6)) {
  93. /* edcsa-nist-p192 etc. */
  94. pks.encoding = "x962";
  95. } else if (!strcmp(pk->pkey_algo, "ecrdsa")) {
  96. pks.encoding = "raw";
  97. } else {
  98. ret = -ENOPKG;
  99. goto out;
  100. }
  101. pks.digest = (u8 *)data;
  102. pks.digest_size = datalen;
  103. pks.s = hdr->sig;
  104. pks.s_size = siglen;
  105. ret = verify_signature(key, &pks);
  106. out:
  107. key_put(key);
  108. pr_debug("%s() = %d\n", __func__, ret);
  109. return ret;
  110. }