mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 11:13:53 +01:00 
			
		
		
		
	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 <ting.ye@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qin Long <qin.long@intel.com> Reviewed-by: Ting Ye <ting.ye@intel.com>
This commit is contained in:
		
							parent
							
								
									72009c626d
								
							
						
					
					
						commit
						a8f37449c7
					
				| @ -1,7 +1,7 @@ | ||||
| /** @file
 | ||||
|   Application for Cryptographic Primitives Validation. | ||||
| 
 | ||||
| Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> | ||||
| Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> | ||||
| 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 | ||||
| @ -63,6 +63,11 @@ CryptestMain ( | ||||
|     return Status; | ||||
|   } | ||||
| 
 | ||||
|   Status = ValidateCryptPkcs5Pbkdf2 (); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     return Status; | ||||
|   } | ||||
| 
 | ||||
|   Status = ValidateCryptPkcs7 (); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     return Status; | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| /** @file
 | ||||
|   Application for Cryptographic Primitives Validation. | ||||
| 
 | ||||
| Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> | ||||
| Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> | ||||
| 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 | ||||
| @ -84,6 +84,18 @@ ValidateCryptRsa2 ( | ||||
|   VOID | ||||
|   ); | ||||
| 
 | ||||
| /**
 | ||||
|   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. | ||||
| 
 | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| ## @file | ||||
| #  Shell application that will test the crypto library. | ||||
| # | ||||
| #  UEFI Application for the Validation of cryptography library (based on OpenSSL 0.9.8zb). | ||||
| #  UEFI Application for the Validation of cryptography library (based on OpenSSL-1.0.2j). | ||||
| # | ||||
| #  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> | ||||
| #  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> | ||||
| #  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 | ||||
| @ -37,6 +37,7 @@ | ||||
|   BlockCipherVerify.c | ||||
|   RsaVerify.c | ||||
|   RsaVerify2.c | ||||
|   Pkcs5Pbkdf2Verify.c | ||||
|   AuthenticodeVerify.c | ||||
|   TSVerify.c | ||||
|   DhVerify.c | ||||
|  | ||||
							
								
								
									
										94
									
								
								CryptoPkg/Application/Cryptest/Pkcs5Pbkdf2Verify.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								CryptoPkg/Application/Cryptest/Pkcs5Pbkdf2Verify.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| /** @file
 | ||||
|   Application for PKCS#5 PBKDF2 Function Validation. | ||||
| 
 | ||||
| Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> | ||||
| 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 "Cryptest.h" | ||||
| 
 | ||||
| //
 | ||||
| // PBKDF2 HMAC-SHA1 Test Vector from RFC6070
 | ||||
| //
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  *Password = "password";  // Input Password
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED UINTN        PassLen   = 8;           // Length of Input Password
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  *Salt     = "salt";      // Input Salt
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED UINTN        SaltLen   = 4;           // Length of Input Salt
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN  Count     = 2;           // InterationCount
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED CONST UINTN  KeyLen    = 20;          // Length of derived key
 | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  DerivedKey[]  = {        // Expected output key
 | ||||
|   0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, 0xcd, 0x1e, 0xd9, 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- PKCS#5 PBKDF2 Verification: "); | ||||
| 
 | ||||
|   OutKey = AllocatePool (KeyLen); | ||||
|   if (OutKey == NULL) { | ||||
|     Print (L"[Fail]"); | ||||
|     return EFI_ABORTED; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
|   // Verify PKCS#5 PBKDF2 Key Derivation Function
 | ||||
|   //
 | ||||
|   Print (L"Deriving Key... "); | ||||
|   Status = 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 (L"Check Derived Key... "); | ||||
|   if (CompareMem (OutKey, DerivedKey, KeyLen) != 0) { | ||||
|     Print (L"[Fail]"); | ||||
|     FreePool (OutKey); | ||||
|     return EFI_ABORTED; | ||||
|   } | ||||
| 
 | ||||
|   Print (L"[Pass]\n"); | ||||
| 
 | ||||
|   //
 | ||||
|   // Release Resources
 | ||||
|   //
 | ||||
|   FreePool (OutKey); | ||||
| 
 | ||||
|   return EFI_SUCCESS; | ||||
| } | ||||
| @ -2210,6 +2210,46 @@ X509GetTBSCert ( | ||||
|   OUT UINTN        *TBSCertSize | ||||
|   ); | ||||
| 
 | ||||
| /**
 | ||||
|   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. | ||||
|   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 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. | ||||
|   @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 "PKCS #7: | ||||
|   Cryptographic Message Syntax Standard". The input signed data could be wrapped | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -54,6 +54,7 @@ | ||||
| 
 | ||||
|   Pk/CryptRsaBasic.c | ||||
|   Pk/CryptRsaExtNull.c | ||||
|   Pk/CryptPkcs5Pbkdf2Null.c | ||||
|   Pk/CryptPkcs7SignNull.c | ||||
|   Pk/CryptPkcs7Verify.c | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										101
									
								
								CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | ||||
| /** @file
 | ||||
|   PBKDF2 Key Derivation Function Wrapper Implementation over OpenSSL. | ||||
| 
 | ||||
| Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> | ||||
| 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 <openssl/evp.h> | ||||
| #include <openssl/hmac.h> | ||||
| 
 | ||||
| /**
 | ||||
|   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 | ||||
|                     ); | ||||
| } | ||||
							
								
								
									
										56
									
								
								CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs5Pbkdf2Null.c
									
									
									
									
									
										Normal file
									
								
							| @ -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.<BR> | ||||
| 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 <openssl/evp.h> | ||||
| #include <openssl/hmac.h> | ||||
| 
 | ||||
| /**
 | ||||
|   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; | ||||
| } | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user