signature.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Verification of builtin signatures
  4. *
  5. * Copyright 2019 Google LLC
  6. */
  7. #include "fsverity_private.h"
  8. #include <linux/cred.h>
  9. #include <linux/key.h>
  10. #include <linux/slab.h>
  11. #include <linux/verification.h>
  12. /*
  13. * /proc/sys/fs/verity/require_signatures
  14. * If 1, all verity files must have a valid builtin signature.
  15. */
  16. static int fsverity_require_signatures;
  17. /*
  18. * Keyring that contains the trusted X.509 certificates.
  19. *
  20. * Only root (kuid=0) can modify this. Also, root may use
  21. * keyctl_restrict_keyring() to prevent any more additions.
  22. */
  23. static struct key *fsverity_keyring;
  24. /**
  25. * fsverity_verify_signature() - check a verity file's signature
  26. * @vi: the file's fsverity_info
  27. * @signature: the file's built-in signature
  28. * @sig_size: size of signature in bytes, or 0 if no signature
  29. *
  30. * If the file includes a signature of its fs-verity file digest, verify it
  31. * against the certificates in the fs-verity keyring.
  32. *
  33. * Return: 0 on success (signature valid or not required); -errno on failure
  34. */
  35. int fsverity_verify_signature(const struct fsverity_info *vi,
  36. const u8 *signature, size_t sig_size)
  37. {
  38. unsigned int digest_algorithm =
  39. vi->tree_params.hash_alg - fsverity_hash_algs;
  40. return __fsverity_verify_signature(vi->inode, signature, sig_size,
  41. vi->file_digest, digest_algorithm);
  42. }
  43. /**
  44. * __fsverity_verify_signature() - check a verity file's signature
  45. * @inode: the file's inode
  46. * @signature: the file's signature
  47. * @sig_size: size of @signature. Can be 0 if there is no signature
  48. * @file_digest: the file's digest
  49. * @digest_algorithm: the digest algorithm used
  50. *
  51. * Takes the file's digest and optional signature and verifies the signature
  52. * against the digest and the fs-verity keyring if appropriate
  53. *
  54. * Return: 0 on success (signature valid or not required); -errno on failure
  55. */
  56. int __fsverity_verify_signature(const struct inode *inode, const u8 *signature,
  57. size_t sig_size, const u8 *file_digest,
  58. unsigned int digest_algorithm)
  59. {
  60. struct fsverity_formatted_digest *d;
  61. struct fsverity_hash_alg *hash_alg = fsverity_get_hash_alg(inode,
  62. digest_algorithm);
  63. int err;
  64. if (IS_ERR(hash_alg))
  65. return PTR_ERR(hash_alg);
  66. if (sig_size == 0) {
  67. if (fsverity_require_signatures) {
  68. fsverity_err(inode,
  69. "require_signatures=1, rejecting unsigned file!");
  70. return -EPERM;
  71. }
  72. return 0;
  73. }
  74. d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL);
  75. if (!d)
  76. return -ENOMEM;
  77. memcpy(d->magic, "FSVerity", 8);
  78. d->digest_algorithm = cpu_to_le16(hash_alg - fsverity_hash_algs);
  79. d->digest_size = cpu_to_le16(hash_alg->digest_size);
  80. memcpy(d->digest, file_digest, hash_alg->digest_size);
  81. err = verify_pkcs7_signature(d, sizeof(*d) + hash_alg->digest_size,
  82. signature, sig_size, fsverity_keyring,
  83. VERIFYING_UNSPECIFIED_SIGNATURE,
  84. NULL, NULL);
  85. kfree(d);
  86. if (err) {
  87. if (err == -ENOKEY)
  88. fsverity_err(inode,
  89. "File's signing cert isn't in the fs-verity keyring");
  90. else if (err == -EKEYREJECTED)
  91. fsverity_err(inode, "Incorrect file signature");
  92. else if (err == -EBADMSG)
  93. fsverity_err(inode, "Malformed file signature");
  94. else
  95. fsverity_err(inode, "Error %d verifying file signature",
  96. err);
  97. return err;
  98. }
  99. pr_debug("Valid signature for file digest %s:%*phN\n",
  100. hash_alg->name, hash_alg->digest_size, file_digest);
  101. return 0;
  102. }
  103. EXPORT_SYMBOL_GPL(__fsverity_verify_signature);
  104. #ifdef CONFIG_SYSCTL
  105. static struct ctl_table_header *fsverity_sysctl_header;
  106. static const struct ctl_path fsverity_sysctl_path[] = {
  107. { .procname = "fs", },
  108. { .procname = "verity", },
  109. { }
  110. };
  111. static struct ctl_table fsverity_sysctl_table[] = {
  112. {
  113. .procname = "require_signatures",
  114. .data = &fsverity_require_signatures,
  115. .maxlen = sizeof(int),
  116. .mode = 0644,
  117. .proc_handler = proc_dointvec_minmax,
  118. .extra1 = SYSCTL_ZERO,
  119. .extra2 = SYSCTL_ONE,
  120. },
  121. { }
  122. };
  123. static int __init fsverity_sysctl_init(void)
  124. {
  125. fsverity_sysctl_header = register_sysctl_paths(fsverity_sysctl_path,
  126. fsverity_sysctl_table);
  127. if (!fsverity_sysctl_header) {
  128. pr_err("sysctl registration failed!\n");
  129. return -ENOMEM;
  130. }
  131. return 0;
  132. }
  133. #else /* !CONFIG_SYSCTL */
  134. static inline int __init fsverity_sysctl_init(void)
  135. {
  136. return 0;
  137. }
  138. #endif /* !CONFIG_SYSCTL */
  139. int __init fsverity_init_signature(void)
  140. {
  141. struct key *ring;
  142. int err;
  143. ring = keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0),
  144. current_cred(), KEY_POS_SEARCH |
  145. KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE |
  146. KEY_USR_SEARCH | KEY_USR_SETATTR,
  147. KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
  148. if (IS_ERR(ring))
  149. return PTR_ERR(ring);
  150. err = fsverity_sysctl_init();
  151. if (err)
  152. goto err_put_ring;
  153. fsverity_keyring = ring;
  154. return 0;
  155. err_put_ring:
  156. key_put(ring);
  157. return err;
  158. }