From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D096F81CE1 for ; Wed, 2 Nov 2016 01:36:36 -0700 (PDT) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP; 02 Nov 2016 01:36:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,583,1473145200"; d="scan'208";a="186658308" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by fmsmga004.fm.intel.com with ESMTP; 02 Nov 2016 01:36:38 -0700 Received: from FMSMSX109.amr.corp.intel.com (10.18.116.9) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 2 Nov 2016 01:36:38 -0700 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by fmsmsx109.amr.corp.intel.com (10.18.116.9) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 2 Nov 2016 01:36:36 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.139]) by shsmsx102.ccr.corp.intel.com ([169.254.2.206]) with mapi id 14.03.0248.002; Wed, 2 Nov 2016 16:36:33 +0800 From: "Ye, Ting" To: "Long, Qin" , "edk2-devel@lists.01.org" Thread-Topic: [edk2] [Patch] CryptoPkg: Add PKCS5 PBKDF2 interface for password derivation. Thread-Index: AQHSM+vjO2vubmn2Y0CrJkxr2BFXZKDFYI1w Date: Wed, 2 Nov 2016 08:36:33 +0000 Message-ID: References: <20161101025833.10372-1-qin.long@intel.com> In-Reply-To: <20161101025833.10372-1-qin.long@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [Patch] CryptoPkg: Add PKCS5 PBKDF2 interface for password derivation. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Nov 2016 08:36:37 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Looks good to me. Reviewed-by: Ye Ting -----Original Message----- From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Qin = Long Sent: Tuesday, November 01, 2016 10:59 AM To: edk2-devel@lists.01.org Cc: Ye, Ting Subject: [edk2] [Patch] CryptoPkg: Add PKCS5 PBKDF2 interface for password = derivation. Add one new API (Pkcs5HashPassword) to provide PKCS#5 v2.0 PBKDF2 support (= Password based encryption key derivation function, specified in RFC 2898). Also update the Cryptest utility to include the new API testing (with the t= est vector from RFC6070). Cc: Ting Ye Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qin Long --- CryptoPkg/Application/Cryptest/Cryptest.c | 9 +- CryptoPkg/Application/Cryptest/Cryptest.h | 16 +++- CryptoPkg/Application/Cryptest/Cryptest.inf | 5 +- CryptoPkg/Application/Cryptest/Pkcs5Pbkdf2Verify.c | 94 +++++++++++++++++= ++ CryptoPkg/Include/Library/BaseCryptLib.h | 40 ++++++++ CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf | 1 + .../Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c | 101 +++++++++++++++++= ++++ .../Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c | 56 ++++++++++++ CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | 1 + CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | 1 + 11 files changed, 319 insertions(+), 6 deletions(-) create mode 100644 Cr= yptoPkg/Application/Cryptest/Pkcs5Pbkdf2Verify.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.= c diff --git a/CryptoPkg/Application/Cryptest/Cryptest.c b/CryptoPkg/Applicat= ion/Cryptest/Cryptest.c index 79c1850..13b7073 100644 --- a/CryptoPkg/Application/Cryptest/Cryptest.c +++ b/CryptoPkg/Application/Cryptest/Cryptest.c @@ -1,7 +1,7 @@ /** @file Application for Cryptographic Primitives Validation. =20 -Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made availab= le under the terms and conditions of the BSD License which accompanies thi= s distribution. The full text of the license may be found at @@ -63,6 +63,= 11 @@ CryptestMain ( return Status; } =20 + Status =3D ValidateCryptPkcs5Pbkdf2 (); if (EFI_ERROR (Status)) { + return Status; + } + Status =3D ValidateCryptPkcs7 (); if (EFI_ERROR (Status)) { return Status; @@ -89,4 +94,4 @@ CryptestMain ( } =20 return EFI_SUCCESS; -} \ No newline at end of file +} diff --git a/CryptoPkg/Application/Cryptest/Cryptest.h b/CryptoPkg/Applicat= ion/Cryptest/Cryptest.h index 17b4224..9e3e0fb 100644 --- a/CryptoPkg/Application/Cryptest/Cryptest.h +++ b/CryptoPkg/Application/Cryptest/Cryptest.h @@ -1,7 +1,7 @@ /** @file Application for Cryptographic Primitives Validation. =20 -Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made availab= le under the terms and conditions of the BSD License which accompanies thi= s distribution. The full text of the license may be found at @@ -85,6 +85,= 18 @@ ValidateCryptRsa2 ( ); =20 /** + Validate UEFI-OpenSSL PKCS#5 PBKDF2 Interface. + + @retval EFI_SUCCESS Validation succeeded. + @retval EFI_ABORTED Validation failed. + +**/ +EFI_STATUS +ValidateCryptPkcs5Pbkdf2 ( + VOID + ); + +/** Validate UEFI-OpenSSL PKCS#7 Signing & Verification Interfaces. =20 @retval EFI_SUCCESS Validation succeeded. @@ -144,4 +156,4 @@ ValidateCryptPrng ( VOID ); =20 -#endif \ No newline at end of file +#endif diff --git a/CryptoPkg/Application/Cryptest/Cryptest.inf b/CryptoPkg/Applic= ation/Cryptest/Cryptest.inf index 11175e5..b7f779c 100644 --- a/CryptoPkg/Application/Cryptest/Cryptest.inf +++ b/CryptoPkg/Application/Cryptest/Cryptest.inf @@ -1,9 +1,9 @@ ## @file # Shell application that will test the crypto library. # -# UEFI Application for the Validation of cryptography library (based on O= penSSL 0.9.8zb). +# UEFI Application for the Validation of cryptography library (based on O= penSSL-1.0.2j). # -# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2009 - 2016, Intel Corporation. All rights=20 +reserved.
# This program and the accompanying materials # are licensed and made a= vailable under the terms and conditions of the BSD License # which accomp= anies this distribution. The full text of the license may be found at @@ -= 37,6 +37,7 @@ BlockCipherVerify.c RsaVerify.c RsaVerify2.c + Pkcs5Pbkdf2Verify.c AuthenticodeVerify.c TSVerify.c DhVerify.c diff --git a/CryptoPkg/Application/Cryptest/Pkcs5Pbkdf2Verify.c b/CryptoPkg= /Application/Cryptest/Pkcs5Pbkdf2Verify.c new file mode 100644 index 0000000..84652d3 --- /dev/null +++ b/CryptoPkg/Application/Cryptest/Pkcs5Pbkdf2Verify.c @@ -0,0 +1,94 @@ +/** @file + Application for PKCS#5 PBKDF2 Function Validation. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
This=20 +program and the accompanying materials are licensed and made available=20 +under the terms and conditions of the BSD License which accompanies=20 +this distribution. The full text of the license may be found at=20 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,=20 +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + +**/ + +#include "Cryptest.h" + +// +// PBKDF2 HMAC-SHA1 Test Vector from RFC6070 //=20 +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *Password =3D "password"; // I= nput Password +GLOBAL_REMOVE_IF_UNREFERENCED UINTN PassLen =3D 8; // L= ength of Input Password +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *Salt =3D "salt"; // I= nput Salt +GLOBAL_REMOVE_IF_UNREFERENCED UINTN SaltLen =3D 4; // L= ength of Input Salt +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN Count =3D 2; // I= nterationCount +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN KeyLen =3D 20; // L= ength of derived key +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 DerivedKey[] =3D { // E= xpected output key + 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, 0xcd, 0x1e, 0xd9,=20 +0x2a, 0xce, 0x1d, 0x41, 0xf0, + 0xd8, 0xde, 0x89, 0x57 + }; + +/** + Validate UEFI-OpenSSL PKCS#5 PBKDF2 Interface. + + @retval EFI_SUCCESS Validation succeeded. + @retval EFI_ABORTED Validation failed. + +**/ +EFI_STATUS +ValidateCryptPkcs5Pbkdf2 ( + VOID + ) +{ + BOOLEAN Status; + UINT8 *OutKey; + + Print (L"\nUEFI-OpenSSL PKCS#5 PBKDF2 Testing: "); Print (L"\n-=20 + PKCS#5 PBKDF2 Verification: "); + + OutKey =3D AllocatePool (KeyLen); + if (OutKey =3D=3D NULL) { + Print (L"[Fail]"); + return EFI_ABORTED; + } + + // + // Verify PKCS#5 PBKDF2 Key Derivation Function // Print=20 + (L"Deriving Key... "); Status =3D Pkcs5HashPassword ( + PassLen, + Password, + SaltLen, + (CONST UINT8 *)Salt, + Count, + SHA1_DIGEST_SIZE, + KeyLen, + OutKey + ); + + if (!Status) { + Print (L"[Fail]"); + FreePool (OutKey); + return EFI_ABORTED; + } + + // + // Check the output key with the expected key result // Print=20 + (L"Check Derived Key... "); if (CompareMem (OutKey, DerivedKey,=20 + KeyLen) !=3D 0) { + Print (L"[Fail]"); + FreePool (OutKey); + return EFI_ABORTED; + } + + Print (L"[Pass]\n"); + + // + // Release Resources + // + FreePool (OutKey); + + return EFI_SUCCESS; +} diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/L= ibrary/BaseCryptLib.h index 9693793..67837ae 100644 --- a/CryptoPkg/Include/Library/BaseCryptLib.h +++ b/CryptoPkg/Include/Library/BaseCryptLib.h @@ -2211,6 +2211,46 @@ X509GetTBSCert ( ); =20 /** + Derives a key from a password using a salt and iteration count, based=20 + on PKCS#5 v2.0 password based encryption key derivation function PBKDF2,= as specified in RFC 2898. + + If Password or Salt or OutKey is NULL, then return FALSE. + If the hash algorithm could not be determined, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in] PasswordLength Length of input password in bytes. + @param[in] Password Pointer to the array for the password. + @param[in] SaltLength Size of the Salt in bytes. + @param[in] Salt Pointer to the Salt. + @param[in] IterationCount Number of iterations to perform. Its value s= hould be + greater than or equal to 1. + @param[in] DigestSize Size of the message digest to be used (eg. S= HA256_DIGEST_SIZE). + NOTE: DigestSize will be used to determine t= he hash algorithm. + Only SHA1_DIGEST_SIZE or SHA256_DIGEST= _SIZE is supported. + @param[in] KeyLength Size of the derived key buffer in bytes. + @param[out] OutKey Pointer to the output derived key buffer. + + @retval TRUE A key was derived successfully. + @retval FALSE One of the pointers was NULL or one of the sizes was too= large. + @retval FALSE The hash algorithm could not be determined from the dige= st size. + @retval FALSE The key derivation operation failed. + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +Pkcs5HashPassword ( + IN UINTN PasswordLength, + IN CONST CHAR8 *Password, + IN UINTN SaltLength, + IN CONST UINT8 *Salt, + IN UINTN IterationCount, + IN UINTN DigestSize, + IN UINTN KeyLength, + OUT UINT8 *OutKey + ); + +/** Get the signer's certificates from PKCS#7 signed data as described in "P= KCS #7: Cryptographic Message Syntax Standard". The input signed data could be w= rapped in a ContentInfo structure. diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Li= brary/BaseCryptLib/BaseCryptLib.inf index 31bb5fb..1a8c41f 100644 --- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf @@ -47,6 +47,7 @@ Cipher/CryptArc4.c Pk/CryptRsaBasic.c Pk/CryptRsaExt.c + Pk/CryptPkcs5Pbkdf2.c Pk/CryptPkcs7Sign.c Pk/CryptPkcs7Verify.c Pk/CryptDh.c diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Lib= rary/BaseCryptLib/PeiCryptLib.inf index 058737b..f56f90e 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -54,6 +54,7 @@ =20 Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs5Pbkdf2Null.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7Verify.c =20 diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c b/CryptoP= kg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c new file mode 100644 index 0000000..78c3a34 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c @@ -0,0 +1,101 @@ +/** @file + PBKDF2 Key Derivation Function Wrapper Implementation over OpenSSL. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
This=20 +program and the accompanying materials are licensed and made available=20 +under the terms and conditions of the BSD License which accompanies=20 +this distribution. The full text of the license may be found at=20 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,=20 +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + +**/ + +#include "InternalCryptLib.h" +#include +#include + +/** + Derives a key from a password using a salt and iteration count, based=20 +on PKCS#5 v2.0 + password based encryption key derivation function PBKDF2, as specified i= n RFC 2898. + + If Password or Salt or OutKey is NULL, then return FALSE. + If the hash algorithm could not be determined, then return FALSE. + + @param[in] PasswordLength Length of input password in bytes. + @param[in] Password Pointer to the array for the password. + @param[in] SaltLength Size of the Salt in bytes. + @param[in] Salt Pointer to the Salt. + @param[in] IterationCount Number of iterations to perform. Its value s= hould be + greater than or equal to 1. + @param[in] DigestSize Size of the message digest to be used (eg. S= HA256_DIGEST_SIZE). + NOTE: DigestSize will be used to determine t= he hash algorithm. + Only SHA1_DIGEST_SIZE or SHA256_DIGEST= _SIZE is supported. + @param[in] KeyLength Size of the derived key buffer in bytes. + @param[out] OutKey Pointer to the output derived key buffer. + + @retval TRUE A key was derived successfully. + @retval FALSE One of the pointers was NULL or one of the sizes was too= large. + @retval FALSE The hash algorithm could not be determined from the dige= st size. + @retval FALSE The key derivation operation failed. + +**/ +BOOLEAN +EFIAPI +Pkcs5HashPassword ( + IN UINTN PasswordLength, + IN CONST CHAR8 *Password, + IN UINTN SaltLength, + IN CONST UINT8 *Salt, + IN UINTN IterationCount, + IN UINTN DigestSize, + IN UINTN KeyLength, + OUT UINT8 *OutKey + ) +{ + CONST EVP_MD *HashAlg; + + HashAlg =3D NULL; + + // + // Parameter Checking. + // + if ((Password =3D=3D NULL) || (Salt =3D=3D NULL) || (OutKey =3D=3D NULL)= ) { + return FALSE; + } + if ((PasswordLength =3D=3D 0) || (PasswordLength > INT_MAX) || + (SaltLength =3D=3D 0) || (SaltLength > INT_MAX) || + (KeyLength =3D=3D 0) || (KeyLength > INT_MAX) || + (IterationCount < 1) || (IterationCount > INT_MAX)) { + return FALSE; + } + // + // Make sure the digest algorithm is supported. + // + switch (DigestSize) { + case SHA1_DIGEST_SIZE: + HashAlg =3D EVP_sha1(); + break; + case SHA256_DIGEST_SIZE: + HashAlg =3D EVP_sha256(); + break; + default: + return FALSE; + break; + } + + // + // Perform password-based key derivation routines. + // + return (BOOLEAN)PKCS5_PBKDF2_HMAC ( + (const char *)Password, + (int)PasswordLength, + (const unsigned char *)Salt, + (int)SaltLength, + (int)IterationCount, + HashAlg, + (int)KeyLength, + (unsigned char *)OutKey + ); +} diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c b/Cry= ptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c new file mode 100644 index 0000000..54d2637 --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c @@ -0,0 +1,56 @@ +/** @file + PBKDF2 Key Derivation Function Wrapper Implementation which does not=20 +provide real + capabilities. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
This=20 +program and the accompanying materials are licensed and made available=20 +under the terms and conditions of the BSD License which accompanies=20 +this distribution. The full text of the license may be found at=20 +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,=20 +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + +**/ + +#include "InternalCryptLib.h" +#include +#include + +/** + Derives a key from a password using a salt and iteration count, based=20 +on PKCS#5 v2.0 + password based encryption key derivation function PBKDF2, as specified i= n RFC 2898. + + Return FALSE to indicate this interface is not supported. + + @param[in] PasswordLength Length of input password in bytes. + @param[in] Password Pointer to the array for the password. + @param[in] SaltLength Size of the Salt in bytes. + @param[in] Salt Pointer to the Salt. + @param[in] IterationCount Number of iterations to perform. Its value s= hould be + greater than or equal to 1. + @param[in] DigestSize Size of the message digest to be used (eg. S= HA256_DIGEST_SIZE). + NOTE: DigestSize will be used to determine t= he hash algorithm. + Only SHA1_DIGEST_SIZE or SHA256_DIGEST= _SIZE is supported. + @param[in] KeyLength Size of the derived key buffer in bytes. + @param[out] OutKey Pointer to the output derived key buffer. + + @retval FALSE This interface is not supported. + +**/ +BOOLEAN +EFIAPI +Pkcs5HashPassword ( + IN UINTN PasswordLength, + IN CONST CHAR8 *Password, + IN UINTN SaltLength, + IN CONST UINT8 *Salt, + IN UINTN IterationCount, + IN UINTN DigestSize, + IN UINTN KeyLength, + OUT UINT8 *OutKey + ) +{ + ASSERT (FALSE); + return FALSE; +} diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg= /Library/BaseCryptLib/RuntimeCryptLib.inf index 12434cf..e6daade 100644 --- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf @@ -52,6 +52,7 @@ Cipher/CryptArc4Null.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs5Pbkdf2Null.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7Verify.c Pk/CryptDhNull.c diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Lib= rary/BaseCryptLib/SmmCryptLib.inf index 26d3e56..df44184 100644 --- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf @@ -52,6 +52,7 @@ Cipher/CryptArc4Null.c Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs5Pbkdf2Null.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7Verify.c Pk/CryptDhNull.c -- 2.10.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel