0024-efi-capsule-Add-support-for-Quark-security-header.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. From b36534fedba5c188eefabf9a8fbbf4dd39495605 Mon Sep 17 00:00:00 2001
  2. From: Jan Kiszka <jan.kiszka@siemens.com>
  3. Date: Fri, 24 Mar 2017 18:34:20 +0100
  4. Subject: [PATCH 24/27] efi/capsule: Add support for Quark security header
  5. The firmware for Quark X102x prepends a security header to the capsule
  6. which is needed to support the mandatory secure boot on this processor.
  7. The header can be detected by checking for the "_CSH" signature and -
  8. to avoid any GUID conflict - validating its size field to contain the
  9. expected value. Then we need to look for the EFI header right after the
  10. security header and pass the real header to __efi_capsule_setup_info.
  11. To be minimal invasive and maximal safe, the quirk version of
  12. efi_capsule_identify_image is only effective on Quark processors.
  13. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
  14. ---
  15. arch/x86/platform/efi/quirks.c | 137 +++++++++++++++++++++++++++++++++++++++++
  16. drivers/firmware/efi/Kconfig | 9 +++
  17. 2 files changed, 146 insertions(+)
  18. diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
  19. index 1c7380da65ff..f0361323a805 100644
  20. --- a/arch/x86/platform/efi/quirks.c
  21. +++ b/arch/x86/platform/efi/quirks.c
  22. @@ -10,12 +10,66 @@
  23. #include <linux/acpi.h>
  24. #include <asm/efi.h>
  25. #include <asm/uv/uv.h>
  26. +#include <asm/cpu_device_id.h>
  27. #define EFI_MIN_RESERVE 5120
  28. #define EFI_DUMMY_GUID \
  29. EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9)
  30. +#define QUARK_CSH_SIGNATURE 0x5f435348 /* _CSH */
  31. +#define QUARK_SECURITY_HEADER_SIZE 0x400
  32. +
  33. +/*
  34. + * Header prepended to the standard EFI capsule on Quark systems the are based
  35. + * on Intel firmware BSP.
  36. + * @csh_signature: Unique identifier to sanity check signed module
  37. + * presence ("_CSH").
  38. + * @version: Current version of CSH used. Should be one for Quark A0.
  39. + * @modulesize: Size of the entire module including the module header
  40. + * and payload.
  41. + * @security_version_number_index: Index of SVN to use for validation of signed
  42. + * module.
  43. + * @security_version_number: Used to prevent against roll back of modules.
  44. + * @rsvd_module_id: Currently unused for Clanton (Quark).
  45. + * @rsvd_module_vendor: Vendor Identifier. For Intel products value is
  46. + * 0x00008086.
  47. + * @rsvd_date: BCD representation of build date as yyyymmdd, where
  48. + * yyyy=4 digit year, mm=1-12, dd=1-31.
  49. + * @headersize: Total length of the header including including any
  50. + * padding optionally added by the signing tool.
  51. + * @hash_algo: What Hash is used in the module signing.
  52. + * @cryp_algo: What Crypto is used in the module signing.
  53. + * @keysize: Total length of the key data including including any
  54. + * padding optionally added by the signing tool.
  55. + * @signaturesize: Total length of the signature including including any
  56. + * padding optionally added by the signing tool.
  57. + * @rsvd_next_header: 32-bit pointer to the next Secure Boot Module in the
  58. + * chain, if there is a next header.
  59. + * @rsvd: Reserved, padding structure to required size.
  60. + *
  61. + * See also QuartSecurityHeader_t in
  62. + * Quark_EDKII_v1.2.1.1/QuarkPlatformPkg/Include/QuarkBootRom.h
  63. + * from https://downloadcenter.intel.com/download/23197/Intel-Quark-SoC-X1000-Board-Support-Package-BSP
  64. + */
  65. +struct quark_security_header {
  66. + u32 csh_signature;
  67. + u32 version;
  68. + u32 modulesize;
  69. + u32 security_version_number_index;
  70. + u32 security_version_number;
  71. + u32 rsvd_module_id;
  72. + u32 rsvd_module_vendor;
  73. + u32 rsvd_date;
  74. + u32 headersize;
  75. + u32 hash_algo;
  76. + u32 cryp_algo;
  77. + u32 keysize;
  78. + u32 signaturesize;
  79. + u32 rsvd_next_header;
  80. + u32 rsvd[2];
  81. +};
  82. +
  83. static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
  84. static bool efi_no_storage_paranoia;
  85. @@ -288,3 +342,86 @@ bool efi_poweroff_required(void)
  86. {
  87. return !!acpi_gbl_reduced_hardware;
  88. }
  89. +
  90. +#ifdef CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH
  91. +
  92. +static int qrk_capsule_setup_info(struct capsule_info *cap_info, void **pkbuff,
  93. + size_t hdr_bytes)
  94. +{
  95. + struct quark_security_header *csh = *pkbuff;
  96. +
  97. + /* Only process data block that is larger than the security header */
  98. + if (hdr_bytes < sizeof(struct quark_security_header))
  99. + return 0;
  100. +
  101. + if (csh->csh_signature != QUARK_CSH_SIGNATURE ||
  102. + csh->headersize != QUARK_SECURITY_HEADER_SIZE)
  103. + return 1;
  104. +
  105. + /* Only process data block if EFI header is included */
  106. + if (hdr_bytes < QUARK_SECURITY_HEADER_SIZE +
  107. + sizeof(efi_capsule_header_t))
  108. + return 0;
  109. +
  110. + pr_debug("Quark security header detected\n");
  111. +
  112. + if (csh->rsvd_next_header != 0) {
  113. + pr_err("multiple Quark security headers not supported\n");
  114. + return -EINVAL;
  115. + }
  116. +
  117. + *pkbuff += csh->headersize;
  118. + cap_info->total_size = csh->headersize;
  119. +
  120. + /*
  121. + * Update the first page pointer to skip over the CSH header.
  122. + */
  123. + cap_info->pages[0] += csh->headersize;
  124. +
  125. + return 1;
  126. +}
  127. +
  128. +#define ICPU(family, model, quirk_handler) \
  129. + { X86_VENDOR_INTEL, family, model, X86_FEATURE_ANY, \
  130. + (unsigned long)&quirk_handler }
  131. +
  132. +static const struct x86_cpu_id efi_capsule_quirk_ids[] = {
  133. + ICPU(5, 9, qrk_capsule_setup_info), /* Intel Quark X1000 */
  134. + { }
  135. +};
  136. +
  137. +int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff,
  138. + size_t hdr_bytes)
  139. +{
  140. + int (*quirk_handler)(struct capsule_info *, void **, size_t);
  141. + const struct x86_cpu_id *id;
  142. + int ret;
  143. +
  144. + if (hdr_bytes < sizeof(efi_capsule_header_t))
  145. + return 0;
  146. +
  147. + cap_info->total_size = 0;
  148. +
  149. + id = x86_match_cpu(efi_capsule_quirk_ids);
  150. + if (id) {
  151. + /*
  152. + * The quirk handler is supposed to return
  153. + * - a value > 0 if the setup should continue, after advancing
  154. + * kbuff as needed
  155. + * - 0 if not enough hdr_bytes are available yet
  156. + * - a negative error code otherwise
  157. + */
  158. + quirk_handler = (typeof(quirk_handler))id->driver_data;
  159. + ret = quirk_handler(cap_info, &kbuff, hdr_bytes);
  160. + if (ret <= 0)
  161. + return ret;
  162. + }
  163. +
  164. + memcpy(&cap_info->header, kbuff, sizeof(cap_info->header));
  165. +
  166. + cap_info->total_size += cap_info->header.imagesize;
  167. +
  168. + return __efi_capsule_setup_info(cap_info);
  169. +}
  170. +
  171. +#endif
  172. diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
  173. index de221bbde9c9..8dfeee3b9e54 100644
  174. --- a/drivers/firmware/efi/Kconfig
  175. +++ b/drivers/firmware/efi/Kconfig
  176. @@ -97,6 +97,15 @@ config EFI_CAPSULE_LOADER
  177. Most users should say N.
  178. +config EFI_CAPSULE_QUIRK_QUARK_CSH
  179. + boolean "Add support for Quark capsules with non-standard headers"
  180. + depends on X86 && !64BIT
  181. + select EFI_CAPSULE_LOADER
  182. + default y
  183. + help
  184. + Add support for processing Quark X1000 EFI capsules, whose header
  185. + layout deviates from the layout mandated by the UEFI specification.
  186. +
  187. endmenu
  188. config UEFI_CPER
  189. --
  190. 2.12.0