efi_loader: image_loader: support image authentication
[oweals/u-boot.git] / include / efi_loader.h
index 23ce732267620b3346b7f3b96f574f7f1a6cf27a..0ba9a1f702a6224431d64238614c17b89ee1df0a 100644 (file)
 #include <common.h>
 #include <part_efi.h>
 #include <efi_api.h>
+#include <pe.h>
+
+static inline int guidcmp(const void *g1, const void *g2)
+{
+       return memcmp(g1, g2, sizeof(efi_guid_t));
+}
+
+static inline void *guidcpy(void *dst, const void *src)
+{
+       return memcpy(dst, src, sizeof(efi_guid_t));
+}
 
 /* No need for efi loader support in SPL */
 #if CONFIG_IS_ENABLED(EFI_LOADER)
 
 #include <linux/list.h>
+#include <linux/oid_registry.h>
 
 /* Maximum number of configuration tables */
 #define EFI_MAX_CONFIGURATION_TABLES 16
 #define U_BOOT_GUID \
        EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \
                 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b)
+/* GUID used as host device on sandbox */
+#define U_BOOT_HOST_DEV_GUID \
+       EFI_GUID(0xbbe4e671, 0x5773, 0x4ea1, \
+                0x9a, 0xab, 0x3a, 0x7d, 0xbf, 0x40, 0xc4, 0x82)
+
+/* Use internal device tree when starting UEFI application */
+#define EFI_FDT_USE_INTERNAL NULL
 
 /* Root node */
 extern efi_handle_t efi_root;
@@ -116,11 +135,16 @@ extern const struct efi_hii_config_routing_protocol efi_hii_config_routing;
 extern const struct efi_hii_config_access_protocol efi_hii_config_access;
 extern const struct efi_hii_database_protocol efi_hii_database;
 extern const struct efi_hii_string_protocol efi_hii_string;
+extern const struct efi_rng_protocol efi_rng_protocol;
 
 uint16_t *efi_dp_str(struct efi_device_path *dp);
 
 /* GUID of the U-Boot root node */
 extern const efi_guid_t efi_u_boot_guid;
+#ifdef CONFIG_SANDBOX
+/* GUID of U-Boot host device on sandbox */
+extern const efi_guid_t efi_guid_host_dev;
+#endif
 /* GUID of the EFI_BLOCK_IO_PROTOCOL */
 extern const efi_guid_t efi_block_io_guid;
 extern const efi_guid_t efi_global_variable_guid;
@@ -156,6 +180,15 @@ extern const efi_guid_t efi_guid_hii_config_routing_protocol;
 extern const efi_guid_t efi_guid_hii_config_access_protocol;
 extern const efi_guid_t efi_guid_hii_database_protocol;
 extern const efi_guid_t efi_guid_hii_string_protocol;
+/* GUIDs for authentication */
+extern const efi_guid_t efi_guid_image_security_database;
+extern const efi_guid_t efi_guid_sha256;
+extern const efi_guid_t efi_guid_cert_x509;
+extern const efi_guid_t efi_guid_cert_x509_sha256;
+extern const efi_guid_t efi_guid_cert_type_pkcs7;
+
+/* GUID of RNG protocol */
+extern const efi_guid_t efi_guid_rng_protocol;
 
 extern unsigned int __efi_runtime_start, __efi_runtime_stop;
 extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
@@ -231,6 +264,11 @@ struct efi_object {
        enum efi_object_type type;
 };
 
+enum efi_image_auth_status {
+       EFI_IMAGE_AUTH_FAILED = 0,
+       EFI_IMAGE_AUTH_PASSED,
+};
+
 /**
  * struct efi_loaded_image_obj - handle of a loaded image
  *
@@ -250,12 +288,14 @@ struct efi_loaded_image_obj {
        EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
                                     struct efi_system_table *st);
        u16 image_type;
+       enum efi_image_auth_status auth_status;
 };
 
 /**
  * struct efi_event
  *
  * @link:              Link to list of all events
+ * @queue_link:                Link to the list of queued events
  * @type:              Type of event, see efi_create_event
  * @notify_tpl:                Task priority level of notifications
  * @nofify_function:   Function to call when the event is triggered
@@ -264,11 +304,11 @@ struct efi_loaded_image_obj {
  * @trigger_time:      Period of the timer
  * @trigger_next:      Next time to trigger the timer
  * @trigger_type:      Type of timer, see efi_set_timer
- * @is_queued:         The notification function is queued
  * @is_signaled:       The event occurred. The event is in the signaled state.
  */
 struct efi_event {
        struct list_head link;
+       struct list_head queue_link;
        uint32_t type;
        efi_uintn_t notify_tpl;
        void (EFIAPI *notify_function)(struct efi_event *event, void *context);
@@ -277,7 +317,6 @@ struct efi_event {
        u64 trigger_next;
        u64 trigger_time;
        enum efi_timer_delay trigger_type;
-       bool is_queued;
        bool is_signaled;
 };
 
@@ -325,10 +364,20 @@ extern struct list_head efi_register_notify_events;
 
 /* Initialize efi execution environment */
 efi_status_t efi_init_obj_list(void);
+/* Install device tree */
+efi_status_t efi_install_fdt(void *fdt);
+/* Run loaded UEFI image */
+efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size);
+/* Initialize variable services */
+efi_status_t efi_init_variables(void);
+/* Notify ExitBootServices() is called */
+void efi_variables_boot_exit_notify(void);
 /* Called by bootefi to initialize root node */
 efi_status_t efi_root_node_register(void);
 /* Called by bootefi to initialize runtime */
 efi_status_t efi_initialize_system_table(void);
+/* efi_runtime_detach() - detach unimplemented runtime functions */
+void efi_runtime_detach(void);
 /* Called by bootefi to make console interface available */
 efi_status_t efi_console_register(void);
 /* Called by bootefi to make all disk storage accessible as EFI objects */
@@ -343,6 +392,7 @@ efi_status_t efi_gop_register(void);
 efi_status_t efi_net_register(void);
 /* Called by bootefi to make the watchdog available */
 efi_status_t efi_watchdog_register(void);
+efi_status_t efi_initrd_register(void);
 /* Called by bootefi to make SMBIOS tables available */
 /**
  * efi_acpi_register() - write out ACPI tables
@@ -372,7 +422,8 @@ efi_status_t efi_set_watchdog(unsigned long timeout);
 /* Called from places to check whether a timer expired */
 void efi_timer_check(void);
 /* PE loader implementation */
-efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
+efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
+                        void *efi, size_t efi_size,
                         struct efi_loaded_image *loaded_image_info);
 /* Called once to store the pristine gd pointer */
 void efi_save_gd(void);
@@ -421,6 +472,20 @@ efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
 /* Install multiple protocol interfaces */
 efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
                                (efi_handle_t *handle, ...);
+/* Get handles that support a given protocol */
+efi_status_t EFIAPI efi_locate_handle_buffer(
+                       enum efi_locate_search_type search_type,
+                       const efi_guid_t *protocol, void *search_key,
+                       efi_uintn_t *no_handles, efi_handle_t **buffer);
+/* Close an previously opened protocol interface */
+efi_status_t EFIAPI efi_close_protocol(efi_handle_t handle,
+                                      const efi_guid_t *protocol,
+                                      efi_handle_t agent_handle,
+                                      efi_handle_t controller_handle);
+/* Open a protocol interface */
+efi_status_t EFIAPI efi_handle_protocol(efi_handle_t handle,
+                                       const efi_guid_t *protocol,
+                                       void **protocol_interface);
 /* Call this to create an event */
 efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
                              void (EFIAPI *notify_function) (
@@ -432,7 +497,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
 efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
                           uint64_t trigger_time);
 /* Call this to signal an event */
-void efi_signal_event(struct efi_event *event, bool check_tpl);
+void efi_signal_event(struct efi_event *event);
 
 /* open file system: */
 struct efi_simple_file_system_protocol *efi_simple_file_system(
@@ -470,8 +535,12 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
                                efi_uintn_t *descriptor_size,
                                uint32_t *descriptor_version);
 /* Adds a range into the EFI memory map */
-uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
-                           bool overlap_only_ram);
+efi_status_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
+                               bool overlap_only_ram);
+/* Adds a conventional range into the EFI memory map */
+efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end,
+                                            u64 ram_top);
+
 /* Called by board init to initialize the EFI drivers */
 efi_status_t efi_driver_init(void);
 /* Called by board init to initialize the EFI memory map */
@@ -520,7 +589,6 @@ struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
 /* Check if a device path contains muliple instances */
 bool efi_dp_is_multi_instance(const struct efi_device_path *dp);
 
-struct efi_device_path *efi_dp_from_dev(struct udevice *dev);
 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part);
 /* Create a device node for a block device partition. */
 struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part);
@@ -545,27 +613,6 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
        (((_dp)->type == DEVICE_PATH_TYPE_##_type) && \
         ((_dp)->sub_type == DEVICE_PATH_SUB_TYPE_##_subtype))
 
-/**
- * ascii2unicode() - convert ASCII string to UTF-16 string
- *
- * A zero terminated ASCII string is converted to a zero terminated UTF-16
- * string. The output buffer must be preassigned.
- *
- * @unicode:   preassigned output buffer for UTF-16 string
- * @ascii:     ASCII string to be converted
- */
-static inline void ascii2unicode(u16 *unicode, const char *ascii)
-{
-       while (*ascii)
-               *(unicode++) = *(ascii++);
-       *unicode = 0;
-}
-
-static inline int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
-{
-       return memcmp(g1, g2, sizeof(efi_guid_t));
-}
-
 /*
  * Use these to indicate that your code / data should go into the EFI runtime
  * section and thus still be available when the OS is running
@@ -573,6 +620,9 @@ static inline int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
 #define __efi_runtime_data __attribute__ ((section (".data.efi_runtime")))
 #define __efi_runtime __attribute__ ((section (".text.efi_runtime")))
 
+/* Indicate supported runtime services */
+efi_status_t efi_init_runtime_supported(void);
+
 /* Update CRC32 in table header */
 void __efi_runtime efi_update_table_header_crc32(struct efi_table_hdr *table);
 
@@ -610,11 +660,16 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
                                     efi_uintn_t *data_size, void *data);
 efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
                                               u16 *variable_name,
-                                              const efi_guid_t *vendor);
+                                              efi_guid_t *vendor);
 efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
                                     const efi_guid_t *vendor, u32 attributes,
                                     efi_uintn_t data_size, const void *data);
 
+efi_status_t EFIAPI efi_query_variable_info(
+                       u32 attributes, u64 *maximum_variable_storage_size,
+                       u64 *remaining_variable_storage_size,
+                       u64 *maximum_variable_size);
+
 /*
  * See section 3.1.3 in the v2.7 UEFI spec for more details on
  * the layout of EFI_LOAD_OPTION.  In short it is:
@@ -640,6 +695,80 @@ void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
 unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
 efi_status_t efi_bootmgr_load(efi_handle_t *handle);
 
+#ifdef CONFIG_EFI_SECURE_BOOT
+#include <image.h>
+
+/**
+ * efi_image_regions - A list of memory regions
+ *
+ * @max:       Maximum number of regions
+ * @num:       Number of regions
+ * @reg:       array of regions
+ */
+struct efi_image_regions {
+       int                     max;
+       int                     num;
+       struct image_region     reg[];
+};
+
+/**
+ * efi_sig_data - A decoded data of struct efi_signature_data
+ *
+ * This structure represents an internal form of signature in
+ * signature database. A listed list may represent a signature list.
+ *
+ * @next:      Pointer to next entry
+ * @onwer:     Signature owner
+ * @data:      Pointer to signature data
+ * @size:      Size of signature data
+ */
+struct efi_sig_data {
+       struct efi_sig_data *next;
+       efi_guid_t owner;
+       void *data;
+       size_t size;
+};
+
+/**
+ * efi_signature_store - A decoded data of signature database
+ *
+ * This structure represents an internal form of signature database.
+ *
+ * @next:              Pointer to next entry
+ * @sig_type:          Signature type
+ * @sig_data_list:     Pointer to signature list
+ */
+struct efi_signature_store {
+       struct efi_signature_store *next;
+       efi_guid_t sig_type;
+       struct efi_sig_data *sig_data_list;
+};
+
+struct x509_certificate;
+struct pkcs7_message;
+
+bool efi_signature_verify_cert(struct x509_certificate *cert,
+                              struct efi_signature_store *dbx);
+bool efi_signature_verify_signers(struct pkcs7_message *msg,
+                                 struct efi_signature_store *dbx);
+bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs,
+                                    struct pkcs7_message *msg,
+                                 struct efi_signature_store *db,
+                                 struct x509_certificate **cert);
+
+efi_status_t efi_image_region_add(struct efi_image_regions *regs,
+                                 const void *start, const void *end,
+                                 int nocheck);
+
+void efi_sigstore_free(struct efi_signature_store *sigstore);
+struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name);
+
+bool efi_secure_boot_enabled(void);
+
+bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp,
+                    WIN_CERTIFICATE **auth, size_t *auth_len);
+#endif /* CONFIG_EFI_SECURE_BOOT */
+
 #else /* CONFIG_IS_ENABLED(EFI_LOADER) */
 
 /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */