From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by mx.groups.io with SMTP id smtpd.web10.10807.1591105139996320715 for ; Tue, 02 Jun 2020 06:39:00 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=w63xoXkr; spf=pass (domain: linaro.org, ip: 209.85.221.67, mailfrom: ard.biesheuvel@linaro.org) Received: by mail-wr1-f67.google.com with SMTP id l11so3490315wru.0 for ; Tue, 02 Jun 2020 06:38:59 -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:mime-version :content-transfer-encoding; bh=/VHrGl0m89FqQNrotKwPVOgnEiu5gzVLg2xL6GdaqWw=; b=w63xoXkrcOeabc3VnJCYdBf8sEPLFirbxJIEdPXZeWw8NYrCw9ppP91DFoqccer1Ev LTV80yBYVlwz2Uh+cCjffGqmWrqXwCbh1/TGEoLdoy8GpKf5pftSvSHWamwSvlt63LLw FjeEJaQrZS3JfpNdax9rqFqW8dRt6lmoL7ZcY9OaI4MxBkn1KV5+1L4QPuMFQZdnBS7O DBf8qUsCBOm3ffbHHlZDUyDY6Eypw1rE4d0bJIZVlGDCDWZirmDE+pz7nQI0AR72zspe Ft1ixbvJNb3V7wuipwm6QTxQ5MjcYZZLVR4pwt+Kx8fFWtiBX04eIqZTNCO9QV6f1bps +xqw== 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:mime-version :content-transfer-encoding; bh=/VHrGl0m89FqQNrotKwPVOgnEiu5gzVLg2xL6GdaqWw=; b=Zu9ShtcHbG+DT8KOH73hv6EBBd56j4N9f1aGZEANUcZXiXUynpvoUxt0ElHYfDo/4t Or24Vwy3rAKPbLPoqHTfTTsi6swvM5ytKs8bcR/0GpmnDXx6RKfstkSYBM+ZtshU8nmz QTQMaXFukkweBG326cAQSokGquxlTn1LG1G0jqIQURowXfPe4Xl/JwVQJPum8By39lhJ i9hwWCfwgIHn1xxLmCjkn+oU7Pw7hgSDm5m8frI9jx+PLp2xOuH/qApXKl+T2KqZBRXN Fm4xjTtAfGVI7baQ3F4XBEz19dIE3ItHzOFXmMtduFSYdfgiJ0yK+kgWl0sn9i9Q36l9 Qwhw== X-Gm-Message-State: AOAM531rF3O5obY7I19jx62iAl7JLiz9QMhfgc7wYp7atG6tXY31KjW5 gjgJDDBiruEdXAns0uSuuT/0gxgvfac= X-Google-Smtp-Source: ABdhPJxga1lLSLm8VxXkGalxrpM9AFqqQEZ7/7M8NbnfrOBvQnytAsupvor/G0OGn0bfbrYKCq8lGA== X-Received: by 2002:a5d:5744:: with SMTP id q4mr25389390wrw.137.1591105138226; Tue, 02 Jun 2020 06:38:58 -0700 (PDT) Return-Path: Received: from localhost.localdomain (82-64-249-211.subs.proxad.net. [82.64.249.211]) by smtp.gmail.com with ESMTPSA id p16sm4441201wru.27.2020.06.02.06.38.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jun 2020 06:38:57 -0700 (PDT) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: leif@nuviainc.com, Ard Biesheuvel Subject: [PATCH edk2-platforms v2] Silicon/ChaosKeyDxe: don't rely on connect all controllers Date: Tue, 2 Jun 2020 15:38:49 +0200 Message-Id: <20200602133849.5422-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Ard Biesheuvel The ChaosKey driver implements the UEFI driver model, and so it is not guaranteed that any controllers will be attached to this driver unless it is connected explicitly. On many platforms today, this is taken care of by the ConnectAll() call that occurs in the BDS, but this is not something we should rely on. So add a protocol notification event that will attempt to connect the ChaosKey on each USB I/O protocol instance that carries the expected vendor and product IDs. This still relies on the USB host controllers to be connected by the platform, which is typically the case (given that a USB keyboard is required to interrupt the boot) On platforms where USB is not connected at all by default, it is really not up to a third party driver to meddle with this, and so relying on the USB host controllers to have been connected non-reursively is the best we can do. Note that third party drivers registered via Driver#### can set a 'reconnect all' flag if needed to mitigate this. Signed-off-by: Ard Biesheuvel --- Unfortunately, the previous approach of connecting a short-form USB device path containing the ChaosKey's VID/PID turned out not to be reliable in practice (it doesn't work at all on ThunderX2 with AMI firmware) So instead, we have to rely on USB I/O protocols having been instantiated by the DXE core. This is what typically happens, given that USB keyboards are also exposed via USB I/O protocol instances. The only difference with a non-fast [ConnectAll()] boot is that those USB I/O protocol instances are not connected further automatically, but it is reasonable to expect that the handles themselves have been instantiated. Platforms that do not produce those USB I/O handles would not be able to offer the ability to interrupt the boot or enter the menu using a USB keyboard, so this is rather rare in practice. Also, if such platforms do exist, it is not up to this 3rd party driver to override this policy and enumerate the entire USB hierarchy. So this means we need to call UsbHwrngDriverBindingSupported() directly to check whether the USB I/O protocol in question has the right VID/PID. If that succeeds, there is really no point in using ConnectController(), so just call UsbHwrngDriverBindingStart() directly to connect the driver to the controller. Tested on ThunderX2 using a Driver0000 option. Silicon/Openmoko/ChaosKeyDxe/DriverBinding.c | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/Silicon/Openmoko/ChaosKeyDxe/DriverBinding.c b/Silicon/Openmoko/ChaosKeyDxe/DriverBinding.c index e7d0d3fe563e..611803c6c339 100644 --- a/Silicon/Openmoko/ChaosKeyDxe/DriverBinding.c +++ b/Silicon/Openmoko/ChaosKeyDxe/DriverBinding.c @@ -11,6 +11,9 @@ #include "ChaosKeyDriver.h" +STATIC VOID *mProtocolNotifyRegistration; +STATIC EFI_EVENT mProtocolNotifyRegistrationEvent; + /** Tests to see if this driver supports a given controller. @@ -157,6 +160,55 @@ EFI_DRIVER_BINDING_PROTOCOL gUsbDriverBinding = { }; +STATIC +VOID +EFIAPI +UsbHwrngOnProtocolNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN HandleCount; + UINTN Index; + + do { + Status = gBS->LocateHandleBuffer (ByRegisterNotify, NULL, + mProtocolNotifyRegistration, &HandleCount, &Handles); + if (EFI_ERROR (Status)) { + if (Status != EFI_NOT_FOUND) { + DEBUG ((DEBUG_WARN, "%a: LocateHandleBuffer() failed - %r\n", + __FUNCTION__, Status)); + } + return; + } + + if (HandleCount == 0) { + return; + } + + for (Index = 0; Index < HandleCount; Index++) { + Status = UsbHwrngDriverBindingSupported (&gUsbDriverBinding, + Handles[Index], NULL); + if (EFI_ERROR (Status)) { + continue; + } + + // + // Attempt to connect the USB device path describing the ChaosKey + // hardware via the handle describing a USB host controller. + // + Status = UsbHwrngDriverBindingStart (&gUsbDriverBinding, + Handles[Index], NULL); + DEBUG ((DEBUG_VERBOSE, "%a: UsbHwrngDriverBindingStart () returned %r\n", + __FUNCTION__, Status)); + } + gBS->FreePool (Handles); + } while (1); +} + + /** The entry point of ChaosKey UEFI Driver. @@ -185,6 +237,18 @@ EntryPoint ( NULL, &gChaosKeyDriverComponentName2); ASSERT_EFI_ERROR (Status); + // + // This driver produces the EFI Random Number Generator protocol on + // compatible USB I/O handles, which is not a protocol that can provide + // a boot target. This means that it will not get connected on an ordinary + // 'fast' boot (which only connects the console and boot entry device paths) + // unless we take extra measures. + // + mProtocolNotifyRegistrationEvent = EfiCreateProtocolNotifyEvent ( + &gEfiUsbIoProtocolGuid, TPL_CALLBACK, + UsbHwrngOnProtocolNotify, NULL, + &mProtocolNotifyRegistration); + DEBUG ((DEBUG_INIT | DEBUG_INFO, "*** Installed ChaosKey driver! ***\n")); return EFI_SUCCESS; @@ -211,6 +275,8 @@ UnloadImage ( UINTN HandleCount; UINTN Index; + gBS->CloseEvent (mProtocolNotifyRegistrationEvent); + // // Retrieve all USB I/O handles in the handle database // -- 2.20.1