From: yi1 li <yi1...@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3892

Add the following API and implementation to the TLS library:
1.TlsShutdown:
Shutdown the TLS connection without releasing the resources,
meaning a new connection can be started without calling TlsNew() and
without setting certificates etc.
2.TlsExportKey: Derive keying material from a TLS connection using the
mechanism described in RFC 5705 and export the key material (needed
by EAP methods such as EAP-TTLS and EAP-PEAP).

Cc: Jiewen Yao <jiewen....@intel.com>
Cc: Jian J Wang <jian.j.w...@intel.com>
Cc: Xiaoyu Lu <xiaoyu1...@intel.com>
Cc: Guomin Jiang <guomin.ji...@intel.com>
Signed-off-by: Yi Li <yi1...@intel.com>
---
 CryptoPkg/Driver/Crypto.c                     | 62 +++++++++++++++++++
 CryptoPkg/Include/Library/TlsLib.h            | 48 ++++++++++++++
 .../Pcd/PcdCryptoServiceFamilyEnable.h        |  2 +
 .../BaseCryptLibOnProtocolPpi/CryptLib.c      | 59 ++++++++++++++++++
 CryptoPkg/Library/TlsLib/TlsConfig.c          | 50 +++++++++++++++
 CryptoPkg/Library/TlsLib/TlsProcess.c         | 32 ++++++++++
 CryptoPkg/Library/TlsLibNull/TlsConfigNull.c  | 33 ++++++++++
 CryptoPkg/Library/TlsLibNull/TlsProcessNull.c | 23 +++++++
 CryptoPkg/Private/Protocol/Crypto.h           | 50 +++++++++++++++
 9 files changed, 359 insertions(+)

diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c
index 6c05c1a69447..6a86c4dba6a2 100644
--- a/CryptoPkg/Driver/Crypto.c
+++ b/CryptoPkg/Driver/Crypto.c
@@ -3882,6 +3882,28 @@ CryptoServiceTlsWrite (
   return CALL_BASECRYPTLIB (Tls.Services.Write, TlsWrite, (Tls, Buffer, 
BufferSize), 0);
 }
 
+/**
+  Shutdown a TLS connection.
+
+  Shutdown the TLS connection without releasing the resources, meaning a new
+  connection can be started without calling TlsNew() and without setting
+  certificates etc.
+
+  @param[in]       Tls            Pointer to the TLS object to shutdown.
+
+  @retval EFI_SUCCESS             The TLS is shutdown successfully.
+  @retval EFI_INVALID_PARAMETER   Tls is NULL.
+  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceTlsShutdown (
+  IN     VOID  *Tls
+  )
+{
+  return CALL_BASECRYPTLIB (Tls.Services.Shutdown, TlsShutdown, (Tls), 
EFI_UNSUPPORTED);
+}
+
 /**
   Set a new TLS/SSL method for a particular TLS object.
 
@@ -4498,6 +4520,44 @@ CryptoServiceTlsGetCertRevocationList (
   return CALL_BASECRYPTLIB (TlsGet.Services.CertRevocationList, 
TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED);
 }
 
+/**
+  Derive keying material from a TLS connection.
+
+  This function exports keying material using the mechanism described in RFC
+  5705.
+
+  @param[in]      Tls          Pointer to the TLS object
+  @param[in]      Label        Description of the key for the PRF function
+  @param[in]      Context,     Optional context
+  @param[in]      ContextLen   The length of the context value in bytes
+  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
+  @param[in]      KeyBufferLen The length of the KeyBuffer
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
+  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceTlsExportKey (
+  IN     VOID        *Tls,
+  IN     CONST VOID  *Label,
+  IN     CONST VOID  *Context,
+  IN     UINTN       ContextLen,
+  OUT    VOID        *KeyBuffer,
+  IN     UINTN       KeyBufferLen
+  )
+{
+  return CALL_BASECRYPTLIB (
+           TlsGet.Services.ExportKey,
+           TlsExportKey,
+           (Tls, Label, Context, ContextLen,
+            KeyBuffer, KeyBufferLen),
+           EFI_UNSUPPORTED
+           );
+}
+
 /**
   Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
 
@@ -4785,6 +4845,7 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   CryptoServiceTlsCtrlTrafficIn,
   CryptoServiceTlsRead,
   CryptoServiceTlsWrite,
+  CryptoServiceTlsShutdown,
   /// TLS Set
   CryptoServiceTlsSetVersion,
   CryptoServiceTlsSetConnectionEnd,
@@ -4812,6 +4873,7 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   CryptoServiceTlsGetHostPublicCert,
   CryptoServiceTlsGetHostPrivateKey,
   CryptoServiceTlsGetCertRevocationList,
+  CryptoServiceTlsExportKey,
   /// RSA PSS
   CryptoServiceRsaPssSign,
   CryptoServiceRsaPssVerify,
diff --git a/CryptoPkg/Include/Library/TlsLib.h 
b/CryptoPkg/Include/Library/TlsLib.h
index 24c1c1ed6477..8a109ec89d3d 100644
--- a/CryptoPkg/Include/Library/TlsLib.h
+++ b/CryptoPkg/Include/Library/TlsLib.h
@@ -310,6 +310,25 @@ TlsWrite (
   IN     UINTN  BufferSize
   );
 
+/**
+  Shutdown a TLS connection.
+
+  Shutdown the TLS connection without releasing the resources, meaning a new
+  connection can be started without calling TlsNew() and without setting
+  certificates etc.
+
+  @param[in]       Tls            Pointer to the TLS object to shutdown.
+
+  @retval EFI_SUCCESS             The TLS is shutdown successfully.
+  @retval EFI_INVALID_PARAMETER   Tls is NULL.
+  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsShutdown (
+  IN     VOID  *Tls
+  );
+
 /**
   Set a new TLS/SSL method for a particular TLS object.
 
@@ -851,4 +870,33 @@ TlsGetCertRevocationList (
   IN OUT UINTN  *DataSize
   );
 
+/**
+  Derive keying material from a TLS connection.
+
+  This function exports keying material using the mechanism described in RFC
+  5705.
+
+  @param[in]      Tls          Pointer to the TLS object
+  @param[in]      Label        Description of the key for the PRF function
+  @param[in]      Context,     Optional context
+  @param[in]      ContextLen   The length of the context value in bytes
+  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
+  @param[in]      KeyBufferLen The length of the KeyBuffer
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
+  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsExportKey (
+  IN     VOID        *Tls,
+  IN     CONST VOID  *Label,
+  IN     CONST VOID  *Context,
+  IN     UINTN       ContextLen,
+  OUT    VOID        *KeyBuffer,
+  IN     UINTN       KeyBufferLen
+  );
+
 #endif // __TLS_LIB_H__
diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h 
b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
index 6f5cde161006..589794776808 100644
--- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
+++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
@@ -251,6 +251,7 @@ typedef struct {
       UINT8    CtrlTrafficIn  : 1;
       UINT8    Read           : 1;
       UINT8    Write          : 1;
+      UINT8    Shutdown       : 1;
     } Services;
     UINT32    Family;
   } Tls;
@@ -286,6 +287,7 @@ typedef struct {
       UINT8    HostPublicCert       : 1;
       UINT8    HostPrivateKey       : 1;
       UINT8    CertRevocationList   : 1;
+      UINT8    ExportKey            : 1;
     } Services;
     UINT32    Family;
   } TlsGet;
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c 
b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index 757b8e40e442..1c7c90e432de 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -3025,6 +3025,28 @@ TlsWrite (
   CALL_CRYPTO_SERVICE (TlsWrite, (Tls, Buffer, BufferSize), 0);
 }
 
+/**
+  Shutdown a TLS connection.
+
+  Shutdown the TLS connection without releasing the resources, meaning a new
+  connection can be started without calling TlsNew() and without setting
+  certificates etc.
+
+  @param[in]       Tls            Pointer to the TLS object to shutdown.
+
+  @retval EFI_SUCCESS             The TLS is shutdown successfully.
+  @retval EFI_INVALID_PARAMETER   Tls is NULL.
+  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsShutdown (
+  IN     VOID  *Tls
+  )
+{
+  CALL_CRYPTO_SERVICE (TlsShutdown, (Tls), EFI_UNSUPPORTED);
+}
+
 /**
   Set a new TLS/SSL method for a particular TLS object.
 
@@ -3644,3 +3666,40 @@ TlsGetCertRevocationList (
 {
   CALL_CRYPTO_SERVICE (TlsGetCertRevocationList, (Data, DataSize), 
EFI_UNSUPPORTED);
 }
+
+/**
+  Derive keying material from a TLS connection.
+
+  This function exports keying material using the mechanism described in RFC
+  5705.
+
+  @param[in]      Tls          Pointer to the TLS object
+  @param[in]      Label        Description of the key for the PRF function
+  @param[in]      Context,     Optional context
+  @param[in]      ContextLen   The length of the context value in bytes
+  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
+  @param[in]      KeyBufferLen The length of the KeyBuffer
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
+  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsExportKey (
+  IN     VOID        *Tls,
+  IN     CONST VOID  *Label,
+  IN     CONST VOID  *Context,
+  IN     UINTN       ContextLen,
+  OUT    VOID        *KeyBuffer,
+  IN     UINTN       KeyBufferLen
+  )
+{
+  CALL_CRYPTO_SERVICE (
+    TlsExportKey,
+    (Tls, Label, Context, ContextLen,
+     KeyBuffer, KeyBufferLen),
+    EFI_UNSUPPORTED
+    );
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c 
b/CryptoPkg/Library/TlsLib/TlsConfig.c
index 5c32f1c3329f..b45050c18770 100644
--- a/CryptoPkg/Library/TlsLib/TlsConfig.c
+++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
@@ -1555,3 +1555,53 @@ TlsGetCertRevocationList (
 {
   return EFI_UNSUPPORTED;
 }
+
+/**
+  Derive keying material from a TLS connection.
+
+  This function exports keying material using the mechanism described in RFC
+  5705.
+
+  @param[in]      Tls          Pointer to the TLS object
+  @param[in]      Label        Description of the key for the PRF function
+  @param[in]      Context,     Optional context
+  @param[in]      ContextLen   The length of the context value in bytes
+  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
+  @param[in]      KeyBufferLen The length of the KeyBuffer
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
+  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsExportKey (
+  IN     VOID        *Tls,
+  IN     CONST VOID  *Label,
+  IN     CONST VOID  *Context,
+  IN     UINTN       ContextLen,
+  OUT    VOID        *KeyBuffer,
+  IN     UINTN       KeyBufferLen
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *)Tls;
+
+  if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return SSL_export_keying_material (
+           TlsConn->Ssl,
+           KeyBuffer,
+           KeyBufferLen,
+           Label,
+           AsciiStrLen (Label),
+           Context,
+           ContextLen,
+           Context != NULL
+           ) == 1 ?
+         EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsProcess.c 
b/CryptoPkg/Library/TlsLib/TlsProcess.c
index 0f2ad7a9fbc0..a803d86c4f4e 100644
--- a/CryptoPkg/Library/TlsLib/TlsProcess.c
+++ b/CryptoPkg/Library/TlsLib/TlsProcess.c
@@ -461,3 +461,35 @@ TlsWrite (
   //
   return SSL_write (TlsConn->Ssl, Buffer, (UINT32)BufferSize);
 }
+
+/**
+  Shutdown a TLS connection.
+
+  Shutdown the TLS connection without releasing the resources, meaning a new
+  connection can be started without calling TlsNew() and without setting
+  certificates etc.
+
+  @param[in]       Tls            Pointer to the TLS object to shutdown.
+
+  @retval EFI_SUCCESS             The TLS is shutdown successfully.
+  @retval EFI_INVALID_PARAMETER   Tls is NULL.
+  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsShutdown (
+  IN     VOID  *Tls
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *)Tls;
+
+  if ((TlsConn == NULL) || ((TlsConn->Ssl) == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SSL_set_quiet_shutdown (TlsConn->Ssl, 1);
+  SSL_shutdown (TlsConn->Ssl);
+  return SSL_clear (TlsConn->Ssl) == 1 ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
diff --git a/CryptoPkg/Library/TlsLibNull/TlsConfigNull.c 
b/CryptoPkg/Library/TlsLibNull/TlsConfigNull.c
index 22d258c7f18f..b2c7e6869f53 100644
--- a/CryptoPkg/Library/TlsLibNull/TlsConfigNull.c
+++ b/CryptoPkg/Library/TlsLibNull/TlsConfigNull.c
@@ -647,3 +647,36 @@ TlsGetCertRevocationList (
   ASSERT (FALSE);
   return EFI_UNSUPPORTED;
 }
+
+/**
+  Derive keying material from a TLS connection.
+
+  This function exports keying material using the mechanism described in RFC
+  5705.
+
+  @param[in]      Tls          Pointer to the TLS object
+  @param[in]      Label        Description of the key for the PRF function
+  @param[in]      Context,     Optional context
+  @param[in]      ContextLen   The length of the context value in bytes
+  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
+  @param[in]      KeyBufferLen The length of the KeyBuffer
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
+  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsExportKey (
+  IN     VOID        *Tls,
+  IN     CONST VOID  *Label,
+  IN     CONST VOID  *Context,
+  IN     UINTN       ContextLen,
+  OUT    VOID        *KeyBuffer,
+  IN     UINTN       KeyBufferLen
+  )
+{
+  ASSERT (FALSE);
+  return EFI_UNSUPPORTED;
+}
diff --git a/CryptoPkg/Library/TlsLibNull/TlsProcessNull.c 
b/CryptoPkg/Library/TlsLibNull/TlsProcessNull.c
index 0958ddd8d608..395dac548d22 100644
--- a/CryptoPkg/Library/TlsLibNull/TlsProcessNull.c
+++ b/CryptoPkg/Library/TlsLibNull/TlsProcessNull.c
@@ -245,3 +245,26 @@ TlsWrite (
   ASSERT (FALSE);
   return 0;
 }
+
+/**
+  Shutdown a TLS connection.
+
+  Shutdown the TLS connection without releasing the resources, meaning a new
+  connection can be started without calling TlsNew() and without setting
+  certificates etc.
+
+  @param[in]       Tls            Pointer to the TLS object to shutdown.
+
+  @retval EFI_SUCCESS             The TLS is shutdown successfully.
+  @retval EFI_INVALID_PARAMETER   Tls is NULL.
+  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsShutdown (
+  IN     VOID  *Tls
+  )
+{
+  ASSERT (FALSE);
+  return EFI_UNSUPPORTED;
+}
diff --git a/CryptoPkg/Private/Protocol/Crypto.h 
b/CryptoPkg/Private/Protocol/Crypto.h
index 8de05a99bdcc..bc94cbb66311 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -2868,6 +2868,25 @@ INTN
   IN     UINTN                    BufferSize
   );
 
+/**
+  Shutdown a TLS connection.
+
+  Shutdown the TLS connection without releasing the resources, meaning a new
+  connection can be started without calling TlsNew() and without setting
+  certificates etc.
+
+  @param[in]       Tls            Pointer to the TLS object to shutdown.
+
+  @retval EFI_SUCCESS             The TLS is shutdown successfully.
+  @retval EFI_INVALID_PARAMETER   Tls is NULL.
+  @retval EFI_PROTOCOL_ERROR      Some other error occurred.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_CRYPTO_TLS_SHUTDOWN)(
+  IN     VOID                     *Tls
+  );
+
 /**
   Set a new TLS/SSL method for a particular TLS object.
 
@@ -3388,6 +3407,35 @@ EFI_STATUS
   IN     UINTN                    DataSize
   );
 
+/**
+  Derive keying material from a TLS connection.
+
+  This function exports keying material using the mechanism described in RFC
+  5705.
+
+  @param[in]      Tls          Pointer to the TLS object
+  @param[in]      Label        Description of the key for the PRF function
+  @param[in]      Context,     Optional context
+  @param[in]      ContextLen   The length of the context value in bytes
+  @param[out]     KeyBuffer    Buffer to hold the output of the TLS-PRF
+  @param[in]      KeyBufferLen The length of the KeyBuffer
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The TLS object is invalid.
+  @retval  EFI_PROTOCOL_ERROR      Some other error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_CRYPTO_TLS_EXPORT_KEY)(
+  IN     VOID                     *Tls,
+  IN     CONST VOID              *Label,
+  IN     CONST VOID               *Context,
+  IN     UINTN                    ContextLen,
+  OUT    VOID                     *KeyBuffer,
+  IN     UINTN                    KeyBufferLen
+  );
+
 /**
   Gets the CA-supplied certificate revocation list data set in the specified
   TLS object.
@@ -3671,6 +3719,7 @@ struct _EDKII_CRYPTO_PROTOCOL {
   EDKII_CRYPTO_TLS_CTRL_TRAFFIC_IN                   TlsCtrlTrafficIn;
   EDKII_CRYPTO_TLS_READ                              TlsRead;
   EDKII_CRYPTO_TLS_WRITE                             TlsWrite;
+  EDKII_CRYPTO_TLS_SHUTDOWN                          TlsShutdown;
   /// TLS Set
   EDKII_CRYPTO_TLS_SET_VERSION                       TlsSetVersion;
   EDKII_CRYPTO_TLS_SET_CONNECTION_END                TlsSetConnectionEnd;
@@ -3698,6 +3747,7 @@ struct _EDKII_CRYPTO_PROTOCOL {
   EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT              TlsGetHostPublicCert;
   EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY              TlsGetHostPrivateKey;
   EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST          TlsGetCertRevocationList;
+  EDKII_CRYPTO_TLS_EXPORT_KEY                        TlsExportKey;
   /// RSA PSS
   EDKII_CRYPTO_RSA_PSS_SIGN                          RsaPssSign;
   EDKII_CRYPTO_RSA_PSS_VERIFY                        RsaPssVerify;
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#89927): https://edk2.groups.io/g/devel/message/89927
Mute This Topic: https://groups.io/mt/91262940/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to