signature.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. if (fsverity_keyring->keys.nr_leaves_on_tree == 0) {
  75. /*
  76. * The ".fs-verity" keyring is empty, due to builtin signatures
  77. * being supported by the kernel but not actually being used.
  78. * In this case, verify_pkcs7_signature() would always return an
  79. * error, usually ENOKEY. It could also be EBADMSG if the
  80. * PKCS#7 is malformed, but that isn't very important to
  81. * distinguish. So, just skip to ENOKEY to avoid the attack
  82. * surface of the PKCS#7 parser, which would otherwise be
  83. * reachable by any task able to execute FS_IOC_ENABLE_VERITY.
  84. */
  85. fsverity_err(inode,
  86. "fs-verity keyring is empty, rejecting signed file!");
  87. return -ENOKEY;
  88. }
  89. d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL);
  90. if (!d)
  91. return -ENOMEM;
  92. memcpy(d->magic, "FSVerity", 8);
  93. d->digest_algorithm = cpu_to_le16(hash_alg - fsverity_hash_algs);
  94. d->digest_size = cpu_to_le16(hash_alg->digest_size);
  95. memcpy(d->digest, file_digest, hash_alg->digest_size);
  96. err = verify_pkcs7_signature(d, sizeof(*d) + hash_alg->digest_size,
  97. signature, sig_size, fsverity_keyring,
  98. VERIFYING_UNSPECIFIED_SIGNATURE,
  99. NULL, NULL);
  100. kfree(d);
  101. if (err) {
  102. if (err == -ENOKEY)
  103. fsverity_err(inode,
  104. "File's signing cert isn't in the fs-verity keyring");
  105. else if (err == -EKEYREJECTED)
  106. fsverity_err(inode, "Incorrect file signature");
  107. else if (err == -EBADMSG)
  108. fsverity_err(inode, "Malformed file signature");
  109. else
  110. fsverity_err(inode, "Error %d verifying file signature",
  111. err);
  112. return err;
  113. }
  114. return 0;
  115. }
  116. EXPORT_SYMBOL_GPL(__fsverity_verify_signature);
  117. #ifdef CONFIG_SYSCTL
  118. static struct ctl_table_header *fsverity_sysctl_header;
  119. static const struct ctl_path fsverity_sysctl_path[] = {
  120. { .procname = "fs", },
  121. { .procname = "verity", },
  122. { }
  123. };
  124. static struct ctl_table fsverity_sysctl_table[] = {
  125. {
  126. .procname = "require_signatures",
  127. .data = &fsverity_require_signatures,
  128. .maxlen = sizeof(int),
  129. .mode = 0644,
  130. .proc_handler = proc_dointvec_minmax,
  131. .extra1 = SYSCTL_ZERO,
  132. .extra2 = SYSCTL_ONE,
  133. },
  134. { }
  135. };
  136. static int __init fsverity_sysctl_init(void)
  137. {
  138. fsverity_sysctl_header = register_sysctl_paths(fsverity_sysctl_path,
  139. fsverity_sysctl_table);
  140. if (!fsverity_sysctl_header) {
  141. pr_err("sysctl registration failed!\n");
  142. return -ENOMEM;
  143. }
  144. return 0;
  145. }
  146. #else /* !CONFIG_SYSCTL */
  147. static inline int __init fsverity_sysctl_init(void)
  148. {
  149. return 0;
  150. }
  151. #endif /* !CONFIG_SYSCTL */
  152. int __init fsverity_init_signature(void)
  153. {
  154. struct key *ring;
  155. int err;
  156. ring = keyring_alloc(".fs-verity", KUIDT_INIT(0), KGIDT_INIT(0),
  157. current_cred(), KEY_POS_SEARCH |
  158. KEY_USR_VIEW | KEY_USR_READ | KEY_USR_WRITE |
  159. KEY_USR_SEARCH | KEY_USR_SETATTR,
  160. KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
  161. if (IS_ERR(ring))
  162. return PTR_ERR(ring);
  163. err = fsverity_sysctl_init();
  164. if (err)
  165. goto err_put_ring;
  166. fsverity_keyring = ring;
  167. return 0;
  168. err_put_ring:
  169. key_put(ring);
  170. return err;
  171. }