From patchwork Sat Aug 19 15:17:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 110451 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2239504qge; Sat, 19 Aug 2017 08:18:03 -0700 (PDT) X-Received: by 10.84.236.11 with SMTP id q11mr13183495plk.401.1503155883036; Sat, 19 Aug 2017 08:18:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503155883; cv=none; d=google.com; s=arc-20160816; b=pFLh7Dp27bZUeksHXRIFk5/yjPrfR0gQwcUkOcWJ6/JtSKYCY6fHjBguKyEJpzsZcE 2sACXTuEjJ+20Ms02UkrWQK4Xn78qowSwC1b+m6ls6LdWRLwzNFaMEPsdJIr7RO53qHQ ZGrpVlxPXBaPTKL3asE1PAQXDmWN3NR1s3SpMK5gbln1LSWMs3k+BBXIzLYljmND4l0k dfBAuwH3YJHpkGO6JKDlU3PiRfM7kUx0lo5/Mo3oZd6+ckzgx5GvnNChFeekpAp3o0sj 9KP28JMV+iJheOm4T4lRIaeWVvjwj4j4IgKu0I0n3notW6W8pgjoRqueZOCLGqVDi315 7xFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=XdxBTb/paEfY0r+8drsXZmxhnN/Vy16BxRGcbYZiPxk=; b=oGfbquCHxP1Kc1aXGtUgOcpPmD9LaZvizdLcuZrmDO7lRKqVJtRNC71OfkLUOq9j5s NSrVgXFUaY5klPc3A5J8WH4Dz6PDIat68WObTWEdEtMs/IkQF7vyCxmfRzamconbkTei kLAHenVuYjt0E3bIRPAT+a4Tpq5YdDu1uv0idnPULkVCXqNqdJbD1Bh6FziJVYV+7Crj weRtQOQz9S36fpbtIijVVKN8XO2yMfYlE6fjQNogfDkezNN2beAd9pafkSQbvhe1dfxM 15F/A/lOnwQ6ILTNI9idNmyzE2/L/D3XnsV/zP2R4eFP3RiKH7I+qrd1tf8DadnC1piF 5uNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=LDrmQ1/h; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h131si3208406pgc.826.2017.08.19.08.18.02; Sat, 19 Aug 2017 08:18:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=LDrmQ1/h; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751153AbdHSPSC (ORCPT + 2 others); Sat, 19 Aug 2017 11:18:02 -0400 Received: from mail-wm0-f52.google.com ([74.125.82.52]:34835 "EHLO mail-wm0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751118AbdHSPSB (ORCPT ); Sat, 19 Aug 2017 11:18:01 -0400 Received: by mail-wm0-f52.google.com with SMTP id m85so19337444wma.0 for ; Sat, 19 Aug 2017 08:18:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=rZ9VUFLoYIrD2f2ZmQD+nvFX/6AZ86/2Eg7eKq25oJY=; b=LDrmQ1/hbG+Wjm96cHjev2rEaYeIj1Tz72F+kSVuy9fItns81weupe9Snkyl5TC32b sH3xqhKgdVqsTY/0rN5KcyAhWvnCNS6acc9+1eoV0gh9OMZv+aDrVU7aEWC/JZoUlfjs Md9MOyaWIxlEEM8FxVn2lylMddjWJnYAFlooQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=rZ9VUFLoYIrD2f2ZmQD+nvFX/6AZ86/2Eg7eKq25oJY=; b=UXqmd2xngQUH6CpqINUB9Aij6VN/IIAzbn+bdtJY7ZOiTwm8URcYw+gAWm+hfbUfTM SEVVXhzSsFM/f6kDHfQU/0KiJSIO0bSM+hsrKJ0AxpqIEOXLBks8wsJkrYaCmKPOEfQ9 dX17CVuCiHlWeA89sI5n/p/ouoy6ZVNp4m0V9VtXr/zT1ro+I4x9lLx20fT9SJAqeeyP whED8lmFieju7/n8JJpXc5Mq4NDKhBTQqxMkshWgm2sZGuKuiMKzNLPNULQWJn+WjHQb sSJh0rF0UB3RW9pzkW3ChYBI9k/O7CFmW+20qlRMbzK5lV8xXVQk2slYD+dAiBH2tq2d yeIw== X-Gm-Message-State: AHYfb5jyNE+iTfAtHn0tzv1c91qqdXbp/8LYNzbRQ3TxXwz2cyD6BizD zY8mISWxemCfd/qgmH9V3A== X-Received: by 10.28.227.215 with SMTP id a206mr1108519wmh.33.1503155879996; Sat, 19 Aug 2017 08:17:59 -0700 (PDT) Received: from localhost.localdomain ([154.146.161.128]) by smtp.gmail.com with ESMTPSA id y127sm4820292wmd.3.2017.08.19.08.17.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 19 Aug 2017 08:17:59 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, linux-hardened@lists.openwall.com Cc: leif.lindholm@linaro.org, matt@codeblueprint.co.uk, lukas@wunner.de, keescook@chromium.org, Ard Biesheuvel Subject: [RFC PATCH 1/2] efi: import USB I/O related declarations from the UEFI spec Date: Sat, 19 Aug 2017 16:17:39 +0100 Message-Id: <20170819151740.625-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org In preparation of adding support for the Chaoskey USB stick to the UEFI stub, import the USB I/O protocol declarations and related types to linux/efi.h. Signed-off-by: Ard Biesheuvel --- include/linux/efi.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/linux/efi.h b/include/linux/efi.h index 12e05118657c..253749cd9b62 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -622,6 +623,7 @@ void efi_native_runtime_setup(void); #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) #define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) #define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0) +#define EFI_USB_IO_PROTOCOL_GUID EFI_GUID(0x2b2f68d6, 0x0cd2, 0x44cf, 0x8e, 0x8b, 0xbb, 0xa2, 0x0b, 0x1b, 0x5b, 0x75) #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) @@ -1569,4 +1571,68 @@ struct linux_efi_random_seed { u8 bits[]; }; +typedef enum { + EfiUsbDataIn, + EfiUsbDataOut, + EfiUsbNoData +} efi_usb_data_direction_t; + +#define EFI_USB_NOERROR 0x0000 +#define EFI_USB_ERR_NOTEXECUTE 0x0001 +#define EFI_USB_ERR_STALL 0x0002 +#define EFI_USB_ERR_BUFFER 0x0004 +#define EFI_USB_ERR_BABBLE 0x0008 +#define EFI_USB_ERR_NAK 0x0010 +#define EFI_USB_ERR_CRC 0x0020 +#define EFI_USB_ERR_TIMEOUT 0x0040 +#define EFI_USB_ERR_BITSTUFF 0x0080 +#define EFI_USB_ERR_SYSTEM 0x0100 + +typedef struct { + u8 request_type; + u8 request; + u16 value; + u16 index; + u16 length; +} efi_usb_device_request_t; + +typedef efi_status_t (*efi_async_usb_transfer_callback_t)(void *, unsigned long, + void *, u32); + +typedef struct efi_usb_io_protocol { + efi_status_t (*control_transfer)(struct efi_usb_io_protocol *, + efi_usb_device_request_t *, + efi_usb_data_direction_t, + u32, void *, unsigned long, u32 *); + efi_status_t (*bulk_transfer)(struct efi_usb_io_protocol *, u8, void *, + unsigned long *, unsigned long, u32 *); + efi_status_t (*async_int_transfer)(struct efi_usb_io_protocol *, u8, + efi_bool_t, unsigned long, + unsigned long, + efi_async_usb_transfer_callback_t, + void *); + efi_status_t (*sync_int_transfer)(struct efi_usb_io_protocol *, u8, + void *, unsigned long *, + unsigned long, u32 *); + efi_status_t (*isoc_transfer)(struct efi_usb_io_protocol *, u8, void *, + unsigned long, u32 *); + efi_status_t (*async_isoc_transfer)(struct efi_usb_io_protocol *, u8 *, + void *, unsigned long, + efi_async_usb_transfer_callback_t, + void *); + efi_status_t (*get_device_descriptor)(struct efi_usb_io_protocol *, + struct usb_device_descriptor *); + efi_status_t (*get_config_descriptor)(struct efi_usb_io_protocol *, + struct usb_config_descriptor *); + efi_status_t (*get_iface_descriptor)(struct efi_usb_io_protocol *, + struct usb_interface_descriptor *); + efi_status_t (*get_ep_descriptor)(struct efi_usb_io_protocol *, u8, + struct usb_endpoint_descriptor *); + efi_status_t (*get_string_descriptor)(struct efi_usb_io_protocol *, + u16, u8, efi_char16_t **); + efi_status_t (*get_supported_languages)(struct efi_usb_io_protocol *, + u16 **, u16 *); + efi_status_t (*port_reset)(struct efi_usb_io_protocol *); +} efi_usb_io_protocol_t; + #endif /* _LINUX_EFI_H */ From patchwork Sat Aug 19 15:17:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 110452 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2239548qge; Sat, 19 Aug 2017 08:18:05 -0700 (PDT) X-Received: by 10.84.210.237 with SMTP id a100mr13367832pli.288.1503155885269; Sat, 19 Aug 2017 08:18:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503155885; cv=none; d=google.com; s=arc-20160816; b=lafa3rsZ0hXOG/CeZwZ8iR2nzc70/WCxQ2Rzb6MHIhQqCNh0Vv7/U7v2Gbgjq9RW0p gG0D83T2v0Zt6Mm5Dl+RiBpNe5X6cV9Ih/lRGD+zkOp10JaF1ivLze/CwXdUYUf2N96R ljnTDJuD2mwGSf5p2LExtso79Z7mMYGi809T94VGvx7QNKJt+c6gJX45GWCxgk2kNCLh FEzm9Vw6Vqqy7BhAtgQUgILKVle35MrjuSw4ocVLvIvVEJE9sN3eI62Y4fQku/vPncIW GBssMp9HiNSJnnDBekz+I+vDU8nhwNaKQEPl+F1QiTTUjDUHqRfbTG+z0G4Xk22wYK+g plHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=Iy9RLAxEKWRwqZfASUpD3euxUmI+EPpGQPw06OgDISI=; b=wYPZ2vwmXOQFVUt29ZbkiBBMukRreEr604PG7Dfxf+7qJDCq2VmgOsApcOxFn0VDAg E7aw6Bp2etEfkvvOc9uUh4qybXIREU4GDINPmsrqADzjcNU0ueUCLWnOShdcwFUwSxZf d7JLWy420eQSBLIARekBSYVz4B4vyCEOCmWDweJ6xoDjDaIhV706r3BrKiyyjB0kMRrH +oWHERhzPFHmhXXY1yZKPcgJbigWqn/WPGkcKXLpWwQNB+InZ3Bp1DXvJs90OYjZJS+B zVADe+VCYNZ6INxzU3MJKdOnhejcLe6OkbmAlw7GdT9PDCW4XtXLWAcZ2cRb8nGPQzUk TJbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kj3Tc1gb; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h131si3208406pgc.826.2017.08.19.08.18.05; Sat, 19 Aug 2017 08:18:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kj3Tc1gb; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751169AbdHSPSE (ORCPT + 2 others); Sat, 19 Aug 2017 11:18:04 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:36544 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751118AbdHSPSE (ORCPT ); Sat, 19 Aug 2017 11:18:04 -0400 Received: by mail-wm0-f49.google.com with SMTP id t201so19349280wmt.1 for ; Sat, 19 Aug 2017 08:18:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Re+jFTbVZpftaXLjxnnUy+voFslQA0Nt+ZywgLkx6Xc=; b=kj3Tc1gbCwJalDBdkuqh7G2kMJGu/fJpWW5aLr+YWQ4AcoQ7VapN0qSHyUCeaTF8VP XY6Ydk0RYeHvVrXvW7Pg9fkltHw7s2Ml7FRSct6Di2+XtlzIdLk0uFS0tM4Y36hnBd0a fg5vWX9q6QEnXldrRC6Lob0UfAhZT2LW9Ee3I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Re+jFTbVZpftaXLjxnnUy+voFslQA0Nt+ZywgLkx6Xc=; b=IOgZGXCV2XA2XawwJVQeZ3i1DUM1TZZOzaOthbrN7kypa/IubcJQIVsGzjGhgOYJLf pzHFnqamJzLfTTd5TJX9U4mgdQJXJbTHkjstwDiv9jDR/KyQxKIooIAE75IvOOBEEMlD JY/VoGtkpjP3jnW2oF/rPBqIh56Ocmw6P80woKxeLwqtQEBVBwjqwY5YXhGp2eMcKg7p idbuoZm/i/qCOmbAyah2IaSSiGwAQEM1kvtiYgPlt0l5ujnr5gSRyaVTA6DbR5P9e4Xt l9mgGZfX69t7HDe6H6qCSisO9+gRh2LLodLTiyOYagB8YNLQfAmqKSRKj4l6s46Uwt1q v+SA== X-Gm-Message-State: AHYfb5jie9VN08tAlxyOHiWWhHjre/Xjg1bF0B8hGthInBoBZVShCTNA PehrEambh20EkUU4YBRSuA== X-Received: by 10.28.173.15 with SMTP id w15mr227379wme.113.1503155882476; Sat, 19 Aug 2017 08:18:02 -0700 (PDT) Received: from localhost.localdomain ([154.146.161.128]) by smtp.gmail.com with ESMTPSA id y127sm4820292wmd.3.2017.08.19.08.18.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 19 Aug 2017 08:18:01 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, linux-hardened@lists.openwall.com Cc: leif.lindholm@linaro.org, matt@codeblueprint.co.uk, lukas@wunner.de, keescook@chromium.org, Ard Biesheuvel Subject: [RFC PATCH 2/2] efi: libstub: add support for the Chaoskey RNG USB stick to the stub Date: Sat, 19 Aug 2017 16:17:40 +0100 Message-Id: <20170819151740.625-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170819151740.625-1-ard.biesheuvel@linaro.org> References: <20170819151740.625-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Early entropy is hard to come by, especially on non-x86 systems that lack an architected instruction and are not as uniform as PCs. Fortunately, on UEFI systems, we can invoke the EFI_RNG_PROTOCOL, which exposes the platform specific entropy source in a generic way. We use this protocol to fill the RNG UEFI config table (which is used during early boot to seed the kernel's entropy pool), and on ARM and arm64, we invoke it to seed KASLR as well. Sadly, EFI_RNG_PROTOCOL is not widely implemented, and so it would be nice to have a fallback for UEFI systems that lack it. So implement this fallback based on the Chaoskey RNG USB stick, which should be exposed using the standard UEFI USB I/O protocol if the firmware has USB support. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/Kconfig | 7 ++ drivers/firmware/efi/libstub/Makefile | 2 +- drivers/firmware/efi/libstub/efistub.h | 3 + drivers/firmware/efi/libstub/random-chaoskey.c | 126 +++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/efi/libstub/random-chaoskey.c -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 2b4c39fdfa91..448a6186d9fb 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -87,6 +87,13 @@ config EFI_RUNTIME_WRAPPERS config EFI_ARMSTUB bool +config EFI_RNG_CHAOSKEY + bool "Chaoskey USB RNG support in the UEFI stub" + help + Fall back to a Chaoskey RNG USB stick in case EFI_RNG_PROTOCOL + is not implemented by the firmware. This is used for early + seeding of the entropy pool, and for KASLR on ARM and arm64. + config EFI_BOOTLOADER_CONTROL tristate "EFI Bootloader Control" depends on EFI_VARS diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index dedf9bde44db..fad6bc1d0e2a 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -40,7 +40,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \ $(patsubst %.c,lib-%.o,$(arm-deps)) - +lib-$(CONFIG_EFI_RNG_CHAOSKEY) += random-chaoskey.o lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 3afff5facd3b..9579ddb5937d 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -62,6 +62,9 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg, unsigned long size, unsigned long align, unsigned long *addr, unsigned long random_seed); +efi_status_t efi_get_random_chaoskey(efi_system_table_t *sys_table_arg, + unsigned long size, u8 *out); + efi_status_t check_platform_features(efi_system_table_t *sys_table_arg); efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg); diff --git a/drivers/firmware/efi/libstub/random-chaoskey.c b/drivers/firmware/efi/libstub/random-chaoskey.c new file mode 100644 index 000000000000..3f94ec3df9ff --- /dev/null +++ b/drivers/firmware/efi/libstub/random-chaoskey.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2017 Linaro Ltd; + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include + +#include "efistub.h" + +#define CHAOSKEY_VENDOR_ID 0x1d50 /* OpenMoko */ +#define CHAOSKEY_PRODUCT_ID 0x60c6 /* ChaosKey */ + +static efi_usb_io_protocol_t *chaoskey_usb_io; +static unsigned long chaoskey_usb_ep_addr, chaoskey_usb_ep_size; + +static void locate_chaoskey(efi_system_table_t *sys_table_arg) +{ + efi_guid_t usb_io_guid = EFI_USB_IO_PROTOCOL_GUID; + unsigned long bufsize = 0, i, j; + efi_handle_t *handles; + efi_status_t status; + + chaoskey_usb_io = (void *)-1; + + /* find all USB devices that UEFI knows about */ + status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL, + &usb_io_guid, NULL, &bufsize, NULL); + if (status != EFI_BUFFER_TOO_SMALL) + return; + + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, bufsize, + (void **)&handles); + if (status != EFI_SUCCESS) + return; + + status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL, + &usb_io_guid, NULL, &bufsize, handles); + if (status != EFI_SUCCESS) + goto out; + + for (i = 0; i < bufsize / sizeof(efi_handle_t); i++) { + struct usb_device_descriptor dev; + struct usb_interface_descriptor iface; + efi_usb_io_protocol_t *p; + + status = efi_call_early(handle_protocol, handles[i], + &usb_io_guid, (void **)&p); + if (status != EFI_SUCCESS) + continue; /* shouldn't happen */ + + /* get the device descriptor so we can check the vid/pid */ + status = p->get_device_descriptor(p, &dev); + if (status != EFI_SUCCESS) + continue; /* shouldn't happen either */ + + if (dev.idVendor != CHAOSKEY_VENDOR_ID || + dev.idProduct != CHAOSKEY_PRODUCT_ID) + continue; + + /* get the number of endpoints from the interface descriptor */ + status = p->get_iface_descriptor(p, &iface); + if (status != EFI_SUCCESS) + continue; + + /* locate the first BULK IN endpoint */ + for (j = 0; j < iface.bNumEndpoints; j++) { + struct usb_endpoint_descriptor ep; + + status = p->get_ep_descriptor(p, j, &ep); + if (status != EFI_SUCCESS) + continue; + + if (!usb_endpoint_dir_in(&ep) || + usb_endpoint_type(&ep) != USB_ENDPOINT_XFER_BULK) + continue; + + pr_efi(sys_table_arg, "Using ChaosKey for entropy\n"); + + chaoskey_usb_io = p; + chaoskey_usb_ep_addr = ep.bEndpointAddress; + chaoskey_usb_ep_size = usb_endpoint_maxp(&ep); + + goto out; + } + } + +out: + efi_call_early(free_pool, handles); +} + +efi_status_t efi_get_random_chaoskey(efi_system_table_t *sys_table_arg, + unsigned long size, u8 *out) +{ + efi_status_t status; + + if (chaoskey_usb_io == NULL) + locate_chaoskey(sys_table_arg); + if (chaoskey_usb_io == (void *)-1) + return EFI_NOT_FOUND; + + while (size > 0) { + u8 buf[chaoskey_usb_ep_size]; + unsigned long bsize = sizeof(buf); + u32 stat; + + status = chaoskey_usb_io->bulk_transfer(chaoskey_usb_io, + chaoskey_usb_ep_addr, + buf, &bsize, 50, &stat); + if (status != EFI_SUCCESS) { + pr_efi_err(sys_table_arg, + "ChaosKey USB communication failed!\n"); + return EFI_NOT_FOUND; + } + + bsize = min(size, bsize); + memcpy(out, buf, bsize); + out += bsize; + size -= bsize; + } + return EFI_SUCCESS; +}