public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: "Wu, Jiaxin" <jiaxin.wu@intel.com>,
	"Fu, Siyuan" <siyuan.fu@intel.com>,
	"Ye, Ting" <ting.ye@intel.com>, "Long, Qin" <qin.long@intel.com>,
	"Hsiung, Harry L" <harry.l.hsiung@intel.com>
Cc: edk2-devel-01 <edk2-devel@lists.01.org>
Subject: Re: setting the TLS cipher list for HTTPS booting
Date: Mon, 22 Jan 2018 10:37:32 +0100	[thread overview]
Message-ID: <7b529d2c-1e46-3bd5-d8a6-9225a630f23b@redhat.com> (raw)
In-Reply-To: <895558F6EA4E3B41AC93A00D163B72741635E571@SHSMSX103.ccr.corp.intel.com>

On 01/20/18 07:18, Wu, Jiaxin wrote:
>>
>> Hello Jiaxin, Siyuan,
>>
>> it seems that the "preferred set of ciphers" can be controlled at the
>> TLS session level.
>
>
> Jiaxin: Yes, TLS CipherList can be configured by TLS protocol.
>
>
>>
>> With regard to HTTPS booting, "NetworkPkg/HttpDxe" makes several
>> calls to EFI_TLS_PROTOCOL.SetSessionData() -- in the file
>> "NetworkPkg/HttpDxe/HttpsSupport.c", -- but it never passes
>> "EfiTlsCipherList" as argument for the "DataType" parameter.
>>
>
>
> Jiaxin: Correct, currently, HttpDxe as a TLS protocol consumer doesn't
> set the its own preferred CipherList because it prefers to use the
> default CipherList, which has been configured by TLS driver by
> default. The TLS default setting was happened during the creation  of
> new OpenSSL SSL_CTX object. The flow path is shown as below:
> TlsCtxNew -> SSL_CTX_new -> ssl_create_cipher_list.
> So, the default CipherList is:
>  # define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL"
>
>
>> Is there a way for platform code to control the list of ciphers?
>
>
> Jiaxin: Currently, not support yet.
>
>
>>
>> This is different from other "global" TLS aspects, such as
>> EFI_TLS_CONFIGURATION_PROTOCOL, because the latter is a singleton
>> "service" protocol, while EFI_TLS_PROTOCOL instances are created by
>> clients as-needed, via TLS service binding. So, I think if a platform
>> wanted to control this on the session level, then it would have to
>> "ask" HttpDxe somehow.
>>
>
>
> Jiaxin: EFI_TLS_CONFIGURATION_PROTOCOL provides the capability to set
> the client certificate/key pairs, different clients may use the
> different certificate/key Paris (so does OpenSSL). Based on this, it's
> not a singleton "service" protocol. So, in TlsDxe driver, we bind it
> to the same ChildHandle as TLS protocol.
>   Status = gBS->InstallMultipleProtocolInterfaces (
>                   ChildHandle,
>                   &gEfiTlsProtocolGuid,
>                   &TlsInstance->Tls,
>                   &gEfiTlsConfigurationProtocolGuid,
>                   &TlsInstance->TlsConfig,
>                   NULL
>                   );
> But above implementation also doesn't prevent all the clients use the
> same certificate/key Paris since they can use its own
> EFI_TLS_CONFIGURATION_PROTOCOL to configure the same "global"
> certificate/key pair (on the session level). That's depend on the TLS
> consumer.

Thank you for the correction.

Do I understand correctly that, consequently, these characteristics have
to be set in NetworkPkg/HttpDxe as well, similarly to the cipher list?

If that's correct, what would be the best way for a platform to control
these settings? Introducing separate dynamic PCDs is perhaps overkill.

Sometimes platform customization is implemented by the core module
calling out to an optional platform-provided protocol.

For example, PciHostBridgeDxe calls EDKII_IOMMU_PROTOCOL, if the
platform provides one.

Alternatively, PciBusDxe calls EFI_PCI_HOT_PLUG_INIT_PROTOCOL, if the
platform provides one.

Can we introduce a similar protocol here, so that HttpDxe can ask the
platform about the TLS preferences, and then configure TLS accordingly?


Sticking with the IOMMU example: in OVMF, we don't *always* have an
IOMMU protocol, but when we do, then we want PciHostBridgeDxe to wait
for the protocol (with a depex). So what we do is, we have a very small
library instance,

  OvmfPkg/Library/PlatformHasIoMmuLib/PlatformHasIoMmuLib.inf

with an empty constructor, and a DEPEX like this:

[Depex]
  gEdkiiIoMmuProtocolGuid OR gIoMmuAbsentProtocolGuid

(The latter protocol is from OvmfPkg.dec.)

Then, in the OVMF DSC files, we hook this library into PciHostBridgeDxe,
as a NULL class library. The end result is that PciHostBridgeDxe will
only be dispatched after OVMF platform code determines whether an IOMMU
is present or not. If not, then gIoMmuAbsentProtocolGuid is installed
(and PciHostBridgeDxe will be launched without an IOMMU). Otherwise
gEdkiiIoMmuProtocolGuid is installed by OVMF, and then PciHostBridgeDxe
is guaranteed to use the IOMMU.

In the HTTPS boot case, I'd make HttpDxe wait for the platform TLS
settings similarly -- NetworkPkg/HttpDxe would only have to look up the
protocol, and use it (for configuring TLS) if the protocol is there.

This looks more flexible than a large set of dynamic PCDs.

... We have such names already:

  EDKII_PLATFORM_LOGO_PROTOCOL
  EDKII_PLATFORM_VTD_POLICY_PROTOCOL

So we could introduce EDKII_PLATFORM_HTTPS_CONFIG_PROTOCOL, with the
following member functions:

  .GetData ()
  .GetSessionData ()

They would have similar signatures to
EFI_TLS_CONFIGURATION_PROTOCOL.GetData() and
EFI_TLS_PROTOCOL.GetSessionData().

"NetworkPkg/HttpDxe" could call each of these functions in a loop
(iterating over EFI_TLS_CONFIG_DATA_TYPE and EFI_TLS_SESSION_DATA_TYPE,
up to EfiTlsConfigDataTypeMaximum and EfiTlsSessionDataTypeMaximum,
respectively). If the platform has nothing to say about a given item, it
returns EFI_UNSUPPORTED. Otherwise, the platform returns the data that
the platform would like HttpDxe to set for that TLS setting.


>
>> 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.

Thank you!
Laszlo


  reply	other threads:[~2018-01-22  9:32 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-19 14:33 setting the TLS cipher list for HTTPS booting Laszlo Ersek
2018-01-20  6:18 ` Wu, Jiaxin
2018-01-22  9:37   ` Laszlo Ersek [this message]
2018-01-23  2:43     ` Wu, Jiaxin
2018-01-23 14:01       ` Laszlo Ersek
2018-01-23 15:01         ` Laszlo Ersek
2018-01-24  2:10           ` Wu, Jiaxin
2018-01-24  3:40             ` Wu, Jiaxin
2018-01-24  6:50               ` Wu, Jiaxin
2018-01-24 16:13                 ` Laszlo Ersek
2018-01-25  4:52                   ` Wu, Jiaxin
2018-01-25 12:41                     ` Laszlo Ersek
2018-02-05  3:33                       ` Wu, Jiaxin
2018-02-05 10:46                         ` Laszlo Ersek
2018-02-06  2:34                           ` Wu, Jiaxin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7b529d2c-1e46-3bd5-d8a6-9225a630f23b@redhat.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox