From a8f37449c7e355e6402e3876c9db9e11d875164f Mon Sep 17 00:00:00 2001 From: Qin Long Date: Tue, 1 Nov 2016 10:38:36 +0800 Subject: 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 test vector from RFC6070). Cc: Ting Ye Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qin Long Reviewed-by: Ting Ye --- 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 + 6 files changed, 161 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c create mode 100644 CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c (limited to 'CryptoPkg/Library') diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf index 31bb5fbe0a..1a8c41fd11 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/Library/BaseCryptLib/PeiCryptLib.inf index 058737b906..f56f90e26e 100644 --- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf +++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf @@ -54,6 +54,7 @@ Pk/CryptRsaBasic.c Pk/CryptRsaExtNull.c + Pk/CryptPkcs5Pbkdf2Null.c Pk/CryptPkcs7SignNull.c Pk/CryptPkcs7Verify.c diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c new file mode 100644 index 0000000000..78c3a34f52 --- /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 program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "InternalCryptLib.h" +#include +#include + +/** + Derives a key from a password using a salt and iteration count, based 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. + + @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 should be + greater than or equal to 1. + @param[in] DigestSize Size of the message digest to be used (eg. SHA256_DIGEST_SIZE). + NOTE: DigestSize will be used to determine the 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 digest 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 = NULL; + + // + // Parameter Checking. + // + if ((Password == NULL) || (Salt == NULL) || (OutKey == NULL)) { + return FALSE; + } + if ((PasswordLength == 0) || (PasswordLength > INT_MAX) || + (SaltLength == 0) || (SaltLength > INT_MAX) || + (KeyLength == 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 = EVP_sha1(); + break; + case SHA256_DIGEST_SIZE: + HashAlg = 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/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c new file mode 100644 index 0000000000..54d2637d6c --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c @@ -0,0 +1,56 @@ +/** @file + PBKDF2 Key Derivation Function Wrapper Implementation which does not provide real + capabilities. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "InternalCryptLib.h" +#include +#include + +/** + Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0 + password based encryption key derivation function PBKDF2, as specified in 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 should be + greater than or equal to 1. + @param[in] DigestSize Size of the message digest to be used (eg. SHA256_DIGEST_SIZE). + NOTE: DigestSize will be used to determine the 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 12434cfc8c..e6daadef9d 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/Library/BaseCryptLib/SmmCryptLib.inf index 26d3e568c2..df44184a2a 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 -- cgit v1.2.3