From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0FD0822333777 for ; Tue, 23 Jan 2018 05:55:42 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 85C30C056786; Tue, 23 Jan 2018 14:01:09 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-122-72.rdu2.redhat.com [10.10.122.72]) by smtp.corp.redhat.com (Postfix) with ESMTP id 180B018AD9; Tue, 23 Jan 2018 14:01:07 +0000 (UTC) To: "Wu, Jiaxin" , "Fu, Siyuan" , "Ye, Ting" , "Long, Qin" , "Hsiung, Harry L" Cc: edk2-devel-01 References: <5307d880-d016-ad91-04f5-6b83eb40f905@redhat.com> <895558F6EA4E3B41AC93A00D163B72741635E571@SHSMSX103.ccr.corp.intel.com> <7b529d2c-1e46-3bd5-d8a6-9225a630f23b@redhat.com> <895558F6EA4E3B41AC93A00D163B72741635F0B5@SHSMSX103.ccr.corp.intel.com> From: Laszlo Ersek Message-ID: <366c3083-0eb1-ecb4-2050-654c09135f8a@redhat.com> Date: Tue, 23 Jan 2018 15:01:07 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 In-Reply-To: <895558F6EA4E3B41AC93A00D163B72741635F0B5@SHSMSX103.ccr.corp.intel.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 23 Jan 2018 14:01:09 +0000 (UTC) Subject: Re: setting the TLS cipher list for HTTPS booting X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jan 2018 13:55:43 -0000 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Hi Jiaxin, > With above solution, if I understand correctly, the specific platform > needs to produce such a "EDKII_PLATFORM_HTTPS_CONFIG_PROTOCOL", which > will be consumed by HttpDxe driver. Yes, that's the idea. > If not existed, EFI_UNSUPPORTED returned. That's totally a > incompatibility change compared to the current solution. I understand that EDKII_PLATFORM_HTTPS_CONFIG_PROTOCOL is new to the HttpDxe driver. However, it does not *have* to be incompatible with the current logic: - HttpDxe could simply call gBS->LocateProtocol(). If the protocol is not found, simply do whatever the driver does right now. - If the protocol is found, then don't use the current logic. Instead, first call HttpsConfig->GetData() in a loop, and then second, call HttpsConfig->GetSessionData() in a loop. For each such call: - If the call succeeded, pass the retrieved data to EFI_TLS_CONFIGURATION_PROTOCOL.SetData() or EFI_TLS_PROTOCOL.SetSessionData, as appropriate. - If the call failed with EFI_UNSUPPORTED, simply skip the current EFI_TLS_CONFIG_DATA_TYPE or EFI_TLS_SESSION_DATA_TYPE value, and continue with the rest of the loop. - If the call fails with any other reason, log an error message and abort the loop. In the high level control flow, it is a simple LocateProtocol() call, and checking whether it succeeds. > Currently, we only support the EfiTlsConfigDataTypeCACertificate since > it's the only requirement of HTTPS one-way authentication. To support > that, Private variable is used to configure this CA certificate: > #define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate" > Then, HttpDxe instance will retrieve the variable to configure > CACertificate via EFI_TLS_CONFIGURATION_PROTOCOL. For compatibility > issue, we must take it into consideration. OVMF can use this variable. It is possible to write a DXE driver for OVMF that waits for the Variable Write Arch Protocol, sets the "TlsCaCertificate" variable as necessary, and then installs a custom NULL protocol in the protcol database. In turn the OVMF DSC file can make "HttpDxe" wait for this new NULL protocol, with a DEPEX. (Alternatively, we can plug a NULL-class library into HttpDxe that sets the variable just before HttpDxe starts.) My issue is not with the functionality; the problem is that OVMF users will want to control many other aspects of TLS (for HTTPS booting), not just the CA certificate for one-way authentication, and the TLS cipher suites. For example, they might want to specify a revocation list, the TLS compression method, and so on. We cannot tell in advance what other TLS configuration knobs will be introduced in the future. OVMF does not have any TLS preferences of its own, it just needs to propagate the TLS preferences that the end-user has already configured on the virtualization *host*. Basically the user sets up TLS on the host computer in some way, and then libvirt (which manages QEMU), QEMU (which runs the guest), and OVMF collaborate so that the same TLS settings take effect for HTTPS booting. If there are 10 guests on the same host computer, then the TLS configuration on the host should apply to HTTPS boot in all the guests. This is why I suggested the loops. If HttpDxe calls EDKII_PLATFORM_HTTPS_CONFIG_PROTOCOL.Get*() for all enumeration values, then we don't have to add new UEFI variables or PCDs when a new item appears. The EfiTls*Maximum enum constants will be bumped, and the loops will cover the new items. > Besides, all the configuration data are retrieved from platform > protocol instead of the PCD directly, which makes the platform/HttpDxe > have more dependency undeniably. The suggestion is about an optional dependency. HttpDxe does not have to wait for the protocol; I'm not suggesting a protocol notify, or a DEPEX for the driver itself. We'll take care of the DEPEX in the OVMF DSC file. The driver only needs a LocateProtocol() call. > At the same time, it will impact the *HTTP* feature since the driver > is only dispatched after platform determines whether the > "EDKII_PLATFORM_HTTPS_CONFIG_PROTOCOL" is present or not. This is not precise; the dispatch is delayed only if the platform DSC hooks a NULL-class library into HttpDxe that introduces a new DEPEX on the protocol. Other platforms would not delay HttpDxe. The LocateProtocol() call would fail and the driver would continue working like before. This is the same pattern that is used with the edk2 IOMMU protocol. > That's looks so weird if we bind the HTTPS_CONFIG_PROTOCOL to *HTTP* > feature. I think the LocateProtocol() call should be fine. HttpDxe covers both HTTP and HTTPS, and only the HTTP part is optional (via PcdAllowHttpConnections). The HTTPS part is always there. So checking for EDKII_PLATFORM_HTTPS_CONFIG_PROTOCOL would be just another aspect for TLS configuration. >>>> If you agree -- do you suggest a dynamic PCD, or an extension to >>>> the UEFI spec (at the HTTP level)? >>> >>> >>> Jiaxin: I agree with the dynamic PCD solution for the CipherList >>> setting, the PCD format can use as following one: >>> gEfiNetworkPkgTokenSpaceGuid.PcdHttpsTlsCipherLists >> |{0x0}|VOID*|0x0000000D >>> If the platform wants to set the below CipherSuites (RFC 5246 >>> defined): >>> CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00,0x35 }; >>> CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA256 = { 0x00,0x3D }; >>> The PCD can be configured by the corresponding platform as below, >>> otherwise it will use the OpenSSL default one: >>> gEfiNetworkPkgTokenSpaceGuid.PcdHttpsTlsCipherLists |{0x00,0x35, >> 0x00,0x3D }|VOID*|4 >>> what do you think? >> >> I feel the platform protocol could be more flexible and extensible. >> > > PCD defined in NetworkPkg is more like a general solution per HttpDxe > driver, it's easy and use directly, without so much dependency and > feature impact. So, I still prefer PCD solution. Functionally, I agree that OVMF can make the feature work, without any changes to the HttpDxe driver, *but* only for the following two configuration items: - CA certificate, through the (already existing) non-volatile UEFI variable - cipher suites (through the new dynamic PCD called "PcdHttpsTlsCipherLists") What about the rest of the configuration items? Should we introduce dynamic PCDs for those as well, individually? I cannot tell what other config items should be exposed right from the start. That's why I'm suggesting HTTPS_CONFIG_PROTOCOL -- it looks flexible and reasonably future-proof. BTW, I'm not asking that you write any code for this; I plan to submit the patches myself (for HttpDxe as well). We just have to figure out the direction first. If you really think that HttpDxe should only care about these two items (CA cert and cipher list), then I have another question: do you think it makes sense to introduce another non-volatile UEFI variable, for the cipher suites too? This would make things uniform, and perhaps TlsAuthConfigDxe could expose the cipher suites too, as a list of checkboxes. Just an idea. Thanks! Laszlo