efivar/0083-Add-some-of-the-authenticode-related-defines-from-pe.patch
Peter Jones 38cfe2832a Pull in a bunch of patches from upstream.
We're not quite ready to release efivar-38 upstream yet, so for now,
pull a bunch of patches in.

Signed-off-by: Peter Jones <pjones@redhat.com>
2020-02-24 15:24:32 -05:00

270 lines
10 KiB
Diff

From 74e3cb9e883f95ed358337df8a9841a2f47fd153 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 3 Feb 2020 13:50:07 -0500
Subject: [PATCH 83/86] Add some of the authenticode-related defines from
pesign
Signed-off-by: Peter Jones <pjones@redhat.com>
---
src/include/efivar/efisec-types.h | 234 ++++++++++++++++++++++++++++++
src/include/efivar/efisec.h | 2 +
2 files changed, 236 insertions(+)
create mode 100644 src/include/efivar/efisec-types.h
diff --git a/src/include/efivar/efisec-types.h b/src/include/efivar/efisec-types.h
new file mode 100644
index 00000000000..5d7febfeaae
--- /dev/null
+++ b/src/include/efivar/efisec-types.h
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * authenticode.h - Authenticode definitions and types
+ * Copyright 2019-2020 Peter Jones <pjones@redhat.com>
+ */
+
+#ifndef EFISEC_TYPES_H_
+#define EFISEC_TYPES_H_ 1
+
+#include <stdint.h>
+#include <efivar/efivar-types.h>
+
+/*
+ * Storage for specific hashes and cryptographic (not pkcs7) signatures
+ */
+typedef uint8_t efi_sha1_hash_t[20];
+typedef uint8_t efi_sha224_hash_t[28];
+typedef uint8_t efi_sha256_hash_t[32];
+typedef uint8_t efi_sha384_hash_t[48];
+typedef uint8_t efi_sha512_hash_t[64];
+typedef uint8_t efi_rsa2048_sig_t[256];
+
+/*
+ * Security database definitions and types
+ */
+
+#define EFI_GLOBAL_PLATFORM_KEY L"PK"
+#define EFI_GLOBAL_KEY_EXCHANGE_KEY L"KEK"
+#define EFI_IMAGE_SECURITY_DATABASE L"db"
+#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
+#define EFI_IMAGE_SECURITY_DATABASE2 L"dbt"
+#define EFI_IMAGE_SECURITY_DATABASE3 L"dbr"
+
+typedef struct {
+ efi_sha256_hash_t to_be_signed_hash;
+ efi_time_t time_of_revocation;
+} efi_cert_x509_sha256_t __attribute__((__aligned__(1)));
+
+typedef struct {
+ efi_sha384_hash_t to_be_signed_hash;
+ efi_time_t time_of_revocation;
+} efi_cert_x509_sha384_t __attribute__((__aligned__(1)));
+
+typedef struct {
+ efi_sha512_hash_t to_be_signed_hash;
+ efi_time_t time_of_revocation;
+} efi_cert_x509_sha512_t __attribute__((__aligned__(1)));
+
+typedef struct {
+ efi_guid_t signature_owner;
+ uint8_t signature_data[];
+} efi_signature_data_t __attribute__((__aligned__(1)));
+
+typedef struct {
+ efi_guid_t signature_type;
+ uint32_t signature_list_size;
+ uint32_t signature_header_size;
+ uint32_t signature_size;
+ // uint8_t signature_header[];
+ // efi_signature_data signatures[][signature_size];
+} efi_signature_list_t __attribute__((__aligned__(1)));
+
+/**********************************************************
+ * Stuff used by authenticode and authenticated variables *
+ **********************************************************/
+
+#define WIN_CERT_REVISION_1_0 ((uint16_t)0x0100)
+#define WIN_CERT_REVISION_2_0 ((uint16_t)0x0200)
+
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA ((uint16_t)0x0002)
+#define WIN_CERT_TYPE_EFI_PKCS115 ((uint16_t)0x0ef0)
+#define WIN_CERT_TYPE_EFI_GUID ((uint16_t)0x0ef1)
+
+typedef struct {
+ uint32_t length;
+ uint16_t revision;
+ uint16_t cert_type;
+} win_certificate_header_t;
+
+/*
+ * The spec says:
+ *
+ * This structure is the certificate header. There may be zero or more
+ * certificates.
+ * • If the wCertificateType field is set to WIN_CERT_TYPE_EFI_PKCS115,
+ * then the certificate follows the format described in
+ * WIN_CERTIFICATE_EFI_PKCS1_15.
+ * • If the wCertificateType field is set to WIN_CERT_TYPE_EFI_GUID, then
+ * the certificate follows the format described in
+ * WIN_CERTIFICATE_UEFI_GUID.
+ * • If the wCertificateType field is set to WIN_CERT_TYPE_PKCS_SIGNED_DATA
+ * then the certificate is formatted as described in the Authenticode
+ * specification.
+ *
+ * Which basically means we see the first two in EFI signature databases,
+ * and the third one in authenticode signatures. It goes on to say:
+ *
+ * Table 11.
+ * PE/COFF Certificates Types and UEFI Signature Database Certificate Types
+ * +---------------------------------------+-----------------------------------+
+ * | Image Certificate Type | Verified Using Signature Database |
+ * | | Type |
+ * +---------------------------------------+-----------------------------------+
+ * | WIN_CERT_TYPE_EFI_PKCS115 | EFI_CERT_RSA2048_GUID (public key)|
+ * | ( Signature Size = 256 bytes) | |
+ * +---------------------------------------+-----------------------------------+
+ * | WIN_CERT_TYPE_EFI_GUID | EFI_CERT_RSA2048_GUID (public key)|
+ * | ( CertType = | |
+ * | EFI_CERT_TYPE_RSA2048_SHA256_GUID ) | |
+ * +---------------------------------------+-----------------------------------+
+ * | WIN_CERT_TYPE_EFI_GUID | EFI_CERT_X509_GUID |
+ * | (CertType = EFI_CERT_TYPE_PKCS7_GUID) | EFI_CERT_RSA2048_GUID |
+ * | | (when applicable) |
+ * | | EFI_CERT_X509_SHA256_GUID |
+ * | | (when applicable) |
+ * | | EFI_CERT_X509_SHA384_GUID |
+ * | | (when applicable) |
+ * | | EFI_CERT_X509_SHA512_GUID |
+ * | | (when applicable) |
+ * +---------------------------------------+-----------------------------------+
+ * | WIN_CERT_TYPE_PKCS_SIGNED_DATA | EFI_CERT_X509_GUID |
+ * | | EFI_CERT_RSA2048_GUID |
+ * | | (when applicable) |
+ * | | EFI_CERT_X509_SHA256_GUID |
+ * | | (when applicable) |
+ * | | EFI_CERT_X509_SHA384_GUID |
+ * | | (when applicable) |
+ * | | EFI_CERT_X509_SHA512_GUID |
+ * | | (when applicable) |
+ * +---------------------------------------+-----------------------------------+
+ * |(Always applicable regardless of | EFI_CERT_SHA1_GUID, |
+ * | whether a certificate is present or | EFI_CERT_SHA224_GUID, |
+ * | not) | EFI_CERT_SHA256_GUID, |
+ * | | EFI_CERT_SHA384_GUID, |
+ * | | EFI_CERT_SHA512_GUID |
+ * | | In this case, the database |
+ * | | contains the hash of the image. |
+ * +---------------------------------------+-----------------------------------+
+ */
+
+/*
+ * hdr.cert_type = WIN_CERT_TYPE_PKCS_SIGNED_DATA
+ */
+typedef struct {
+ win_certificate_header_t hdr;
+ uint8_t data[]; // pkcs7 signedData
+} win_certificate_pkcs_signed_data_t;
+
+/*
+ * hdr.cert_type = WIN_CERT_TYPE_EFI_PKCS115
+ */
+typedef struct {
+ win_certificate_header_t hdr;
+ efi_guid_t hash_alg;
+ uint8_t signature[];
+} win_certificate_efi_pkcs1_15_t;
+
+/*
+ * hdr.cert_type = WIN_CERT_TYPE_EFI_GUID
+ */
+typedef struct {
+ win_certificate_header_t hdr;
+ efi_guid_t type;
+ uint8_t data[];
+} win_certificate_uefi_guid_t;
+
+
+/*
+ * public_key: pubkey that may or may not be trusted
+ * signature: a RSA2048 signature of the SHA256 authenticode hash
+ */
+typedef struct {
+ efi_guid_t hash_type;
+ uint8_t public_key[256];
+ uint8_t signature[256];
+} efi_cert_rsa2048_sha256_t;
+
+typedef struct {
+ uint64_t monotonic_count;
+ win_certificate_uefi_guid_t auth_info;
+} efi_variable_authentication_t __attribute__((aligned (1)));
+
+typedef struct {
+ efi_time_t timestamp;
+ win_certificate_uefi_guid_t auth_info;
+} efi_variable_authentication_2_t __attribute__((aligned (1)));
+
+#define EFI_VARIABLE_AUTHENTICATION_3_CERT_ID_SHA256 ((uint8_t)1)
+
+/* XXX the spec doesn't say if this is supposed to be packed/align(1) */
+typedef struct {
+ uint8_t type;
+ uint32_t id_size;
+ uint8_t id[];
+} efi_variable_authentication_3_cert_id_t __attribute__((aligned (1)));
+
+#define EFI_VARIABLE_AUTHENTICATION_3_TIMESTAMP_TYPE ((uint8_t)1)
+#define EFI_VARIABLE_AUTHENTICATION_3_NONCE_TYPE ((uint8_t)2)
+
+/* XXX the spec doesn't say if this is supposed to be packed/align(1) */
+typedef struct {
+ uint8_t version;
+ uint8_t type;
+ uint32_t metadata_size; // this is everything except data[]
+ uint32_t flags;
+} efi_variable_authentication_3_header_t __attribute__((aligned (1)));
+
+#define EFI_VARIABLE_ENHANCED_AUTH_FLAG_UPDATE_CERT ((uint32_t)0x00000001)
+
+typedef struct {
+ uint32_t nonce_size;
+ uint8_t nonce[];
+} efi_variable_authentication_3_nonce_t;
+
+/* XXX the spec sort of implies that this is supposed to be packed/align(1) */
+typedef struct {
+ efi_variable_authentication_3_header_t hdr;
+ efi_time_t timestamp;
+ // if EFI_VARIABLE_ENHANCED_AUTH_FLAG_UPDATE_CERT is set:
+ // uint8_t newcert[];
+ // uint8_t signing_cert[];
+} efi_variable_timestamped_authentication_3 __attribute__((aligned (1)));
+
+/* XXX the spec sort of implies that this is supposed to be packed/align(1) */
+typedef struct {
+ efi_variable_authentication_3_header_t hdr;
+ efi_variable_authentication_3_nonce_t nonce;
+ // if EFI_VARIABLE_ENHANCED_AUTH_FLAG_UPDATE_CERT is set:
+ // uint8_t newcert[];
+ // uint8_t signing_cert[];
+} efi_variable_nonced_authentication_3 __attribute__((aligned (1)));
+
+#endif /* !SECURITY_H_ */
+// vim:fenc=utf-8:tw=75:noet
diff --git a/src/include/efivar/efisec.h b/src/include/efivar/efisec.h
index 0ee5abe8bfd..f62bcedbf6f 100644
--- a/src/include/efivar/efisec.h
+++ b/src/include/efivar/efisec.h
@@ -9,6 +9,8 @@
#include <efivar/efivar.h>
+#include <efivar/efisec-types.h>
+
extern uint32_t efi_get_libefisec_version(void)
__attribute__((__visibility__("default")));
--
2.24.1