From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web08.12308.1653184484313245119 for ; Sat, 21 May 2022 18:54:48 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=iNg5XJyR; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: yi1.li@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653184487; x=1684720487; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ejrnqJqxWaaFKh6Ua03QaQd+tVPqqlAnJ8iZWxHSMQY=; b=iNg5XJyRuf1zQxpp1qxuCshm/ku2rCg7LF8gkWY8ZCXCCau4MMF57t8Q VbsMAQeSBLl6AT2AxFOn/64ua+PqFDVydqMBjDttL9HqJ4qKcyWE8cPnv Ye44wcpimc7hG9cFMmaA/dCCqvv+z/fzK556QM3ZXUDgIbyEqyTWDmHw4 QqHBGVA2OFPJrngq5cZp1kMkWA0Kql377qVmWTx+KYSViQCLb6dLIytnv eXNifiOpgYUQnHySihe8tp2O3X9lYdxY3h67buMQNIeMD1eS3p+T2aMxA xRvk8NffRUo5KvR3GPnmOMBQGjcBIYHHxNu4vfATVjHErTdHT3cgLChqF w==; X-IronPort-AV: E=McAfee;i="6400,9594,10354"; a="272638252" X-IronPort-AV: E=Sophos;i="5.91,243,1647327600"; d="scan'208";a="272638252" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 May 2022 18:54:47 -0700 X-IronPort-AV: E=Sophos;i="5.91,243,1647327600"; d="scan'208";a="599981533" Received: from shwdejointd178.ccr.corp.intel.com ([10.239.153.103]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 May 2022 18:54:45 -0700 From: "yi1 li" To: devel@edk2.groups.io Cc: yi1 li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Subject: [PATCH 3/5] CryptoPkg: Add APIs TlsShutdown and TlsExportKey to TlsLib Date: Sun, 22 May 2022 09:54:17 +0800 Message-Id: <2586704e02647e6f1d1d5e805eb0f267ad6d73ad.1653183737.git.yi1.li@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: yi1 li 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 Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li --- 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