Update CryptoPkg for new ciphers (HMAC, Block Cipher, etc) supports.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10997 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/CryptoPkg/Application/Cryptest/AuthenticodeVerify.c b/CryptoPkg/Application/Cryptest/AuthenticodeVerify.c
index 72c4092..7a4e294 100644
--- a/CryptoPkg/Application/Cryptest/AuthenticodeVerify.c
+++ b/CryptoPkg/Application/Cryptest/AuthenticodeVerify.c
@@ -12,11 +12,7 @@
 

 **/

 

-#include <Library/BaseLib.h>

-#include <Library/BaseMemoryLib.h>

-#include <Library/MemoryAllocationLib.h>

-

-#include <Library/BaseCryptLib.h>

+#include "Cryptest.h"

 

 //

 // DER encoding of SpcIndirectDataContent (Authenticode-specific Structure)

@@ -656,3 +652,30 @@
 

   return Status;

 }

+

+/**

+  Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateAuthenticode (

+  VOID

+  )

+{

+  Print (L"\nUEFI-OpenSSL PKCS#7-Signed-Data Testing: ");

+

+  Print (L"\n- Authenticode (PKCS#7 Signed Data) Verification ... ");

+

+  if (AuthenticodeVerify ()) {

+    Print (L"[Pass]");

+  } else {

+    Print (L"[Fail]");

+  }   

+

+  Print (L"\n");

+

+  return EFI_SUCCESS;

+}

diff --git a/CryptoPkg/Application/Cryptest/BlockCipherVerify.c b/CryptoPkg/Application/Cryptest/BlockCipherVerify.c
new file mode 100644
index 0000000..de8f6ec
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/BlockCipherVerify.c
@@ -0,0 +1,473 @@
+/** @file  

+  Application for Block Cipher Primitives Validation.

+

+Copyright (c) 2010, 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"

+

+//

+// TDES test vectors are extracted from OpenSSL 0.9.8l, crypto\des\destest.c

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcbData[] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcbKey[] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcbCipher[] = {

+  0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7,

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcb2Cipher[] = {

+  0x92, 0x95, 0xB5, 0x9B, 0xB3, 0x84, 0x73, 0x6E,

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesCbcData[] = {

+  0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,

+  0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,

+  0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesCbcKey[] = {

+  0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 

+  0xf1, 0xe0, 0xd3, 0xc2, 0xb5, 0xa4, 0x97, 0x86,

+  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 TdesCbcIvec[] = {

+  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesCbc3Cipher[] = {

+  0x3F, 0xE3, 0x01, 0xC9, 0x62, 0xAC, 0x01, 0xD0,

+  0x22, 0x13, 0x76, 0x3C, 0x1C, 0xBD, 0x4C, 0xDC,

+  0x79, 0x96, 0x57, 0xC0, 0x64, 0xEC, 0xF5, 0xD4

+  };

+

+//

+// AES test vectors are from NIST KAT of AES

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128EcbData[] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128EcbKey[] = {

+  0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128EcbCipher[] = {

+  0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes192EcbData[] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes192EcbKey[] = {

+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes192EcbCipher[] = {

+  0xdd, 0x8a, 0x49, 0x35, 0x14, 0x23, 0x1c, 0xbf, 0x56, 0xec, 0xce, 0xe4, 0xc4, 0x08, 0x89, 0xfb

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes256EcbData[] = {

+  0x01, 0x47, 0x30, 0xf8, 0x0a, 0xc6, 0x25, 0xfe, 0x84, 0xf0, 0x26, 0xc6, 0x0b, 0xfd, 0x54, 0x7d

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes256EcbKey[] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes256EcbCipher[] = {

+  0x5c, 0x9d, 0x84, 0x4e, 0xd4, 0x6f, 0x98, 0x85, 0x08, 0x5e, 0x5d, 0x6a, 0x4f, 0x94, 0xc7, 0xd7

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcData[] = {

+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,

+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcKey[] = {

+  0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcIvec[] = {

+  0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcCipher[] = {

+  0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,

+  0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1

+  };

+

+//

+// ARC4 Test Vector defined in "Appendix A.1 Test Vectors from [CRYPTLIB]" of

+// IETF Draft draft-kaukonen-cipher-arcfour-03 ("A Stream Cipher Encryption Algorithm 'Arcfour'").

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Arc4Data[] = {

+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Arc4Key[] = {

+  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF

+  };

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Arc4Cipher[] = {

+  0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79

+  };

+

+/**

+  Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptBlockCipher (

+  VOID

+  )

+{

+  UINTN    CtxSize;

+  VOID     *CipherCtx;

+  UINT8    Encrypt[256];

+  UINT8    Decrypt[256];

+  BOOLEAN  Status;

+

+  Print (L"\nUEFI-OpenSSL Block Cipher Engine Testing: ");

+

+  CtxSize   = TdesGetContextSize ();

+  CipherCtx = AllocatePool (CtxSize);

+

+  Print (L"\n- TDES Validation: ");

+

+

+  Print (L"ECB... ");

+

+  //

+  // TDES ECB Validation

+  //

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = TdesInit (CipherCtx, TdesEcbKey, 64);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = TdesEcbEncrypt (CipherCtx, TdesEcbData, 8, Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = TdesEcbDecrypt (CipherCtx, Encrypt, 8, Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, TdesEcbCipher, 8) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Decrypt, TdesEcbData, 8) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"EDE2 ECB... ");

+

+  //

+  // TDES EDE2 ECB Validation

+  //

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = TdesInit (CipherCtx, TdesEcbKey, 128);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = TdesEcbEncrypt (CipherCtx, TdesEcbData, 8, Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = TdesEcbDecrypt (CipherCtx, Encrypt, 8, Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, TdesEcb2Cipher, 8) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  } 

+

+  if (CompareMem (Decrypt, TdesEcbData, 8) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"EDE3 CBC... ");

+

+  //

+  // TDES EDE3 CBC Validation

+  //

+  ZeroMem (Encrypt, 256);

+  ZeroMem (Decrypt, 256);

+

+  Status = TdesInit (CipherCtx, TdesCbcKey, 192);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = TdesCbcEncrypt (CipherCtx, TdesCbcData, sizeof (TdesCbcData), TdesCbcIvec, Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = TdesCbcDecrypt (CipherCtx, Encrypt, sizeof (TdesCbcData), TdesCbcIvec, Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, TdesCbc3Cipher, sizeof (TdesCbc3Cipher)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Decrypt, TdesCbcData, sizeof (TdesCbcData)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]");

+

+  FreePool (CipherCtx);

+

+  CtxSize   = AesGetContextSize ();

+  CipherCtx = AllocatePool (CtxSize);

+  

+  Print (L"\n- AES Validation:  ");

+

+  Print (L"ECB-128... ");

+

+  //

+  // AES-128 ECB Validation

+  //

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = AesInit (CipherCtx, Aes128EcbKey, 128);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesEcbEncrypt (CipherCtx, Aes128EcbData, sizeof (Aes128EcbData), Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesEcbDecrypt (CipherCtx, Encrypt, sizeof (Aes128EcbData), Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, Aes128EcbCipher, sizeof (Aes128EcbCipher)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  } 

+

+  if (CompareMem (Decrypt, Aes128EcbData, sizeof (Aes128EcbData)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"ECB-192... ");

+

+  //

+  // AES-192 ECB Validation

+  //

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = AesInit (CipherCtx, Aes192EcbKey, 192);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesEcbEncrypt (CipherCtx, Aes192EcbData, sizeof (Aes192EcbData), Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesEcbDecrypt (CipherCtx, Encrypt, sizeof (Aes192EcbData), Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, Aes192EcbCipher, sizeof (Aes192EcbCipher)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Decrypt, Aes192EcbData, sizeof (Aes192EcbData)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"ECB-256... ");

+

+  //

+  // AES-256 ECB Validation

+  //

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = AesInit (CipherCtx, Aes256EcbKey, 256);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesEcbEncrypt (CipherCtx, Aes256EcbData, sizeof (Aes256EcbData), Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesEcbDecrypt (CipherCtx, Encrypt, sizeof (Aes256EcbData), Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, Aes256EcbCipher, sizeof (Aes256EcbCipher)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Decrypt, Aes256EcbData, sizeof (Aes256EcbData)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"CBC-128... ");

+

+  //

+  // AES-128 CBC Validation

+  //

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = AesInit (CipherCtx, Aes128CbcKey, 128);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesCbcEncrypt (CipherCtx, Aes128CbcData, sizeof (Aes128CbcData), Aes128CbcIvec, Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = AesCbcDecrypt (CipherCtx, Encrypt, sizeof (Aes128CbcData), Aes128CbcIvec, Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, Aes128CbcCipher, sizeof (Aes128CbcCipher)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Decrypt, Aes128CbcData, sizeof (Aes128CbcData)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]");

+

+  Print (L"\n- ARC4 Validation: ");

+

+  //

+  // ARC4 Validation

+  //

+  CtxSize   = Arc4GetContextSize ();

+  CipherCtx = AllocatePool (CtxSize);

+

+  ZeroMem (Encrypt, sizeof (Encrypt));

+  ZeroMem (Decrypt, sizeof (Decrypt));

+

+  Status = Arc4Init (CipherCtx, Arc4Key, sizeof (Arc4Key));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = Arc4Encrypt (CipherCtx, Arc4Data, sizeof (Arc4Data), Encrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = Arc4Reset (CipherCtx);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = Arc4Decrypt (CipherCtx, Encrypt, sizeof (Arc4Data), Decrypt);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Encrypt, Arc4Cipher, sizeof (Arc4Cipher)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Decrypt, Arc4Data, sizeof (Arc4Data)) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]");

+

+  Print (L"\n");

+

+  return EFI_SUCCESS;

+}

diff --git a/CryptoPkg/Application/Cryptest/Cryptest.c b/CryptoPkg/Application/Cryptest/Cryptest.c
index 6afe299..188a36c 100644
--- a/CryptoPkg/Application/Cryptest/Cryptest.c
+++ b/CryptoPkg/Application/Cryptest/Cryptest.c
@@ -12,332 +12,7 @@
 

 **/

 

-#include <Uefi.h>

-#include <Library/BaseLib.h>

-#include <Library/BaseMemoryLib.h>

-#include <Library/MemoryAllocationLib.h>

-#include <Library/UefiLib.h>

-#include <Library/UefiApplicationEntryPoint.h>

-#include <Library/DebugLib.h>

-

-#include <Library/BaseCryptLib.h>

-

-//

-// Max Known Digest Size is SHA512 Output (64 bytes) by far

-//

-#define MAX_DIGEST_SIZE    64

-

-//

-// Message string for digest validation

-//

-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HashData = "abc";

-

-//

-// Result for MD5("abc"). (From "A.5 Test suite" of IETF RFC1321)

-//

-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Md5Digest[MD5_DIGEST_SIZE] = {

-  0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72

-  };

-

-//

-// Result for SHA-1("abc"). (From "A.1 SHA-1 Example" of NIST FIPS 180-2)

-//

-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha1Digest[SHA1_DIGEST_SIZE] = {

-  0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,

-  0x9c, 0xd0, 0xd8, 0x9d

-  };

-

-//

-// Result for SHA-256("abc"). (From "B.1 SHA-256 Example" of NIST FIPS 180-2)

-//

-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha256Digest[SHA256_DIGEST_SIZE] = {

-  0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,

-  0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad

-  };

-

-//

-// RSA PKCS#1 Validation Data from OpenSSL "Fips_rsa_selftest.c"

-//

-

-// Public Modulus of RSA Key

-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaN[] = {

-  0xBB, 0xF8, 0x2F, 0x09, 0x06, 0x82, 0xCE, 0x9C, 0x23, 0x38, 0xAC, 0x2B, 0x9D, 0xA8, 0x71, 0xF7, 

-  0x36, 0x8D, 0x07, 0xEE, 0xD4, 0x10, 0x43, 0xA4, 0x40, 0xD6, 0xB6, 0xF0, 0x74, 0x54, 0xF5, 0x1F,

-  0xB8, 0xDF, 0xBA, 0xAF, 0x03, 0x5C, 0x02, 0xAB, 0x61, 0xEA, 0x48, 0xCE, 0xEB, 0x6F, 0xCD, 0x48,

-  0x76, 0xED, 0x52, 0x0D, 0x60, 0xE1, 0xEC, 0x46, 0x19, 0x71, 0x9D, 0x8A, 0x5B, 0x8B, 0x80, 0x7F,

-  0xAF, 0xB8, 0xE0, 0xA3, 0xDF, 0xC7, 0x37, 0x72, 0x3E, 0xE6, 0xB4, 0xB7, 0xD9, 0x3A, 0x25, 0x84,

-  0xEE, 0x6A, 0x64, 0x9D, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xB2, 0x45, 0x45, 0x98, 0x39, 0x4E,

-  0xE0, 0xAA, 0xB1, 0x2D, 0x7B, 0x61, 0xA5, 0x1F, 0x52, 0x7A, 0x9A, 0x41, 0xF6, 0xC1, 0x68, 0x7F,

-  0xE2, 0x53, 0x72, 0x98, 0xCA, 0x2A, 0x8F, 0x59, 0x46, 0xF8, 0xE5, 0xFD, 0x09, 0x1D, 0xBD, 0xCB

-  };

-

-// Public Exponent of RSA Key

-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaE[] = { 0x11 };

-

-// Known Answer Test (KAT) Data for RSA PKCS#1 Signing

-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 RsaSignData[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";

-

-// Known Signature for the above message, under SHA-1 Digest

-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaPkcs1Signature[] = {

-  0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, 0x4A, 0xFD, 0x1A, 0x05,

-  0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51,

-  0x55, 0x77, 0x90, 0xCF, 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,

-  0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, 0x20, 0x22, 0xBE, 0x59,

-  0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF,

-  0x4E, 0xCA, 0x2E, 0x4E, 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,

-  0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, 0x72, 0x05, 0xDE, 0xE6,

-  0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4

-  };

-

-/**

-  Validate MSFT Authenticode using PKCS#7 Verification Interfaces.

-

-  @return  EFI_SUCCESS  Validation succeeds. 

-

-**/

-BOOLEAN

-AuthenticodeVerify (

-  VOID

-  );

-

-/**

-  Validate UEFI-OpenSSL Digest Interfaces.

-

-  @return  EFI_SUCCESS  Validation succeeded.

-

-**/

-EFI_STATUS

-ValidateCryptDigest (

-  VOID

-  )

-{

-  UINTN    CtxSize;

-  VOID     *HashCtx;

-  UINTN    DataSize;

-  UINT8    Digest[MAX_DIGEST_SIZE];

-  UINTN    Index;

-  BOOLEAN  Status;

-

-  Print (L" UEFI-OpenSSL Hash Engine Testing (Hashing(\"abc\")): ");

-  DataSize = AsciiStrLen (HashData);

-

-  //

-  // MD5 Digest Validation

-  //

-  ZeroMem (Digest, MAX_DIGEST_SIZE);

-  CtxSize = Md5GetContextSize ();

-  HashCtx = AllocatePool (CtxSize);

-  Status  = Md5Init (HashCtx);

-  Status  = Md5Update (HashCtx, HashData, DataSize);

-  Status  = Md5Final (HashCtx, Digest);

-  FreePool (HashCtx);

-  Print (L"\n   - MD5 Digest: \n     = 0x");

-  for (Index = 0; Index < MD5_DIGEST_SIZE; Index++) {

-    Print (L"%02x", Digest[Index]);

-  }

-  if (CompareMem (Digest, Md5Digest, MD5_DIGEST_SIZE) == 0) {

-    Print (L" [Pass]");

-  } else {

-    Print (L" [Failed]");

-  }

-

-  //

-  // SHA-1 Digest Validation

-  //

-  ZeroMem (Digest, MAX_DIGEST_SIZE);

-  CtxSize = Sha1GetContextSize ();

-  HashCtx = AllocatePool (CtxSize);

-  Status  = Sha1Init (HashCtx);

-  Status  = Sha1Update (HashCtx, HashData, DataSize);

-  Status  = Sha1Final (HashCtx, Digest);

-  FreePool (HashCtx);

-  Print (L"\n   - SHA-1 Digest: \n     = 0x");

-  for (Index = 0; Index < SHA1_DIGEST_SIZE; Index++) {

-    Print (L"%02x", Digest[Index]);

-  }

-  if (CompareMem (Digest, Sha1Digest, SHA1_DIGEST_SIZE) == 0) {

-    Print (L" [Pass]");

-  } else {

-    Print (L" [Failed]");

-  }

-

-  //

-  // SHA256 Digest Validation

-  //

-  ZeroMem (Digest, MAX_DIGEST_SIZE);

-  CtxSize = Sha256GetContextSize ();

-  HashCtx = AllocatePool (CtxSize);

-  Status  = Sha256Init (HashCtx);

-  Status  = Sha256Update (HashCtx, HashData, DataSize);

-  Status  = Sha256Final (HashCtx, Digest);

-  FreePool (HashCtx);

-  Print (L"\n   - SHA-256 Digest: \n     = 0x");

-  for (Index = 0; Index < SHA256_DIGEST_SIZE; Index++) {

-    Print (L"%02x", Digest[Index]);

-  }

-  if (CompareMem (Digest, Sha256Digest, SHA256_DIGEST_SIZE) == 0) {

-    Print (L" [Pass]");

-  } else {

-    Print (L" [Failed]");

-  }  

-

-  Print (L"\n");

-  

-  return EFI_SUCCESS;

-}

-

-

-/**

-  Validate UEFI-OpenSSL Message Authentication Codes Interfaces.

-

-  @return  EFI_SUCCESS  Validation succeeded. 

-

-**/

-EFI_STATUS

-ValidateCryptHmac (

-  VOID

-  )

-{

-  Print (L"\n UEFI-OpenSSL HMAC Engine Testing: ");

-  Print (L"\n   ==> No HMAC Support in Base Crypto Library!\n");

-

-  return EFI_SUCCESS;

-}

-

-

-/**

-  Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.

-

-  @return  EFI_SUCCESS  Validation succeeded.

-

-**/

-EFI_STATUS

-ValidateCryptBlockCipher (

-  VOID

-  )

-{

-  Print (L"\n UEFI-OpenSSL Block Cipher Engine Testing: ");

-  Print (L"\n   ==> No Block Cipher Support in Base Crypto Library!\n");

-

-  return EFI_SUCCESS;

-}

-

-

-/**

-  Validate UEFI-OpenSSL RSA Interfaces.

-

-  @return  EFI_SUCCESS  Validation succeeded.

-

-**/

-EFI_STATUS

-ValidateCryptRsa (

-  VOID

-  )

-{

-  VOID     *Rsa;

-  UINT8    mHash[SHA1_DIGEST_SIZE];

-  UINTN    HashSize;

-  UINTN    CtxSize;

-  VOID     *Sha1Ctx;

-  UINT8    *Signature;

-  UINTN    SigSize;

-  BOOLEAN  Status;

-

-  Print (L"\n UEFI-OpenSSL RSA Engine Testing: ");

-

-  //

-  // Generate & Initialize RSA Context

-  //

-  Rsa = RsaNew ();

-  Print (L"\n   - Generate RSA Context .............. ");

-  if (Rsa != NULL) {

-    Print (L"[Pass]");

-  } else {

-    Print (L"[Failed]");

-  }

-

-  //

-  // Set RSA Key Components

-  // NOTE: Only N and E are needed to be set as RSA public key for signature verification

-  //

-  Print (L"\n   - Set RSA Key Components ............ ");

-  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));

-  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));

-  if (Status) {

-    Print (L"[Pass]");

-  } else {

-    Print (L"[Failed]");

-  }

-

-  //

-  // SHA-1 Digest Message for PKCS#1 Signature 

-  //

-  Print (L"\n   - Hash Original Message ............. ");

-  HashSize = SHA1_DIGEST_SIZE;

-  ZeroMem (mHash, HashSize);

-  CtxSize = Sha1GetContextSize ();

-  Sha1Ctx = AllocatePool (CtxSize);

-  Status  = Sha1Init (Sha1Ctx);

-  Status  = Sha1Update (Sha1Ctx, RsaSignData, AsciiStrLen (RsaSignData));

-  Status  = Sha1Final (Sha1Ctx, mHash);

-  FreePool (Sha1Ctx);

-  if (Status) {

-    Print (L"[Pass]");

-  } else {

-    Print (L"[Failed]");

-  }

-

-  //

-  // Verify RSA PKCS#1-encoded Signature

-  //

-  Print (L"\n   - PKCS#1 Signature Verification ..... ");

-  SigSize   = sizeof (RsaPkcs1Signature);

-  Signature = (UINT8 *)AllocatePool (SigSize);

-  CopyMem (Signature, RsaPkcs1Signature, SigSize);

-  Status = RsaPkcs1Verify (Rsa, mHash, HashSize, Signature, SigSize);

-  if (Status) {

-    Print (L"[Pass]");

-  } else {

-    Print (L"[Failed]");

-  }   

-

-  //

-  // Release Resources

-  //

-  RsaFree (Rsa);

-  Print (L"\n   - Release RSA Context ............... [Pass]");

-

-  Print (L"\n");

-

-  return EFI_SUCCESS;

-}

-

-/**

-  Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.

-

-  @return  EFI_SUCCESS  Validation succeeded.

-

-**/

-EFI_STATUS

-ValidateAuthenticode (

-  VOID

-  )

-{

-  Print (L"\n UEFI-OpenSSL PKCS#7-Signed-Data Testing: ");

-

-  Print (L"\n   - Authenticode (PKCS#7 Signed Data) Verification ... ");

-

-  if (AuthenticodeVerify ()) {

-    Print (L"[Pass]");

-  } else {

-    Print (L"[Failed]");

-  }   

-

-  Print (L"\n");

-

-  return EFI_SUCCESS;

-}

-

+#include "Cryptest.h"

 

 /**

   Entry Point of Cryptographic Validation Utility.

@@ -361,12 +36,42 @@
   Print (L"\nUEFI-OpenSSL Wrapper Cryptosystem Testing: \n");

   Print (L"-------------------------------------------- \n");

 

-  Status = EFI_SUCCESS;

-  Status = ValidateCryptDigest ();

-  Status = ValidateCryptHmac ();

-  Status = ValidateCryptBlockCipher ();

-  Status = ValidateCryptRsa ();

-  Status = ValidateAuthenticode ();

+  RandomSeed (NULL, 0);

 

-  return Status;

+  Status = ValidateCryptDigest ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ValidateCryptHmac ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ValidateCryptBlockCipher ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ValidateCryptRsa ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ValidateAuthenticode ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ValidateCryptDh ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  Status = ValidateCryptPrng ();

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  return EFI_SUCCESS;

 }

diff --git a/CryptoPkg/Application/Cryptest/Cryptest.h b/CryptoPkg/Application/Cryptest/Cryptest.h
new file mode 100644
index 0000000..b631285
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/Cryptest.h
@@ -0,0 +1,111 @@
+/** @file  

+  Application for Cryptographic Primitives Validation.

+

+Copyright (c) 2009 - 2010, 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.

+

+**/

+

+#ifndef __CRYPTEST_H__

+#define __CRYPTEST_H__

+

+#include <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiLib.h>

+#include <Library/UefiApplicationEntryPoint.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseCryptLib.h>

+

+/**

+  Validate UEFI-OpenSSL Digest Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptDigest (

+  VOID

+  );

+

+/**

+  Validate UEFI-OpenSSL Message Authentication Codes Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptHmac (

+  VOID

+  );

+

+/**

+  Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptBlockCipher (

+  VOID

+  );

+

+/**

+  Validate UEFI-OpenSSL RSA Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptRsa (

+  VOID

+  );

+

+/**

+  Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateAuthenticode (

+  VOID

+  );

+

+/**

+  Validate UEFI-OpenSSL DH Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptDh (

+  VOID

+  );

+

+/**

+  Validate UEFI-OpenSSL pseudorandom number generator interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptPrng (

+  VOID

+  );

+

+#endif

diff --git a/CryptoPkg/Application/Cryptest/Cryptest.inf b/CryptoPkg/Application/Cryptest/Cryptest.inf
index 8517294..0e61760 100644
--- a/CryptoPkg/Application/Cryptest/Cryptest.inf
+++ b/CryptoPkg/Application/Cryptest/Cryptest.inf
@@ -29,9 +29,16 @@
 #

 

 [Sources]

+  Cryptest.h

   Cryptest.c

+  HashVerify.c

+  HmacVerify.c

+  BlockCipherVerify.c

+  RsaVerify.c

   AuthenticodeVerify.c

-

+  DhVerify.c

+  RandVerify.c

+  

 [Packages]

   MdePkg/MdePkg.dec

   CryptoPkg/CryptoPkg.dec

diff --git a/CryptoPkg/Application/Cryptest/DhVerify.c b/CryptoPkg/Application/Cryptest/DhVerify.c
new file mode 100644
index 0000000..455d85b
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/DhVerify.c
@@ -0,0 +1,117 @@
+/** @file  

+  Application for Diffie-Hellman Primitives Validation.

+

+Copyright (c) 2010, 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"

+

+/**

+  Validate UEFI-OpenSSL DH Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptDh (

+  VOID

+  )

+{

+  VOID    *Dh1;

+  VOID    *Dh2;

+  UINT8   Prime[64];

+  UINT8   PublicKey1[64];

+  UINTN   PublicKey1Length;

+  UINT8   PublicKey2[64];

+  UINTN   PublicKey2Length;

+  UINT8   Key1[64];

+  UINTN   Key1Length;

+  UINT8   Key2[64];

+  UINTN   Key2Length;

+  BOOLEAN Status;

+

+  Print (L"\nUEFI-OpenSSL DH Engine Testing:\n");

+

+  //

+  // Generate & Initialize DH Context

+  //

+  Print (L"- Context1 ... ");

+  Dh1 = DhNew ();

+  if (Dh1 == NULL) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Context2 ... ");

+  Dh2 = DhNew ();

+  if (Dh2 == NULL) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Parameter1 ... ");

+  Status = DhGenerateParameter (Dh1, 2, 64, Prime);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Parameter2 ... ");

+  Status = DhSetParameter (Dh2, 2, 64, Prime);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Generate key1 ... ");

+  Status = DhGenerateKey (Dh1, PublicKey1, &PublicKey1Length);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Generate key2 ... ");

+  Status = DhGenerateKey (Dh2, PublicKey2, &PublicKey2Length);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Compute key1 ... ");

+  Status = DhComputeKey (Dh1, PublicKey2, PublicKey2Length, Key1, &Key1Length);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Compute key2 ... ");

+  Status = DhComputeKey (Dh2, PublicKey1, PublicKey1Length, Key2, &Key2Length);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Compare Keys ... ");

+  if (Key1Length != Key2Length) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Key1, Key2, Key1Length) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]\n");

+

+  return EFI_SUCCESS;

+}

diff --git a/CryptoPkg/Application/Cryptest/HashVerify.c b/CryptoPkg/Application/Cryptest/HashVerify.c
new file mode 100644
index 0000000..1b21896
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/HashVerify.c
@@ -0,0 +1,192 @@
+/** @file  

+  Application for Hash Primitives Validation.

+

+Copyright (c) 2010, 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"

+

+//

+// Max Known Digest Size is SHA512 Output (64 bytes) by far

+//

+#define MAX_DIGEST_SIZE    64

+

+//

+// Message string for digest validation

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HashData = "abc";

+

+//

+// Result for MD5("abc"). (From "A.5 Test suite" of IETF RFC1321)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Md5Digest[MD5_DIGEST_SIZE] = {

+  0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72

+  };

+

+//

+// Result for SHA-1("abc"). (From "A.1 SHA-1 Example" of NIST FIPS 180-2)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha1Digest[SHA1_DIGEST_SIZE] = {

+  0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,

+  0x9c, 0xd0, 0xd8, 0x9d

+  };

+

+//

+// Result for SHA-256("abc"). (From "B.1 SHA-256 Example" of NIST FIPS 180-2)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha256Digest[SHA256_DIGEST_SIZE] = {

+  0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,

+  0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad

+  };

+

+/**

+  Validate UEFI-OpenSSL Digest Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptDigest (

+  VOID

+  )

+{

+  UINTN    CtxSize;

+  VOID     *HashCtx;

+  UINTN    DataSize;

+  UINT8    Digest[MAX_DIGEST_SIZE];

+  BOOLEAN  Status;

+

+  Print (L" UEFI-OpenSSL Hash Engine Testing:\n");

+  DataSize = AsciiStrLen (HashData);

+

+  Print (L"- MD5:    ");

+

+  //

+  // MD5 Digest Validation

+  //

+  ZeroMem (Digest, MAX_DIGEST_SIZE);

+  CtxSize = Md5GetContextSize ();

+  HashCtx = AllocatePool (CtxSize);

+

+  Print (L"Init... ");

+  Status  = Md5Init (HashCtx);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Update... ");

+  Status  = Md5Update (HashCtx, HashData, DataSize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Finalize... ");

+  Status  = Md5Final (HashCtx, Digest);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (HashCtx);

+

+  Print (L"Check Value... ");

+  if (CompareMem (Digest, Md5Digest, MD5_DIGEST_SIZE) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]\n");

+

+  Print (L"- SHA1:   ");

+

+  //

+  // SHA-1 Digest Validation

+  //

+  ZeroMem (Digest, MAX_DIGEST_SIZE);

+  CtxSize = Sha1GetContextSize ();

+  HashCtx = AllocatePool (CtxSize);

+

+  Print (L"Init... ");

+  Status  = Sha1Init (HashCtx);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Update... ");

+  Status  = Sha1Update (HashCtx, HashData, DataSize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Finalize... ");

+  Status  = Sha1Final (HashCtx, Digest);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (HashCtx);

+

+  Print (L"Check Value... ");

+  if (CompareMem (Digest, Sha1Digest, SHA1_DIGEST_SIZE) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]\n");

+

+  Print (L"- SHA256: ");

+

+  //

+  // SHA256 Digest Validation

+  //

+  ZeroMem (Digest, MAX_DIGEST_SIZE);

+  CtxSize = Sha256GetContextSize ();

+  HashCtx = AllocatePool (CtxSize);

+

+  Print (L"Init... ");

+  Status  = Sha256Init (HashCtx);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Update... ");

+  Status  = Sha256Update (HashCtx, HashData, DataSize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Finalize... ");

+  Status  = Sha256Final (HashCtx, Digest);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (HashCtx);

+

+  Print (L"Check Value... ");

+  if (CompareMem (Digest, Sha256Digest, SHA256_DIGEST_SIZE) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]\n");

+  

+  return EFI_SUCCESS;

+}

diff --git a/CryptoPkg/Application/Cryptest/HmacVerify.c b/CryptoPkg/Application/Cryptest/HmacVerify.c
new file mode 100644
index 0000000..73b38f3
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/HmacVerify.c
@@ -0,0 +1,157 @@
+/** @file  

+  Application for HMAC Primitives Validation.

+

+Copyright (c) 2010, 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"

+

+//

+// Max Known Digest Size is SHA512 Output (64 bytes) by far

+//

+#define MAX_DIGEST_SIZE    64

+

+//

+// Data string for HMAC validation

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HmacData = "Hi There";

+

+//

+// Key value for HMAC-MD5 validation. (From "2. Test Cases for HMAC-MD5" of IETF RFC2202)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacMd5Key[16] = {

+  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b

+  };

+

+//

+// Result for HMAC-MD5("Hi There"). (From "2. Test Cases for HMAC-MD5" of IETF RFC2202)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacMd5Digest[] = {

+  0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d

+  };

+

+//

+// Key value for HMAC-SHA-1 validation. (From "3. Test Cases for HMAC-SHA-1" of IETF RFC2202)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacSha1Key[20] = {

+  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,

+  0x0b, 0x0b, 0x0b, 0x0b

+  };

+

+//

+// Result for HMAC-SHA-1 ("Hi There"). (From "3. Test Cases for HMAC-SHA-1" of IETF RFC2202)

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacSha1Digest[] = {

+  0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,

+  0xf1, 0x46, 0xbe, 0x00

+  };

+

+/**

+  Validate UEFI-OpenSSL Message Authentication Codes Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptHmac (

+  VOID

+  )

+{

+  UINTN    CtxSize;

+  VOID     *HmacCtx;

+  UINT8    Digest[MAX_DIGEST_SIZE];

+  BOOLEAN  Status;

+

+  Print (L" \nUEFI-OpenSSL HMAC Engine Testing:\n");

+

+  Print (L"- HMAC-MD5:  ");

+

+  //

+  // HMAC-MD5 Digest Validation

+  //

+  ZeroMem (Digest, MAX_DIGEST_SIZE);

+  CtxSize = HmacMd5GetContextSize ();

+  HmacCtx = AllocatePool (CtxSize);

+

+  Print (L"Init... ");

+  Status  = HmacMd5Init (HmacCtx, HmacMd5Key, sizeof (HmacMd5Key));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Update... ");

+  Status  = HmacMd5Update (HmacCtx, HmacData, 8);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Finalize... ");

+  Status  = HmacMd5Final (HmacCtx, Digest);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (HmacCtx);

+

+  Print (L"Check Value... ");

+  if (CompareMem (Digest, HmacMd5Digest, MD5_DIGEST_SIZE) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]\n");

+

+  Print (L"- HMAC-SHA1: ");

+

+  //

+  // HMAC-SHA1 Digest Validation

+  //

+  ZeroMem (Digest, MAX_DIGEST_SIZE);

+  CtxSize = HmacSha1GetContextSize ();

+  HmacCtx = AllocatePool (CtxSize);

+

+  Print (L"Init... ");

+  Status  = HmacSha1Init (HmacCtx, HmacSha1Key, sizeof (HmacSha1Key));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Update... ");

+  Status  = HmacSha1Update (HmacCtx, HmacData, 8);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"Finalize... ");

+  Status  = HmacSha1Final (HmacCtx, Digest);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (HmacCtx);

+

+  Print (L"Check Value... ");

+  if (CompareMem (Digest, HmacSha1Digest, SHA1_DIGEST_SIZE) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Print (L"[Pass]\n");

+

+  return EFI_SUCCESS;

+}

diff --git a/CryptoPkg/Application/Cryptest/RandVerify.c b/CryptoPkg/Application/Cryptest/RandVerify.c
new file mode 100644
index 0000000..c9e7341
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/RandVerify.c
@@ -0,0 +1,69 @@
+/** @file  

+  Application for Pseudorandom Number Generator Validation.

+

+Copyright (c) 2010, 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"

+

+#define  RANDOM_NUMBER_SIZE  256

+

+CONST  UINT8  SeedString[] = "This is the random seed for PRNG verification.";

+

+UINT8  PreviousRandomBuffer[RANDOM_NUMBER_SIZE] = { 0x0 };

+

+UINT8  RandomBuffer[RANDOM_NUMBER_SIZE] = { 0x0 };

+

+/**

+  Validate UEFI-OpenSSL pseudorandom number generator interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptPrng (

+  VOID

+  )

+{

+  UINTN    Index;

+  BOOLEAN  Status;

+

+  Print (L" \nUEFI-OpenSSL PRNG Engine Testing:\n");

+

+  Print (L"- Random Generation...");

+

+  Status = RandomSeed (SeedString, sizeof (SeedString));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  for (Index = 0; Index < 10; Index ++) {

+    Status = RandomBytes (RandomBuffer, RANDOM_NUMBER_SIZE);

+    if (!Status) {

+      Print (L"[Fail]");

+      return EFI_ABORTED;

+    }

+

+    if (CompareMem (PreviousRandomBuffer, RandomBuffer, RANDOM_NUMBER_SIZE) == 0) {

+      Print (L"[Fail]");

+      return EFI_ABORTED;

+    }

+

+    CopyMem (PreviousRandomBuffer, RandomBuffer, RANDOM_NUMBER_SIZE);

+  }

+

+  Print (L"[Pass]\n");

+

+  return EFI_SUCCESS;

+

+}

diff --git a/CryptoPkg/Application/Cryptest/RsaVerify.c b/CryptoPkg/Application/Cryptest/RsaVerify.c
new file mode 100644
index 0000000..bbcad68
--- /dev/null
+++ b/CryptoPkg/Application/Cryptest/RsaVerify.c
@@ -0,0 +1,406 @@
+/** @file  

+  Application for RSA Primitives Validation.

+

+Copyright (c) 2010, 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"

+

+#define  RSA_MODULUS_LENGTH  512

+

+//

+// RSA PKCS#1 Validation Data from OpenSSL "Fips_rsa_selftest.c"

+//

+

+//

+// Public Modulus of RSA Key

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaN[] = {

+  0xBB, 0xF8, 0x2F, 0x09, 0x06, 0x82, 0xCE, 0x9C, 0x23, 0x38, 0xAC, 0x2B, 0x9D, 0xA8, 0x71, 0xF7, 

+  0x36, 0x8D, 0x07, 0xEE, 0xD4, 0x10, 0x43, 0xA4, 0x40, 0xD6, 0xB6, 0xF0, 0x74, 0x54, 0xF5, 0x1F,

+  0xB8, 0xDF, 0xBA, 0xAF, 0x03, 0x5C, 0x02, 0xAB, 0x61, 0xEA, 0x48, 0xCE, 0xEB, 0x6F, 0xCD, 0x48,

+  0x76, 0xED, 0x52, 0x0D, 0x60, 0xE1, 0xEC, 0x46, 0x19, 0x71, 0x9D, 0x8A, 0x5B, 0x8B, 0x80, 0x7F,

+  0xAF, 0xB8, 0xE0, 0xA3, 0xDF, 0xC7, 0x37, 0x72, 0x3E, 0xE6, 0xB4, 0xB7, 0xD9, 0x3A, 0x25, 0x84,

+  0xEE, 0x6A, 0x64, 0x9D, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xB2, 0x45, 0x45, 0x98, 0x39, 0x4E,

+  0xE0, 0xAA, 0xB1, 0x2D, 0x7B, 0x61, 0xA5, 0x1F, 0x52, 0x7A, 0x9A, 0x41, 0xF6, 0xC1, 0x68, 0x7F,

+  0xE2, 0x53, 0x72, 0x98, 0xCA, 0x2A, 0x8F, 0x59, 0x46, 0xF8, 0xE5, 0xFD, 0x09, 0x1D, 0xBD, 0xCB

+  };

+

+//

+// Public Exponent of RSA Key

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaE[] = { 0x11 };

+

+//

+// Private Exponent of RSA Key

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaD[] = {

+  0xA5, 0xDA, 0xFC, 0x53, 0x41, 0xFA, 0xF2, 0x89, 0xC4, 0xB9, 0x88, 0xDB, 0x30, 0xC1, 0xCD, 0xF8,

+  0x3F, 0x31, 0x25, 0x1E, 0x06, 0x68, 0xB4, 0x27, 0x84, 0x81, 0x38, 0x01, 0x57, 0x96, 0x41, 0xB2,

+  0x94, 0x10, 0xB3, 0xC7, 0x99, 0x8D, 0x6B, 0xC4, 0x65, 0x74, 0x5E, 0x5C, 0x39, 0x26, 0x69, 0xD6,

+  0x87, 0x0D, 0xA2, 0xC0, 0x82, 0xA9, 0x39, 0xE3, 0x7F, 0xDC, 0xB8, 0x2E, 0xC9, 0x3E, 0xDA, 0xC9,

+  0x7F, 0xF3, 0xAD, 0x59, 0x50, 0xAC, 0xCF, 0xBC, 0x11, 0x1C, 0x76, 0xF1, 0xA9, 0x52, 0x94, 0x44,

+  0xE5, 0x6A, 0xAF, 0x68, 0xC5, 0x6C, 0x09, 0x2C, 0xD3, 0x8D, 0xC3, 0xBE, 0xF5, 0xD2, 0x0A, 0x93,

+  0x99, 0x26, 0xED, 0x4F, 0x74, 0xA1, 0x3E, 0xDD, 0xFB, 0xE1, 0xA1, 0xCE, 0xCC, 0x48, 0x94, 0xAF,

+  0x94, 0x28, 0xC2, 0xB7, 0xB8, 0x88, 0x3F, 0xE4, 0x46, 0x3A, 0x4B, 0xC8, 0x5B, 0x1C, 0xB3, 0xC1

+  };

+

+//

+// Known Answer Test (KAT) Data for RSA PKCS#1 Signing

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 RsaSignData[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";

+

+//

+// Known Signature for the above message, under SHA-1 Digest

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaPkcs1Signature[] = {

+  0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, 0x4A, 0xFD, 0x1A, 0x05,

+  0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51,

+  0x55, 0x77, 0x90, 0xCF, 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,

+  0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, 0x20, 0x22, 0xBE, 0x59,

+  0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF,

+  0x4E, 0xCA, 0x2E, 0x4E, 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,

+  0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, 0x72, 0x05, 0xDE, 0xE6,

+  0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4

+  };

+

+//

+// Default public key 0x10001 = 65537

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 DefaultPublicKey[] = {

+  0x01, 0x00, 0x01

+};

+

+/**

+  Validate UEFI-OpenSSL RSA Interfaces.

+

+  @retval  EFI_SUCCESS  Validation succeeded.

+  @retval  EFI_ABORTED  Validation failed.

+

+**/

+EFI_STATUS

+ValidateCryptRsa (

+  VOID

+  )

+{

+  VOID     *Rsa;

+  UINT8    HashValue[SHA1_DIGEST_SIZE];

+  UINTN    HashSize;

+  UINTN    CtxSize;

+  VOID     *Sha1Ctx;

+  UINT8    *Signature;

+  UINTN    SigSize;

+  BOOLEAN  Status;

+  UINTN    KeySize;

+  UINT8    *KeyBuffer;

+

+  Print (L"\nUEFI-OpenSSL RSA Engine Testing: ");

+

+  //

+  // Generate & Initialize RSA Context

+  //

+  Rsa = RsaNew ();

+  Print (L"\n- Generate RSA Context ... ");

+  if (Rsa == NULL) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  //

+  // Set/Get RSA Key Components

+  //

+  Print (L"Set/Get RSA Key Components ... ");

+

+  //

+  // Set/Get RSA Key N

+  //

+  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeySize = 0;

+  Status = RsaGetKey (Rsa, RsaKeyN, NULL, &KeySize);

+  if (Status || KeySize != sizeof (RsaN)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeyBuffer = AllocatePool (KeySize);

+  Status = RsaGetKey (Rsa, RsaKeyN, KeyBuffer, &KeySize);

+  if (!Status || KeySize != sizeof (RsaN)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (KeyBuffer, RsaN, KeySize) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (KeyBuffer);

+

+  //

+  // Set/Get RSA Key E

+  //

+  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeySize = 0;

+  Status = RsaGetKey (Rsa, RsaKeyE, NULL, &KeySize);

+  if (Status || KeySize != sizeof (RsaE)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeyBuffer = AllocatePool (KeySize);

+  Status = RsaGetKey (Rsa, RsaKeyE, KeyBuffer, &KeySize);

+  if (!Status || KeySize != sizeof (RsaE)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (KeyBuffer, RsaE, KeySize) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (KeyBuffer);

+

+  //

+  // Clear/Get RSA Key Components

+  //

+  Print (L"Clear/Get RSA Key Components ... ");

+

+  //

+  // Clear/Get RSA Key N

+  //

+  Status = RsaSetKey (Rsa, RsaKeyN, NULL, 0);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeySize = 1;

+  Status = RsaGetKey (Rsa, RsaKeyN, NULL, &KeySize);

+  if (!Status || KeySize != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  //

+  // Clear/Get RSA Key E

+  //

+  Status = RsaSetKey (Rsa, RsaKeyE, NULL, 0);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeySize = 1;

+  Status = RsaGetKey (Rsa, RsaKeyE, NULL, &KeySize);

+  if (!Status || KeySize != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  //

+  // Generate RSA Key Components

+  //

+  Print (L"Generate RSA Key Components ... ");

+

+  Status = RsaGenerateKey (Rsa, RSA_MODULUS_LENGTH, NULL, 0);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeySize = RSA_MODULUS_LENGTH / 8;

+  KeyBuffer = AllocatePool (KeySize);

+  Status = RsaGetKey (Rsa, RsaKeyE, KeyBuffer, &KeySize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+  

+  if (KeySize != 3 ||

+      CompareMem (KeyBuffer, DefaultPublicKey, 3) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  KeySize = RSA_MODULUS_LENGTH / 8;

+  Status = RsaGetKey (Rsa, RsaKeyN, KeyBuffer, &KeySize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (KeySize != RSA_MODULUS_LENGTH / 8) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (!RsaCheckKey (Rsa)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  //

+  // Check invalid RSA key components

+  //

+  Print (L"Check Invalid RSA Key Components ... ");

+

+  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (RsaCheckKey (Rsa)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = RsaSetKey (Rsa, RsaKeyN, KeyBuffer, KeySize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (!RsaCheckKey (Rsa)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (RsaCheckKey (Rsa)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (KeyBuffer);

+

+  //

+  // SHA-1 Digest Message for PKCS#1 Signature 

+  //

+  Print (L"Hash Original Message ... ");

+  HashSize = SHA1_DIGEST_SIZE;

+  ZeroMem (HashValue, HashSize);

+  CtxSize = Sha1GetContextSize ();

+  Sha1Ctx = AllocatePool (CtxSize);

+

+  Status  = Sha1Init (Sha1Ctx);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status  = Sha1Update (Sha1Ctx, RsaSignData, AsciiStrLen (RsaSignData));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status  = Sha1Final (Sha1Ctx, HashValue);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  FreePool (Sha1Ctx);

+

+  //

+  // Sign RSA PKCS#1-encoded Signature

+  //

+  Print (L"PKCS#1 Signature ... ");

+

+  RsaFree (Rsa);

+

+  Rsa = RsaNew ();

+  if (Rsa == NULL) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Status = RsaSetKey (Rsa, RsaKeyD, RsaD, sizeof (RsaD));

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  SigSize = 0;

+  Status  = RsaPkcs1Sign (Rsa, HashValue, HashSize, NULL, &SigSize);

+  if (Status || SigSize == 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  Signature = AllocatePool (SigSize);

+  Status  = RsaPkcs1Sign (Rsa, HashValue, HashSize, Signature, &SigSize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (SigSize != sizeof (RsaPkcs1Signature)) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  if (CompareMem (Signature, RsaPkcs1Signature, SigSize) != 0) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  //

+  // Verify RSA PKCS#1-encoded Signature

+  //

+

+  Print (L"PKCS#1 Signature Verification ... ");

+

+  Status = RsaPkcs1Verify (Rsa, HashValue, HashSize, Signature, SigSize);

+  if (!Status) {

+    Print (L"[Fail]");

+    return EFI_ABORTED;

+  }

+

+  //

+  // Release Resources

+  //

+  RsaFree (Rsa);

+  Print (L"Release RSA Context ... [Pass]");

+

+  Print (L"\n");

+

+  return EFI_SUCCESS;

+}

diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index c5a7d4a..8df9e30 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -74,23 +74,13 @@
 #

 ################################################################################

 [PcdsFeatureFlag]

-  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE

-  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|FALSE

   gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE

   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE

 

 [PcdsFixedAtBuild]

-  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000

-  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000

-  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000

-

   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f

   gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000

   gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06

-  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF

-  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0

-  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0

-  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320

 

 ###################################################################################################

 #

@@ -119,5 +109,8 @@
 

   CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf

 

+[Components.IA32, Components.X64]

+  CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf

+

 [Components.IPF]

   CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/BaseCryptLibRuntimeCryptProtocol.inf

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index 556026e..ee8c44d 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1,7 +1,8 @@
 /** @file

   Defines base cryptographic library APIs.

   The Base Cryptographic Library provides implementations of basic cryptography

-  primitives (MD5, SHA-1, SHA-256, RSA, etc) for UEFI security functionality enabling.

+  primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security

+  functionality enabling.

 

 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

 This program and the accompanying materials

@@ -33,6 +34,16 @@
 #define SHA256_DIGEST_SIZE  32

 

 ///

+/// TDES block size in bytes

+///

+#define TDES_BLOCK_SIZE     8

+

+///

+/// AES block size in bytes

+///

+#define AES_BLOCK_SIZE      16

+

+///

 /// RSA Key Tags Definition used in RsaSetKey() function for key component identification.

 ///

 typedef enum {

@@ -62,14 +73,13 @@
   VOID

   );

 

-

 /**

   Initializes user-supplied memory pointed by Md5Context as MD5 hash context for

   subsequent use.

 

   If Md5Context is NULL, then ASSERT().

 

-  @param[in, out]  Md5Context  Pointer to MD5 Context being initialized.

+  @param[out]  Md5Context  Pointer to MD5 context being initialized.

 

   @retval TRUE   MD5 context initialization succeeded.

   @retval FALSE  MD5 context initialization failed.

@@ -78,23 +88,45 @@
 BOOLEAN

 EFIAPI

 Md5Init (

-  IN OUT  VOID  *Md5Context

+  OUT  VOID  *Md5Context

   );

 

+/**

+  Makes a copy of an existing MD5 context.

+

+  If Md5Context is NULL, then ASSERT().

+  If NewMd5Context is NULL, then ASSERT().

+

+  @param[in]  Md5Context     Pointer to MD5 context being copied.

+  @param[out] NewMd5Context  Pointer to new MD5 context.

+

+  @retval TRUE   MD5 context copy succeeded.

+  @retval FALSE  MD5 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+Md5Duplicate (

+  IN   CONST VOID  *Md5Context,

+  OUT  VOID        *NewMd5Context

+  );

 

 /**

-  Performs MD5 digest on a data buffer of the specified length. This function can

-  be called multiple times to compute the digest of long or discontinuous data streams.

+  Digests the input data and updates MD5 context.

+

+  This function performs MD5 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized

+  by Md5Final(). Behavior with invalid context is undefined.

 

   If Md5Context is NULL, then ASSERT().

 

   @param[in, out]  Md5Context  Pointer to the MD5 context.

   @param[in]       Data        Pointer to the buffer containing the data to be hashed.

-  @param[in]       DataLength  Length of Data buffer in bytes.

+  @param[in]       DataSize    Size of Data buffer in bytes.

 

   @retval TRUE   MD5 data digest succeeded.

-  @retval FALSE  Invalid MD5 context. After Md5Final function has been called, the

-                 MD5 context cannot be reused.

+  @retval FALSE  MD5 data digest failed.

 

 **/

 BOOLEAN

@@ -102,18 +134,22 @@
 Md5Update (

   IN OUT  VOID        *Md5Context,

   IN      CONST VOID  *Data,

-  IN      UINTN       DataLength

+  IN      UINTN       DataSize

   );

 

-

 /**

-  Completes MD5 hash computation and retrieves the digest value into the specified

-  memory. After this function has been called, the MD5 context cannot be used again.

+  Completes computation of the MD5 digest value.

+

+  This function completes MD5 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the MD5 context cannot

+  be used again.

+  MD5 context should be already correctly intialized by Md5Init(), and should not be

+  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.

 

   If Md5Context is NULL, then ASSERT().

   If HashValue is NULL, then ASSERT().

 

-  @param[in, out]  Md5Context  Pointer to the MD5 context

+  @param[in, out]  Md5Context  Pointer to the MD5 context.

   @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest

                                value (16 bytes).

 

@@ -128,7 +164,6 @@
   OUT     UINT8  *HashValue

   );

 

-

 /**

   Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations.

 

@@ -141,39 +176,60 @@
   VOID

   );

 

-

 /**

-  Initializes user-supplied memory pointed by Sha1Context as the SHA-1 hash context for

+  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for

   subsequent use.

 

   If Sha1Context is NULL, then ASSERT().

 

-  @param[in, out]  Sha1Context  Pointer to the SHA-1 Context being initialized.

+  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.

 

-  @retval TRUE   SHA-1 initialization succeeded.

-  @retval FALSE  SHA-1 initialization failed.

+  @retval TRUE   SHA-1 context initialization succeeded.

+  @retval FALSE  SHA-1 context initialization failed.

 

 **/

 BOOLEAN

 EFIAPI

 Sha1Init (

-  IN OUT  VOID  *Sha1Context

+  OUT  VOID  *Sha1Context

   );

 

+/**

+  Makes a copy of an existing SHA-1 context.

+

+  If Sha1Context is NULL, then ASSERT().

+  If NewSha1Context is NULL, then ASSERT().

+

+  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.

+  @param[out] NewSha1Context  Pointer to new SHA-1 context.

+

+  @retval TRUE   SHA-1 context copy succeeded.

+  @retval FALSE  SHA-1 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+Sha1Duplicate (

+  IN   CONST VOID  *Sha1Context,

+  OUT  VOID        *NewSha1Context

+  );

 

 /**

-  Performs SHA-1 digest on a data buffer of the specified length. This function can

-  be called multiple times to compute the digest of long or discontinuous data streams.

+  Digests the input data and updates SHA-1 context.

+

+  This function performs SHA-1 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be finalized

+  by Sha1Final(). Behavior with invalid context is undefined.

 

   If Sha1Context is NULL, then ASSERT().

 

   @param[in, out]  Sha1Context  Pointer to the SHA-1 context.

   @param[in]       Data         Pointer to the buffer containing the data to be hashed.

-  @param[in]       DataLength   Length of Data buffer in bytes.

+  @param[in]       DataSize     Size of Data buffer in bytes.

 

   @retval TRUE   SHA-1 data digest succeeded.

-  @retval FALSE  Invalid SHA-1 context. After Sha1Final function has been called, the

-                 SHA-1 context cannot be reused.

+  @retval FALSE  SHA-1 data digest failed.

 

 **/

 BOOLEAN

@@ -181,18 +237,22 @@
 Sha1Update (

   IN OUT  VOID        *Sha1Context,

   IN      CONST VOID  *Data,

-  IN      UINTN       DataLength

+  IN      UINTN       DataSize

   );

 

-

 /**

-  Completes SHA-1 hash computation and retrieves the digest value into the specified

-  memory. After this function has been called, the SHA-1 context cannot be used again.

+  Completes computation of the SHA-1 digest value.

+

+  This function completes SHA-1 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the SHA-1 context cannot

+  be used again.

+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be

+  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.

 

   If Sha1Context is NULL, then ASSERT().

   If HashValue is NULL, then ASSERT().

 

-  @param[in, out]  Sha1Context  Pointer to the SHA-1 context

+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.

   @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest

                                 value (20 bytes).

 

@@ -207,11 +267,10 @@
   OUT     UINT8  *HashValue

   );

 

-

 /**

-  Retrieves the size, in bytes, of the context buffer required for SHA-256 operations.

+  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.

 

-  @return  The size, in bytes, of the context buffer required for SHA-256 operations.

+  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.

 

 **/

 UINTN

@@ -220,14 +279,13 @@
   VOID

   );

 

-

 /**

   Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for

   subsequent use.

 

   If Sha256Context is NULL, then ASSERT().

 

-  @param[in, out]  Sha256Context  Pointer to SHA-256 Context being initialized.

+  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.

 

   @retval TRUE   SHA-256 context initialization succeeded.

   @retval FALSE  SHA-256 context initialization failed.

@@ -236,23 +294,45 @@
 BOOLEAN

 EFIAPI

 Sha256Init (

-  IN OUT  VOID  *Sha256Context

+  OUT  VOID  *Sha256Context

   );

 

+/**

+  Makes a copy of an existing SHA-256 context.

+

+  If Sha256Context is NULL, then ASSERT().

+  If NewSha256Context is NULL, then ASSERT().

+

+  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.

+  @param[out] NewSha256Context  Pointer to new SHA-256 context.

+

+  @retval TRUE   SHA-256 context copy succeeded.

+  @retval FALSE  SHA-256 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+Sha256Duplicate (

+  IN   CONST VOID  *Sha256Context,

+  OUT  VOID        *NewSha256Context

+  );

 

 /**

-  Performs SHA-256 digest on a data buffer of the specified length. This function can

-  be called multiple times to compute the digest of long or discontinuous data streams.

+  Digests the input data and updates SHA-256 context.

+

+  This function performs SHA-256 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be finalized

+  by Sha256Final(). Behavior with invalid context is undefined.

 

   If Sha256Context is NULL, then ASSERT().

 

   @param[in, out]  Sha256Context  Pointer to the SHA-256 context.

   @param[in]       Data           Pointer to the buffer containing the data to be hashed.

-  @param[in]       DataLength     Length of Data buffer in bytes.

+  @param[in]       DataSize       Size of Data buffer in bytes.

 

   @retval TRUE   SHA-256 data digest succeeded.

-  @retval FALSE  Invalid SHA-256 context. After Sha256Final function has been called, the

-                 SHA-256 context cannot be reused.

+  @retval FALSE  SHA-256 data digest failed.

 

 **/

 BOOLEAN

@@ -260,18 +340,22 @@
 Sha256Update (

   IN OUT  VOID        *Sha256Context,

   IN      CONST VOID  *Data,

-  IN      UINTN       DataLength

+  IN      UINTN       DataSize

   );

 

-

 /**

-  Completes SHA-256 hash computation and retrieves the digest value into the specified

-  memory. After this function has been called, the SHA-256 context cannot be used again.

+  Completes computation of the SHA-256 digest value.

+

+  This function completes SHA-256 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the SHA-256 context cannot

+  be used again.

+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be

+  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.

 

   If Sha256Context is NULL, then ASSERT().

   If HashValue is NULL, then ASSERT().

 

-  @param[in, out]  Sha256Context  Pointer to SHA-256 context

+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.

   @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest

                                   value (32 bytes).

 

@@ -291,28 +375,717 @@
 //    MAC (Message Authentication Code) Primitive

 //=====================================================================================

 

-///

-/// No MAC supports for minimum scope required by UEFI

-///

+/**

+  Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.

+

+  @return  The size, in bytes, of the context buffer required for HMAC-MD5 operations.

+

+**/

+UINTN

+EFIAPI

+HmacMd5GetContextSize (

+  VOID

+  );

+

+/**

+  Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for

+  subsequent use.

+

+  If HmacMd5Context is NULL, then ASSERT().

+

+  @param[out]  HmacMd5Context  Pointer to HMAC-MD5 context being initialized.

+  @param[in]   Key             Pointer to the user-supplied key.

+  @param[in]   KeySize         Key size in bytes.

+

+  @retval TRUE   HMAC-MD5 context initialization succeeded.

+  @retval FALSE  HMAC-MD5 context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Init (

+  OUT  VOID         *HmacMd5Context,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeySize

+  );

+

+/**

+  Makes a copy of an existing HMAC-MD5 context.

+

+  If HmacMd5Context is NULL, then ASSERT().

+  If NewHmacMd5Context is NULL, then ASSERT().

+

+  @param[in]  HmacMd5Context     Pointer to HMAC-MD5 context being copied.

+  @param[out] NewHmacMd5Context  Pointer to new HMAC-MD5 context.

+

+  @retval TRUE   HMAC-MD5 context copy succeeded.

+  @retval FALSE  HMAC-MD5 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Duplicate (

+  IN   CONST VOID  *HmacMd5Context,

+  OUT  VOID        *NewHmacMd5Context

+  );

+

+/**

+  Digests the input data and updates HMAC-MD5 context.

+

+  This function performs HMAC-MD5 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be

+  finalized by HmacMd5Final(). Behavior with invalid context is undefined.

+

+  If HmacMd5Context is NULL, then ASSERT().

+

+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.

+  @param[in]       Data            Pointer to the buffer containing the data to be digested.

+  @param[in]       DataSize        Size of Data buffer in bytes.

+

+  @retval TRUE   HMAC-MD5 data digest succeeded.

+  @retval FALSE  HMAC-MD5 data digest failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Update (

+  IN OUT  VOID        *HmacMd5Context,

+  IN      CONST VOID  *Data,

+  IN      UINTN       DataSize

+  );

+

+/**

+  Completes computation of the HMAC-MD5 digest value.

+

+  This function completes HMAC-MD5 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the HMAC-MD5 context cannot

+  be used again.

+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be

+  finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.

+

+  If HmacMd5Context is NULL, then ASSERT().

+  If HashValue is NULL, then ASSERT().

+

+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.

+  @param[out]      HashValue       Pointer to a buffer that receives the HMAC-MD5 digest

+                                   value (16 bytes).

+

+  @retval TRUE   HMAC-MD5 digest computation succeeded.

+  @retval FALSE  HMAC-MD5 digest computation failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Final (

+  IN OUT  VOID   *HmacMd5Context,

+  OUT     UINT8  *HmacValue

+  );

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.

+

+  @return  The size, in bytes, of the context buffer required for HMAC-SHA1 operations.

+

+**/

+UINTN

+EFIAPI

+HmacSha1GetContextSize (

+  VOID

+  );

+

+/**

+  Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for

+  subsequent use.

+

+  If HmacSha1Context is NULL, then ASSERT().

+

+  @param[out]  HmacSha1Context  Pointer to HMAC-SHA1 context being initialized.

+  @param[in]   Key              Pointer to the user-supplied key.

+  @param[in]   KeySize          Key size in bytes.

+

+  @retval TRUE   HMAC-SHA1 context initialization succeeded.

+  @retval FALSE  HMAC-SHA1 context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Init (

+  OUT  VOID         *HmacSha1Context,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeySize

+  );

+

+/**

+  Makes a copy of an existing HMAC-SHA1 context.

+

+  If HmacSha1Context is NULL, then ASSERT().

+  If NewHmacSha1Context is NULL, then ASSERT().

+

+  @param[in]  HmacSha1Context     Pointer to HMAC-SHA1 context being copied.

+  @param[out] NewHmacSha1Context  Pointer to new HMAC-SHA1 context.

+

+  @retval TRUE   HMAC-SHA1 context copy succeeded.

+  @retval FALSE  HMAC-SHA1 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Duplicate (

+  IN   CONST VOID  *HmacSha1Context,

+  OUT  VOID        *NewHmacSha1Context

+  );

+

+/**

+  Digests the input data and updates HMAC-SHA1 context.

+

+  This function performs HMAC-SHA1 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not

+  be finalized by HmacSha1Final(). Behavior with invalid context is undefined.

+

+  If HmacSha1Context is NULL, then ASSERT().

+

+  @param[in, out]  HmacSha1Context Pointer to the HMAC-SHA1 context.

+  @param[in]       Data            Pointer to the buffer containing the data to be digested.

+  @param[in]       DataSize        Size of Data buffer in bytes.

+

+  @retval TRUE   HMAC-SHA1 data digest succeeded.

+  @retval FALSE  HMAC-SHA1 data digest failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Update (

+  IN OUT  VOID        *HmacSha1Context,

+  IN      CONST VOID  *Data,

+  IN      UINTN       DataSize

+  );

+

+/**

+  Completes computation of the HMAC-SHA1 digest value.

+

+  This function completes HMAC-SHA1 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the HMAC-SHA1 context cannot

+  be used again.

+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should

+  not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.

+

+  If HmacSha1Context is NULL, then ASSERT().

+  If HashValue is NULL, then ASSERT().

+

+  @param[in, out]  HmacSha1Context  Pointer to the HMAC-SHA1 context.

+  @param[out]      HashValue        Pointer to a buffer that receives the HMAC-SHA1 digest

+                                    value (20 bytes).

+

+  @retval TRUE   HMAC-SHA1 digest computation succeeded.

+  @retval FALSE  HMAC-SHA1 digest computation failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Final (

+  IN OUT  VOID   *HmacSha1Context,

+  OUT     UINT8  *HmacValue

+  );

 

 

 //=====================================================================================

 //    Symmetric Cryptography Primitive

 //=====================================================================================

 

-///

-/// No symmetric cryptographic supports for minimum scope required by UEFI

-///

+/**

+  Retrieves the size, in bytes, of the context buffer required for TDES operations.

 

+  @return  The size, in bytes, of the context buffer required for TDES operations.

+

+**/

+UINTN

+EFIAPI

+TdesGetContextSize (

+  VOID

+  );

+

+/**

+  Initializes user-supplied memory as TDES context for subsequent use.

+

+  This function initializes user-supplied memory pointed by TdesContext as TDES context.

+  In addtion, it sets up all TDES key materials for subsequent encryption and decryption

+  operations.

+  There are 3 key options as follows:

+  KeyLength = 64,  Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)

+  KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)

+  KeyLength = 192  Keying option 3: K1 != K2 != K3 (Strongest)

+

+  If TdesContext is NULL, then ASSERT().

+  If Key is NULL, then ASSERT().

+  If KeyLength is not valid, then ASSERT().

+

+  @param[out]  TdesContext  Pointer to TDES context being initialized.

+  @param[in]   Key          Pointer to the user-supplied TDES key.

+  @param[in]   KeyLength    Length of TDES key in bits.

+

+  @retval TRUE   TDES context initialization succeeded.

+  @retval FALSE  TDES context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesInit (

+  OUT  VOID         *TdesContext,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeyLength

+  );

+

+/**

+  Performs TDES encryption on a data buffer of the specified size in ECB mode.

+

+  This function performs TDES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.

+

+  @retval TRUE   TDES encryption succeeded.

+  @retval FALSE  TDES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesEcbEncrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Performs TDES decryption on a data buffer of the specified size in ECB mode.

+

+  This function performs TDES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[out]  Output       Pointer to a buffer that receives the TDES decryption output.

+

+  @retval TRUE   TDES decryption succeeded.

+  @retval FALSE  TDES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesEcbDecrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Performs TDES encryption on a data buffer of the specified size in CBC mode.

+

+  This function performs TDES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (8 bytes).

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[in]   Ivec         Pointer to initialization vector.

+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.

+

+  @retval TRUE   TDES encryption succeeded.

+  @retval FALSE  TDES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesCbcEncrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Performs TDES decryption on a data buffer of the specified size in CBC mode.

+

+  This function performs TDES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (8 bytes).

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[in]   Ivec         Pointer to initialization vector.

+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.

+

+  @retval TRUE   TDES decryption succeeded.

+  @retval FALSE  TDES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesCbcDecrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for AES operations.

+

+  @return  The size, in bytes, of the context buffer required for AES operations.

+

+**/

+UINTN

+EFIAPI

+AesGetContextSize (

+  VOID

+  );

+

+/**

+  Initializes user-supplied memory as AES context for subsequent use.

+

+  This function initializes user-supplied memory pointed by AesContext as AES context.

+  In addtion, it sets up all AES key materials for subsequent encryption and decryption

+  operations.

+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.

+

+  If AesContext is NULL, then ASSERT().

+  If Key is NULL, then ASSERT().

+  If KeyLength is not valid, then ASSERT().

+

+  @param[out]  AesContext  Pointer to AES context being initialized.

+  @param[in]   Key         Pointer to the user-supplied AES key.

+  @param[in]   KeyLength   Length of AES key in bits.

+

+  @retval TRUE   AES context initialization succeeded.

+  @retval FALSE  AES context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesInit (

+  OUT  VOID         *AesContext,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeyLength

+  );

+

+/**

+  Performs AES encryption on a data buffer of the specified size in ECB mode.

+

+  This function performs AES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES encryption succeeded.

+  @retval FALSE  AES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesEcbEncrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Performs AES decryption on a data buffer of the specified size in ECB mode.

+

+  This function performs AES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be decrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[out]  Output      Pointer to a buffer that receives the AES decryption output.

+

+  @retval TRUE   AES decryption succeeded.

+  @retval FALSE  AES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesEcbDecrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Performs AES encryption on a data buffer of the specified size in CBC mode.

+

+  This function performs AES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (16 bytes).

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[in]   Ivec        Pointer to initialization vector.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES encryption succeeded.

+  @retval FALSE  AES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesCbcEncrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Performs AES decryption on a data buffer of the specified size in CBC mode.

+

+  This function performs AES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (16 bytes).

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[in]   Ivec        Pointer to initialization vector.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES decryption succeeded.

+  @retval FALSE  AES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesCbcDecrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  );

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for ARC4 operations.

+

+  @return  The size, in bytes, of the context buffer required for ARC4 operations.

+

+**/

+UINTN

+EFIAPI

+Arc4GetContextSize (

+  VOID

+  );

+

+/**

+  Initializes user-supplied memory as ARC4 context for subsequent use.

+

+  This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.

+  In addtion, it sets up all ARC4 key materials for subsequent encryption and decryption

+  operations.

+

+  If Arc4Context is NULL, then ASSERT().

+  If Key is NULL, then ASSERT().

+  If KeySize does not in the range of [5, 256] bytes, then ASSERT().

+

+  @param[out]  Arc4Context  Pointer to ARC4 context being initialized.

+  @param[in]   Key          Pointer to the user-supplied ARC4 key.

+  @param[in]   KeySize      Size of ARC4 key in bytes.

+

+  @retval TRUE   ARC4 context initialization succeeded.

+  @retval FALSE  ARC4 context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Init (

+  OUT  VOID         *Arc4Context,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeySize

+  );

+

+/**

+  Performs ARC4 encryption on a data buffer of the specified size.

+

+  This function performs ARC4 encryption on data buffer pointed by Input, of specified

+  size of InputSize.

+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with

+  invalid ARC4 context is undefined.

+

+  If Arc4Context is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   Arc4Context  Pointer to the ARC4 context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[out]  Output       Pointer to a buffer that receives the ARC4 encryption output.

+

+  @retval TRUE   ARC4 encryption succeeded.

+  @retval FALSE  ARC4 encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Encrypt (

+  IN OUT  VOID         *Arc4Context,

+  IN      CONST UINT8  *Input,

+  IN      UINTN        InputSize,

+  OUT     UINT8        *Output

+  );

+

+/**

+  Performs ARC4 decryption on a data buffer of the specified size.

+

+  This function performs ARC4 decryption on data buffer pointed by Input, of specified

+  size of InputSize.

+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with

+  invalid ARC4 context is undefined.

+

+  If Arc4Context is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   Arc4Context  Pointer to the ARC4 context.

+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[out]  Output       Pointer to a buffer that receives the ARC4 decryption output.

+

+  @retval TRUE   ARC4 decryption succeeded.

+  @retval FALSE  ARC4 decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Decrypt (

+  IN OUT  VOID   *Arc4Context,

+  IN      UINT8  *Input,

+  IN      UINTN  InputSize,

+  OUT     UINT8  *Output

+  );

+

+/**

+  Resets the ARC4 context to the initial state.

+

+  The function resets the ARC4 context to the state it had immediately after the

+  ARC4Init() function call.

+  Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context

+  should be already correctly initialized by ARC4Init().

+

+  If Arc4Context is NULL, then ASSERT().

+

+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.

+

+  @retval TRUE   ARC4 reset succeeded.

+  @retval FALSE  ARC4 reset failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Reset (

+  IN OUT  VOID  *Arc4Context

+  );

 

 //=====================================================================================

 //    Asymmetric Cryptography Primitive

 //=====================================================================================

 

 /**

-  Allocates and Initializes one RSA Context for subsequent use.

+  Allocates and initializes one RSA context for subsequent use.

 

-  @return  Pointer to the RSA Context that has been initialized.

+  @return  Pointer to the RSA context that has been initialized.

            If the allocations fails, RsaNew() returns NULL.

 

 **/

@@ -322,9 +1095,10 @@
   VOID

   );

 

-

 /**

-  Release the specified RSA Context.

+  Release the specified RSA context.

+

+  If RsaContext is NULL, then ASSERT().

 

   @param[in]  RsaContext  Pointer to the RSA context to be released.

 

@@ -335,32 +1109,159 @@
   IN  VOID  *RsaContext

   );

 

-

 /**

-  Sets the tag-designated RSA key component into the established RSA context from

-  the user-specified nonnegative integer (octet string format represented in RSA

-  PKCS#1).

+  Sets the tag-designated key component into the established RSA context.

+

+  This function sets the tag-designated RSA key component into the established

+  RSA context from the user-specified non-negative integer (octet string format

+  represented in RSA PKCS#1).

+  If BigNumber is NULL, then the specified key componenet in RSA context is cleared.

 

   If RsaContext is NULL, then ASSERT().

 

   @param[in, out]  RsaContext  Pointer to RSA context being set.

   @param[in]       KeyTag      Tag of RSA key component being set.

   @param[in]       BigNumber   Pointer to octet integer buffer.

-  @param[in]       BnLength    Length of big number buffer in bytes.

+                               If NULL, then the specified key componenet in RSA

+                               context is cleared.

+  @param[in]       BnSize      Size of big number buffer in bytes.

+                               If BigNumber is NULL, then it is ignored.

 

-  @return  TRUE   RSA key component was set successfully.

-  @return  FALSE  Invalid RSA key component tag.

+  @retval  TRUE   RSA key component was set successfully.

+  @retval  FALSE  Invalid RSA key component tag.

 

 **/

 BOOLEAN

 EFIAPI

 RsaSetKey (

-  IN OUT VOID         *RsaContext,

-  IN     RSA_KEY_TAG  KeyTag,

-  IN     CONST UINT8  *BigNumber,

-  IN     UINTN        BnLength

+  IN OUT  VOID         *RsaContext,

+  IN      RSA_KEY_TAG  KeyTag,

+  IN      CONST UINT8  *BigNumber,

+  IN      UINTN        BnSize

   );

 

+/**

+  Gets the tag-designated RSA key component from the established RSA context.

+

+  This function retrieves the tag-designated RSA key component from the

+  established RSA context as a non-negative integer (octet string format

+  represented in RSA PKCS#1).

+  If specified key component has not been set or has been cleared, then returned

+  BnSize is set to 0.

+  If the BigNumber buffer is too small to hold the contents of the key, FALSE

+  is returned and BnSize is set to the required buffer size to obtain the key.

+

+  If RsaContext is NULL, then ASSERT().

+  If BnSize is NULL, then ASSERT().

+  If BnSize is large enough but BigNumber is NULL, then ASSERT().

+

+  @param[in, out]  RsaContext  Pointer to RSA context being set.

+  @param[in]       KeyTag      Tag of RSA key component being set.

+  @param[out]      BigNumber   Pointer to octet integer buffer.

+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.

+                               On output, the size of data returned in big number buffer in bytes.

+

+  @retval  TRUE   RSA key component was retrieved successfully.

+  @retval  FALSE  Invalid RSA key component tag.

+  @retval  FALSE  BnSize is too small.

+

+**/

+BOOLEAN

+EFIAPI

+RsaGetKey (

+  IN OUT  VOID         *RsaContext,

+  IN      RSA_KEY_TAG  KeyTag,

+  OUT     UINT8        *BigNumber,

+  IN OUT  UINTN        *BnSize

+  );

+

+/**

+  Generates RSA key components.

+

+  This function generates RSA key components. It takes RSA public exponent E and

+  length in bits of RSA modulus N as input, and generates all key components.

+  If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.

+

+  Before this function can be invoked, pseudorandom number generator must be correctly

+  initialized by RandomSeed().

+

+  If RsaContext is NULL, then ASSERT().

+

+  @param[in, out]  RsaContext           Pointer to RSA context being set.

+  @param[in]       ModulusLength        Length of RSA modulus N in bits.

+  @param[in]       PublicExponent       Pointer to RSA public exponent.

+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes. 

+

+  @retval  TRUE   RSA key component was generated successfully.

+  @retval  FALSE  Invalid RSA key component tag.

+

+**/

+BOOLEAN

+EFIAPI

+RsaGenerateKey (

+  IN OUT  VOID         *RsaContext,

+  IN      UINTN        ModulusLength,

+  IN      CONST UINT8  *PublicExponent,

+  IN      UINTN        PublicExponentSize

+  );

+

+/**

+  Validates key components of RSA context.

+

+  This function validates key compoents of RSA context in following aspects:

+  - Whether p is a prime

+  - Whether q is a prime

+  - Whether n = p * q

+  - Whether d*e = 1  mod lcm(p-1,q-1)

+

+  If RsaContext is NULL, then ASSERT().

+

+  @param[in]  RsaContext  Pointer to RSA context to check.

+

+  @retval  TRUE   RSA key components are valid.

+  @retval  FALSE  RSA key components are not valid.

+

+**/

+BOOLEAN

+EFIAPI

+RsaCheckKey (

+  IN  VOID  *RsaContext

+  );

+

+/**

+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.

+

+  This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in

+  RSA PKCS#1.

+  If the Signature buffer is too small to hold the contents of signature, FALSE

+  is returned and SigSize is set to the required buffer size to obtain the signature.

+

+  If RsaContext is NULL, then ASSERT().

+  If MessageHash is NULL, then ASSERT().

+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().

+  If SigSize is large enough but Signature is NULL, then ASSERT().

+

+  @param[in]      RsaContext   Pointer to RSA context for signature generation.

+  @param[in]      MessageHash  Pointer to octet message hash to be signed.

+  @param[in]      HashSize     Size of the message hash in bytes.

+  @param[out]     Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.

+  @param[in, out] SigSize      On input, the size of Signature buffer in bytes.

+                              On output, the size of data returned in Signature buffer in bytes.

+

+  @retval  TRUE   Signature successfully generated in PKCS1-v1_5.

+  @retval  FALSE  Signature generation failed.

+  @retval  FALSE  SigSize is too small.

+

+**/

+BOOLEAN

+EFIAPI

+RsaPkcs1Sign (

+  IN      VOID         *RsaContext,

+  IN      CONST UINT8  *MessageHash,

+  IN      UINTN        HashSize,

+  OUT     UINT8        *Signature,

+  IN OUT  UINTN        *SigSize

+  );

 

 /**

   Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in

@@ -369,16 +1270,16 @@
   If RsaContext is NULL, then ASSERT().

   If MessageHash is NULL, then ASSERT().

   If Signature is NULL, then ASSERT().

-  If HashLength is not equal to the size of MD5, SHA-1 or SHA-256 digest, then ASSERT().

+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().

 

   @param[in]  RsaContext   Pointer to RSA context for signature verification.

   @param[in]  MessageHash  Pointer to octet message hash to be checked.

-  @param[in]  HashLength   Length of the message hash in bytes.

+  @param[in]  HashSize     Size of the message hash in bytes.

   @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.

-  @param[in]  SigLength    Length of signature in bytes.

+  @param[in]  SigSize      Size of signature in bytes.

 

-  @return  TRUE   Valid signature encoded in PKCS1-v1_5.

-  @return  FALSE  Invalid signature or invalid RSA context.

+  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.

+  @retval  FALSE  Invalid signature or invalid RSA context.

 

 **/

 BOOLEAN

@@ -386,12 +1287,11 @@
 RsaPkcs1Verify (

   IN  VOID         *RsaContext,

   IN  CONST UINT8  *MessageHash,

-  IN  UINTN        HashLength,

+  IN  UINTN        HashSize,

   IN  UINT8        *Signature,

-  IN  UINTN        SigLength

+  IN  UINTN        SigSize

   );

 

-

 /**

   Verifies the validility of a PKCS#7 signed data as described in "PKCS #7: Cryptographic

   Message Syntax Standard".

@@ -399,27 +1299,227 @@
   If P7Data is NULL, then ASSERT().

 

   @param[in]  P7Data       Pointer to the PKCS#7 message to verify.

-  @param[in]  P7Length     Length of the PKCS#7 message in bytes.

+  @param[in]  P7Size       Size of the PKCS#7 message in bytes.

   @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which

                            is used for certificate chain verification.

-  @param[in]  CertLength   Length of the trusted certificate in bytes.

+  @param[in]  CertSize     Size of the trusted certificate in bytes.

   @param[in]  InData       Pointer to the content to be verified.

-  @param[in]  DataLength   Length of InData in bytes.

+  @param[in]  DataSize     Size of InData in bytes.

 

-  @return  TRUE  The specified PKCS#7 signed data is valid.

-  @return  FALSE Invalid PKCS#7 signed data.

+  @retval  TRUE  The specified PKCS#7 signed data is valid.

+  @retval  FALSE Invalid PKCS#7 signed data.

 

 **/

 BOOLEAN

 EFIAPI

 Pkcs7Verify (

   IN  CONST UINT8  *P7Data,

-  IN  UINTN        P7Length,

+  IN  UINTN        P7Size,

   IN  CONST UINT8  *TrustedCert,

-  IN  UINTN        CertLength,

+  IN  UINTN        CertSize,

   IN  CONST UINT8  *InData,

-  IN  UINTN        DataLength

+  IN  UINTN        DataSize

   );

 

+//=====================================================================================

+//    DH Key Exchange Primitive

+//=====================================================================================

+

+/**

+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.

+

+  @return  Pointer to the Diffie-Hellman Context that has been initialized.

+           If the allocations fails, DhNew() returns NULL.

+

+**/

+VOID *

+EFIAPI

+DhNew (

+  VOID

+  );

+

+/**

+  Release the specified DH context.

+

+  If DhContext is NULL, then ASSERT().

+

+  @param[in]  DhContext  Pointer to the DH context to be released.

+

+**/

+VOID

+EFIAPI

+DhFree (

+  IN  VOID  *DhContext

+  );

+

+/**

+  Generates DH parameter.

+

+  Given generator g, and length of prime number p in bits, this function generates p,

+  and sets DH context according to value of g and p.

+  

+  Before this function can be invoked, pseudorandom number generator must be correctly

+  initialized by RandomSeed().

+

+  If DhContext is NULL, then ASSERT().

+  If Prime is NULL, then ASSERT().

+

+  @param[in, out]  DhContext    Pointer to the DH context.

+  @param[in]       Generator    Value of generator.

+  @param[in]       PrimeLength  Length in bits of prime to be generated.

+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.

+

+  @retval TRUE   DH pamameter generation succeeded.

+  @retval FALSE  Value of Generator is not supported.

+  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.

+

+**/

+BOOLEAN

+EFIAPI

+DhGenerateParameter (

+  IN OUT  VOID   *DhContext,

+  IN      UINTN  Generator,

+  IN      UINTN  PrimeLength,

+  OUT     UINT8  *Prime

+  );

+

+/**

+  Sets generator and prime parameters for DH.

+

+  Given generator g, and prime number p, this function and sets DH

+  context accordingly.

+

+  If DhContext is NULL, then ASSERT().

+  If Prime is NULL, then ASSERT().

+

+  @param[in, out]  DhContext    Pointer to the DH context.

+  @param[in]       Generator    Value of generator.

+  @param[in]       PrimeLength  Length in bits of prime to be generated.

+  @param[in]       Prime        Pointer to the prime number.

+

+  @retval TRUE   DH pamameter setting succeeded.

+  @retval FALSE  Value of Generator is not supported.

+  @retval FALSE  Value of Generator is not suitable for the Prime.

+  @retval FALSE  Value of Prime is not a prime number.

+  @retval FALSE  Value of Prime is not a safe prime number.

+

+**/

+BOOLEAN

+EFIAPI

+DhSetParameter (

+  IN OUT  VOID         *DhContext,

+  IN      UINTN        Generator,

+  IN      UINTN        PrimeLength,

+  IN      CONST UINT8  *Prime

+  );

+

+/**

+  Generates DH public key.

+

+  This function generates random secret exponent, and computes the public key, which is 

+  returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.

+  If the PublicKey buffer is too small to hold the public key, FALSE is returned and

+  PublicKeySize is set to the required buffer size to obtain the public key.

+

+  If DhContext is NULL, then ASSERT().

+  If PublicKeySize is NULL, then ASSERT().

+  If PublicKeySize is large enough but PublicKey is NULL, then ASSERT().

+

+  @param[in, out]  DhContext      Pointer to the DH context.

+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.

+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.

+                                 On output, the size of data returned in PublicKey buffer in bytes.

+

+  @retval TRUE   DH public key generation succeeded.

+  @retval FALSE  DH public key generation failed.

+  @retval FALSE  PublicKeySize is not large enough.

+

+**/

+BOOLEAN

+EFIAPI

+DhGenerateKey (

+  IN OUT  VOID   *DhContext,

+  OUT     UINT8  *PublicKey,

+  IN OUT  UINTN  *PublicKeySize

+  );

+

+/**

+  Computes exchanged common key.

+

+  Given peer's public key, this function computes the exchanged common key, based on its own

+  context including value of prime modulus and random secret exponent. 

+

+  If DhContext is NULL, then ASSERT().

+  If PeerPublicKey is NULL, then ASSERT().

+  If KeySize is NULL, then ASSERT().

+  If KeySize is large enough but Key is NULL, then ASSERT().

+

+  @param[in, out]  DhContext          Pointer to the DH context.

+  @param[in]       PeerPublicKey      Pointer to the peer's public key.

+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.

+  @param[out]      Key                Pointer to the buffer to receive generated key.

+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.

+                                     On output, the size of data returned in Key buffer in bytes.

+

+  @retval TRUE   DH exchanged key generation succeeded.

+  @retval FALSE  DH exchanged key generation failed.

+  @retval FALSE  KeySize is not large enough.

+

+**/

+BOOLEAN

+EFIAPI

+DhComputeKey (

+  IN OUT  VOID         *DhContext,

+  IN      CONST UINT8  *PeerPublicKey,

+  IN      UINTN        PeerPublicKeySize,

+  OUT     UINT8        *Key,

+  IN OUT  UINTN        *KeySize

+  );

+

+//=====================================================================================

+//    Pseudo-Random Generation Primitive

+//=====================================================================================

+

+/**

+  Sets up the seed value for the pseudorandom number generator.

+

+  This function sets up the seed value for the pseudorandom number generator.

+  If Seed is not NULL, then the seed passed in is used.

+  If Seed is NULL, then default seed is used.

+

+  @param[in]  Seed      Pointer to seed value.

+                        If NULL, default seed is used.

+  @param[in]  SeedSize  Size of seed value.

+                        If Seed is NULL, this parameter is ignored.

+

+  @retval TRUE   Pseudorandom number generator has enough entropy for random generation.

+  @retval FALSE  Pseudorandom number generator does not have enough entropy for random generation.

+

+**/

+BOOLEAN

+EFIAPI

+RandomSeed (

+  IN  CONST  UINT8  *Seed  OPTIONAL,

+  IN  UINTN         SeedSize

+  );

+

+/**

+  Generates a pseudorandom byte stream of the specified size.

+

+  If Output is NULL, then ASSERT().

+

+  @param[out]  Output  Pointer to buffer to receive random value.

+  @param[in]   Size    Size of randome bytes to generate.

+

+  @retval TRUE   Pseudorandom byte stream generated successfully.

+  @retval FALSE  Pseudorandom number generator fails to generate due to lack of entropy.

+

+**/

+BOOLEAN

+EFIAPI

+RandomBytes (

+  OUT  UINT8  *Output,

+  IN   UINTN  Size

+  );

 

 #endif // __BASE_CRYPT_LIB_H__

diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 5395da0..c941942 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -27,11 +27,19 @@
 #

 

 [Sources]

+  InternalCryptLib.h

   Hash/CryptMd5.c

   Hash/CryptSha1.c

   Hash/CryptSha256.c

+  Hmac/CryptHmacMd5.c

+  Hmac/CryptHmacSha1.c

+  Cipher/CryptAes.c

+  Cipher/CryptTdes.c

+  Cipher/CryptArc4.c

+  Rand/CryptRand.c

   Pk/CryptRsa.c

   Pk/CryptPkcs7.c

+  Pk/CryptDh.c

 

   SysCall/CrtWrapper.c

   SysCall/TimerWrapper.c

@@ -58,8 +66,6 @@
   SysCall/Ia32/MathLShiftS64.S      | GCC

   SysCall/Ia32/MathRShiftU64.S      | GCC

 

-  SysCall/Ia32/Alloca.S             | GCC

-

 [Packages]

   MdePkg/MdePkg.dec

   CryptoPkg/CryptoPkg.dec

diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c
new file mode 100644
index 0000000..e32063c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c
@@ -0,0 +1,309 @@
+/** @file

+  AES Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/aes.h>

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for AES operations.

+

+  @return  The size, in bytes, of the context buffer required for AES operations.

+

+**/

+UINTN

+EFIAPI

+AesGetContextSize (

+  VOID

+  )

+{

+  //

+  // AES uses different key contexts for encryption and decryption, so here memory

+  // for 2 copies of AES_KEY is allocated.

+  //

+  return (UINTN) (2 * sizeof (AES_KEY));

+}

+

+/**

+  Initializes user-supplied memory as AES context for subsequent use.

+

+  This function initializes user-supplied memory pointed by AesContext as AES context.

+  In addtion, it sets up all AES key materials for subsequent encryption and decryption

+  operations.

+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.

+

+  If AesContext is NULL, then ASSERT().

+  If Key is NULL, then ASSERT().

+  If KeyLength is not valid, then ASSERT().

+

+  @param[out]  AesContext  Pointer to AES context being initialized.

+  @param[in]   Key         Pointer to the user-supplied AES key.

+  @param[in]   KeyLength   Length of AES key in bits.

+

+  @retval TRUE   AES context initialization succeeded.

+  @retval FALSE  AES context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesInit (

+  OUT  VOID         *AesContext,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeyLength

+  )

+{

+  AES_KEY  *AesKey;

+

+  ASSERT (AesContext != NULL);

+  //

+  // AES Key Checking

+  //

+  ASSERT (Key != NULL);

+  ASSERT ((KeyLength == 128) || (KeyLength == 192) || (KeyLength == 256));

+

+  //

+  // Initialize AES encryption & decryption key schedule.

+  //

+  AesKey = (AES_KEY *) AesContext;

+  if (AES_set_encrypt_key (Key, (UINT32) KeyLength, AesKey) != 0) {

+    return FALSE;

+  }

+  if (AES_set_decrypt_key (Key, (UINT32) KeyLength, AesKey + 1) != 0) {

+    return FALSE;

+  }

+  return TRUE;

+}

+

+/**

+  Performs AES encryption on a data buffer of the specified size in ECB mode.

+

+  This function performs AES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES encryption succeeded.

+  @retval FALSE  AES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesEcbEncrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  )

+{

+  AES_KEY  *AesKey;

+  

+  ASSERT (AesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);

+  ASSERT (Output != NULL);

+

+  AesKey = (AES_KEY *) AesContext;

+

+  //

+  // Perform AES data encryption with ECB mode (block-by-block)

+  //

+  while (InputSize > 0) {

+    AES_ecb_encrypt (Input, Output, AesKey, AES_ENCRYPT);

+    Input     += AES_BLOCK_SIZE;

+    Output    += AES_BLOCK_SIZE;

+    InputSize -= AES_BLOCK_SIZE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Performs AES decryption on a data buffer of the specified size in ECB mode.

+

+  This function performs AES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be decrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[out]  Output      Pointer to a buffer that receives the AES decryption output.

+

+  @retval TRUE   AES decryption succeeded.

+  @retval FALSE  AES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesEcbDecrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  )

+{

+  AES_KEY  *AesKey;

+  

+  ASSERT (AesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);

+  ASSERT (Output != NULL);

+

+  AesKey = (AES_KEY *) AesContext;

+

+  //

+  // Perform AES data decryption with ECB mode (block-by-block)

+  //

+  while (InputSize > 0) {

+    AES_ecb_encrypt (Input, Output, AesKey + 1, AES_DECRYPT);

+    Input     += AES_BLOCK_SIZE;

+    Output    += AES_BLOCK_SIZE;

+    InputSize -= AES_BLOCK_SIZE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Performs AES encryption on a data buffer of the specified size in CBC mode.

+

+  This function performs AES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (16 bytes).

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[in]   Ivec        Pointer to initialization vector.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES encryption succeeded.

+  @retval FALSE  AES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesCbcEncrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  )

+{

+  AES_KEY  *AesKey;

+  UINT8    IvecBuffer[AES_BLOCK_SIZE];

+

+  ASSERT (AesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);

+  ASSERT (Ivec != NULL);

+  ASSERT (Output != NULL);

+

+  AesKey = (AES_KEY *) AesContext;

+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);

+

+  //

+  // Perform AES data encryption with CBC mode

+  //

+  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);

+

+  return TRUE;

+}

+

+/**

+  Performs AES decryption on a data buffer of the specified size in CBC mode.

+

+  This function performs AES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (16 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (16 bytes).

+  AesContext should be already correctly initialized by AesInit(). Behavior with

+  invalid AES context is undefined.

+

+  If AesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (16 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   AesContext  Pointer to the AES context.

+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize   Size of the Input buffer in bytes.

+  @param[in]   Ivec        Pointer to initialization vector.

+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.

+

+  @retval TRUE   AES decryption succeeded.

+  @retval FALSE  AES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+AesCbcDecrypt (

+  IN   VOID         *AesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  )

+{

+  AES_KEY  *AesKey;

+  UINT8    IvecBuffer[AES_BLOCK_SIZE];

+  

+  ASSERT (AesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);

+  ASSERT (Ivec != NULL);

+  ASSERT (Output != NULL);

+

+  AesKey = (AES_KEY *) AesContext;

+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);

+

+  //

+  // Perform AES data decryption with CBC mode

+  //

+  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);

+

+  return TRUE;

+}

diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c
new file mode 100644
index 0000000..fa8fd96
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c
@@ -0,0 +1,197 @@
+/** @file

+  ARC4 Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/rc4.h>

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for ARC4 operations.

+

+  @return  The size, in bytes, of the context buffer required for ARC4 operations.

+

+**/

+UINTN

+EFIAPI

+Arc4GetContextSize (

+  VOID

+  )

+{

+  //

+  // Memory for 2 copies of RC4_KEY is allocated, one for working copy, and the other

+  // for backup copy. When Arc4Reset() is called, we can use the backup copy to restore

+  // the working copy to the initial state.

+  //

+  return (UINTN) (2 * sizeof(RC4_KEY));

+}

+

+/**

+  Initializes user-supplied memory as ARC4 context for subsequent use.

+

+  This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.

+  In addtion, it sets up all ARC4 key materials for subsequent encryption and decryption

+  operations.

+

+  If Arc4Context is NULL, then ASSERT().

+  If Key is NULL, then ASSERT().

+  If KeySize does not in the range of [5, 256] bytes, then ASSERT().

+

+  @param[out]  Arc4Context  Pointer to ARC4 context being initialized.

+  @param[in]   Key          Pointer to the user-supplied ARC4 key.

+  @param[in]   KeySize      Size of ARC4 key in bytes.

+

+  @retval TRUE   ARC4 context initialization succeeded.

+  @retval FALSE  ARC4 context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Init (

+  OUT  VOID         *Arc4Context,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeySize

+  )

+{

+  RC4_KEY  *Rc4Key;

+

+  ASSERT (Arc4Context != NULL);

+  ASSERT (Key != NULL);

+  ASSERT ((KeySize >= 5) && (KeySize <= 256));

+

+  Rc4Key = (RC4_KEY *) Arc4Context;

+

+  RC4_set_key (Rc4Key, (UINT32) KeySize, Key);

+

+  CopyMem (Rc4Key +  1, Rc4Key, sizeof(RC4_KEY));

+

+  return TRUE;

+}

+

+/**

+  Performs ARC4 encryption on a data buffer of the specified size.

+

+  This function performs ARC4 encryption on data buffer pointed by Input, of specified

+  size of InputSize.

+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with

+  invalid ARC4 context is undefined.

+

+  If Arc4Context is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.

+  @param[in]       Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]       InputSize    Size of the Input buffer in bytes.

+  @param[out]      Output       Pointer to a buffer that receives the ARC4 encryption output.

+

+  @retval TRUE   ARC4 encryption succeeded.

+  @retval FALSE  ARC4 encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Encrypt (

+  IN OUT  VOID         *Arc4Context,

+  IN      CONST UINT8  *Input,

+  IN      UINTN        InputSize,

+  OUT     UINT8        *Output

+  )

+{

+  RC4_KEY  *Rc4Key;

+

+  ASSERT (Arc4Context != NULL);

+  ASSERT (Input != NULL);

+  ASSERT (Output != NULL);

+

+  Rc4Key = (RC4_KEY *) Arc4Context;

+

+  RC4 (Rc4Key, (UINT32) InputSize, Input, Output);

+

+  return TRUE;

+}

+

+/**

+  Performs ARC4 decryption on a data buffer of the specified size.

+

+  This function performs ARC4 decryption on data buffer pointed by Input, of specified

+  size of InputSize.

+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with

+  invalid ARC4 context is undefined.

+

+  If Arc4Context is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.

+  @param[in]       Input        Pointer to the buffer containing the data to be decrypted.

+  @param[in]       InputSize    Size of the Input buffer in bytes.

+  @param[out]      Output       Pointer to a buffer that receives the ARC4 decryption output.

+

+  @retval TRUE   ARC4 decryption succeeded.

+  @retval FALSE  ARC4 decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Decrypt (

+  IN OUT  VOID   *Arc4Context,

+  IN      UINT8  *Input,

+  IN      UINTN  InputSize,

+  OUT     UINT8  *Output

+  )

+{

+  RC4_KEY  *Rc4Key;

+

+  ASSERT (Arc4Context != NULL);

+  ASSERT (Input != NULL);

+  ASSERT (Output != NULL);

+

+  Rc4Key = (RC4_KEY *) Arc4Context;

+

+  RC4 (Rc4Key, (UINT32) InputSize, Input, Output);

+

+  return TRUE;

+}

+

+/**

+  Resets the ARC4 context to the initial state.

+

+  The function resets the ARC4 context to the state it had immediately after the

+  ARC4Init() function call.

+  Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context

+  should be already correctly initialized by ARC4Init().

+

+  If Arc4Context is NULL, then ASSERT().

+

+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.

+

+  @retval TRUE   ARC4 reset succeeded.

+  @retval FALSE  ARC4 reset failed.

+

+**/

+BOOLEAN

+EFIAPI

+Arc4Reset (

+  IN OUT  VOID  *Arc4Context

+  )

+{

+  RC4_KEY  *Rc4Key;

+

+  ASSERT (Arc4Context != NULL);

+

+  Rc4Key = (RC4_KEY *) Arc4Context;

+

+  CopyMem (Rc4Key, Rc4Key + 1, sizeof(RC4_KEY));

+

+  return TRUE;

+}

diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c
new file mode 100644
index 0000000..5535ab3
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c
@@ -0,0 +1,353 @@
+/** @file

+  TDES Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/des.h>

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for TDES operations.

+

+  @return  The size, in bytes, of the context buffer required for TDES operations.

+

+**/

+UINTN

+EFIAPI

+TdesGetContextSize (

+  VOID

+  )

+{

+  //

+  // Memory for 3 copies of DES_key_schedule is allocated, for K1, K2 and K3 each.

+  //

+  return (UINTN) (3 * sizeof (DES_key_schedule));

+}

+

+/**

+  Initializes user-supplied memory as TDES context for subsequent use.

+

+  This function initializes user-supplied memory pointed by TdesContext as TDES context.

+  In addtion, it sets up all TDES key materials for subsequent encryption and decryption

+  operations.

+  There are 3 key options as follows:

+  KeyLength = 64,  Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)

+  KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)

+  KeyLength = 192  Keying option 3: K1 != K2 != K3 (Strongest)

+

+  If TdesContext is NULL, then ASSERT().

+  If Key is NULL, then ASSERT().

+  If KeyLength is not valid, then ASSERT().

+

+  @param[out]  TdesContext  Pointer to TDES context being initialized.

+  @param[in]   Key          Pointer to the user-supplied TDES key.

+  @param[in]   KeyLength    Length of TDES key in bits.

+

+  @retval TRUE   TDES context initialization succeeded.

+  @retval FALSE  TDES context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesInit (

+  OUT  VOID         *TdesContext,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeyLength

+  )

+{

+  DES_key_schedule  *KeySchedule;

+

+  ASSERT (TdesContext != NULL);

+  ASSERT (Key != NULL);

+  ASSERT ((KeyLength == 64) || (KeyLength == 128) || (KeyLength == 192));

+

+  KeySchedule = (DES_key_schedule *) TdesContext;

+

+  //

+  // 

+  //

+  if (DES_is_weak_key ((const_DES_cblock *) Key)) {

+    return FALSE;

+  }

+

+  DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);

+

+  if (KeyLength == 64) {

+    CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));

+    CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));

+    return TRUE;

+  }

+

+  if (DES_is_weak_key ((const_DES_cblock *) Key + 8)) {

+    return FALSE;

+  }

+

+  DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);

+

+  if (KeyLength == 128) {

+    CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));

+    return TRUE;

+  }

+

+  if (DES_is_weak_key ((const_DES_cblock *) Key + 16)) {

+    return FALSE;

+  }

+

+  DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);

+

+  return TRUE;

+}

+

+/**

+  Performs TDES encryption on a data buffer of the specified size in ECB mode.

+

+  This function performs TDES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.

+

+  @retval TRUE   TDES encryption succeeded.

+  @retval FALSE  TDES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesEcbEncrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  )

+{

+  DES_key_schedule  *KeySchedule;

+

+  ASSERT (TdesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);

+  ASSERT (Output != NULL);

+

+  KeySchedule = (DES_key_schedule *) TdesContext;

+

+  while (InputSize > 0) {

+    DES_ecb3_encrypt (

+      (const_DES_cblock *) Input,

+      (DES_cblock *) Output,

+      KeySchedule,

+      KeySchedule + 1,

+      KeySchedule + 2,

+      DES_ENCRYPT

+      );

+    Input     += TDES_BLOCK_SIZE;

+    Output    += TDES_BLOCK_SIZE;

+    InputSize -= TDES_BLOCK_SIZE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Performs TDES decryption on a data buffer of the specified size in ECB mode.

+

+  This function performs TDES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in ECB mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[out]  Output       Pointer to a buffer that receives the TDES decryption output.

+

+  @retval TRUE   TDES decryption succeeded.

+  @retval FALSE  TDES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesEcbDecrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  OUT  UINT8        *Output

+  )

+{

+  DES_key_schedule  *KeySchedule;

+

+  ASSERT (TdesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);

+  ASSERT (Output != NULL);

+

+  KeySchedule = (DES_key_schedule *) TdesContext;

+

+  while (InputSize > 0) {

+    DES_ecb3_encrypt (

+      (const_DES_cblock *) Input,

+      (DES_cblock *) Output,

+      KeySchedule,

+      KeySchedule + 1,

+      KeySchedule + 2,

+      DES_DECRYPT

+      );

+    Input     += TDES_BLOCK_SIZE;

+    Output    += TDES_BLOCK_SIZE;

+    InputSize -= TDES_BLOCK_SIZE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Performs TDES encryption on a data buffer of the specified size in CBC mode.

+

+  This function performs TDES encryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (8 bytes).

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[in]   Ivec         Pointer to initialization vector.

+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.

+

+  @retval TRUE   TDES encryption succeeded.

+  @retval FALSE  TDES encryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesCbcEncrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  )

+{

+  DES_key_schedule  *KeySchedule;

+  UINT8             IvecBuffer[TDES_BLOCK_SIZE];

+

+  ASSERT (TdesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);

+  ASSERT (Ivec != NULL);

+  ASSERT (Output != NULL);

+

+  KeySchedule = (DES_key_schedule *) TdesContext;

+  CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);

+

+  DES_ede3_cbc_encrypt (

+    Input,

+    Output,

+    (UINT32) InputSize,

+    KeySchedule,

+    KeySchedule + 1,

+    KeySchedule + 2,

+    (DES_cblock *) IvecBuffer,

+    DES_ENCRYPT

+    );

+

+  return TRUE;

+}

+

+/**

+  Performs TDES decryption on a data buffer of the specified size in CBC mode.

+

+  This function performs TDES decryption on data buffer pointed by Input, of specified

+  size of InputSize, in CBC mode.

+  InputSize must be multiple of block size (8 bytes). This function does not perform

+  padding. Caller must perform padding, if necessary, to ensure valid input data size.

+  Initialization vector should be one block size (8 bytes).

+  TdesContext should be already correctly initialized by TdesInit(). Behavior with

+  invalid TDES context is undefined.

+

+  If TdesContext is NULL, then ASSERT().

+  If Input is NULL, then ASSERT().

+  If InputSize is not multiple of block size (8 bytes), then ASSERT().

+  If Ivec is NULL, then ASSERT().

+  If Output is NULL, then ASSERT().

+

+  @param[in]   TdesContext  Pointer to the TDES context.

+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.

+  @param[in]   InputSize    Size of the Input buffer in bytes.

+  @param[in]   Ivec         Pointer to initialization vector.

+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.

+

+  @retval TRUE   TDES decryption succeeded.

+  @retval FALSE  TDES decryption failed.

+

+**/

+BOOLEAN

+EFIAPI

+TdesCbcDecrypt (

+  IN   VOID         *TdesContext,

+  IN   CONST UINT8  *Input,

+  IN   UINTN        InputSize,

+  IN   CONST UINT8  *Ivec,

+  OUT  UINT8        *Output

+  )

+{

+  DES_key_schedule  *KeySchedule;

+  UINT8             IvecBuffer[TDES_BLOCK_SIZE];

+

+  ASSERT (TdesContext != NULL);

+  ASSERT (Input != NULL);

+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);

+  ASSERT (Ivec != NULL);

+  ASSERT (Output != NULL);

+

+  KeySchedule = (DES_key_schedule *) TdesContext;

+  CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);

+

+  DES_ede3_cbc_encrypt (

+    Input,

+    Output,

+    (UINT32) InputSize,

+    KeySchedule,

+    KeySchedule + 1,

+    KeySchedule + 2,

+    (DES_cblock *) IvecBuffer,

+    DES_DECRYPT

+    );

+

+  return TRUE;

+}

+

diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c
index 99471a0..73f3d21 100644
--- a/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c
@@ -12,10 +12,7 @@
 

 **/

 

-#include <Library/BaseLib.h>

-#include <Library/DebugLib.h>

-

-#include <Library/BaseCryptLib.h>

+#include "InternalCryptLib.h"

 #include <openssl/md5.h>

 

 

@@ -44,7 +41,7 @@
 

   If Md5Context is NULL, then ASSERT().

 

-  @param[in, out]  Md5Context  Pointer to MD5 Context being initialized.

+  @param[out]  Md5Context  Pointer to MD5 context being initialized.

 

   @retval TRUE   MD5 context initialization succeeded.

   @retval FALSE  MD5 context initialization failed.

@@ -53,7 +50,7 @@
 BOOLEAN

 EFIAPI

 Md5Init (

-  IN OUT  VOID  *Md5Context

+  OUT  VOID  *Md5Context

   )

 {

   //

@@ -67,20 +64,47 @@
   return (BOOLEAN) (MD5_Init ((MD5_CTX *)Md5Context));

 }

 

+/**

+  Makes a copy of an existing MD5 context.

+

+  If Md5Context is NULL, then ASSERT().

+  If NewMd5Context is NULL, then ASSERT().

+

+  @param[in]  Md5Context     Pointer to MD5 context being copied.

+  @param[out] NewMd5Context  Pointer to new MD5 context.

+

+  @retval TRUE   MD5 context copy succeeded.

+  @retval FALSE  MD5 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+Md5Duplicate (

+  IN   CONST VOID  *Md5Context,

+  OUT  VOID        *NewMd5Context

+  )

+{

+  CopyMem (NewMd5Context, Md5Context, sizeof (MD5_CTX));

+

+  return TRUE;

+}

 

 /**

-  Performs MD5 digest on a data buffer of the specified length. This function can

-  be called multiple times to compute the digest of long or discontinuous data streams.

+  Digests the input data and updates MD5 context.

+

+  This function performs MD5 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized

+  by Md5Final(). Behavior with invalid context is undefined.

 

   If Md5Context is NULL, then ASSERT().

 

   @param[in, out]  Md5Context  Pointer to the MD5 context.

   @param[in]       Data        Pointer to the buffer containing the data to be hashed.

-  @param[in]       DataLength  Length of Data buffer in bytes.

+  @param[in]       DataSize    Size of Data buffer in bytes.

 

   @retval TRUE   MD5 data digest succeeded.

-  @retval FALSE  Invalid MD5 context. After Md5Final function has been called, the

-                 MD5 context cannot be reused.

+  @retval FALSE  MD5 data digest failed.

 

 **/

 BOOLEAN

@@ -88,7 +112,7 @@
 Md5Update (

   IN OUT  VOID        *Md5Context,

   IN      CONST VOID  *Data,

-  IN      UINTN       DataLength

+  IN      UINTN       DataSize

   )

 {

   //

@@ -100,24 +124,28 @@
   // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL

   //

   if (Data == NULL) {

-    ASSERT (DataLength == 0);

+    ASSERT (DataSize == 0);

   }

 

   //

   // OpenSSL MD5 Hash Update

   //

-  return (BOOLEAN) (MD5_Update ((MD5_CTX *)Md5Context, Data, DataLength));

+  return (BOOLEAN) (MD5_Update ((MD5_CTX *)Md5Context, Data, DataSize));

 }

 

-

 /**

-  Completes MD5 hash computation and retrieves the digest value into the specified

-  memory. After this function has been called, the MD5 context cannot be used again.

+  Completes computation of the MD5 digest value.

+

+  This function completes MD5 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the MD5 context cannot

+  be used again.

+  MD5 context should be already correctly intialized by Md5Init(), and should not be

+  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.

 

   If Md5Context is NULL, then ASSERT().

   If HashValue is NULL, then ASSERT().

 

-  @param[in, out]  Md5Context  Pointer to the MD5 context

+  @param[in, out]  Md5Context  Pointer to the MD5 context.

   @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest

                                value (16 bytes).

 

diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c
index d774059..9a317ec 100644
--- a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c
@@ -12,10 +12,7 @@
 

 **/

 

-#include <Library/BaseLib.h>

-#include <Library/DebugLib.h>

-

-#include <Library/BaseCryptLib.h>

+#include "InternalCryptLib.h"

 #include <openssl/sha.h>

 

 

@@ -37,23 +34,22 @@
   return (UINTN)(sizeof (SHA_CTX));

 }

 

-

 /**

-  Initializes user-supplied memory pointed by Sha1Context as the SHA-1 hash context for

+  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for

   subsequent use.

 

   If Sha1Context is NULL, then ASSERT().

 

-  @param[in, out]  Sha1Context  Pointer to the SHA-1 Context being initialized.

+  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.

 

-  @retval TRUE   SHA-1 initialization succeeded.

-  @retval FALSE  SHA-1 initialization failed.

+  @retval TRUE   SHA-1 context initialization succeeded.

+  @retval FALSE  SHA-1 context initialization failed.

 

 **/

 BOOLEAN

 EFIAPI

 Sha1Init (

-  IN OUT  VOID  *Sha1Context

+  OUT  VOID  *Sha1Context

   )

 {

   //

@@ -67,20 +63,47 @@
   return (BOOLEAN) (SHA1_Init ((SHA_CTX *)Sha1Context));

 }

 

+/**

+  Makes a copy of an existing SHA-1 context.

+

+  If Sha1Context is NULL, then ASSERT().

+  If NewSha1Context is NULL, then ASSERT().

+

+  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.

+  @param[out] NewSha1Context  Pointer to new SHA-1 context.

+

+  @retval TRUE   SHA-1 context copy succeeded.

+  @retval FALSE  SHA-1 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+Sha1Duplicate (

+  IN   CONST VOID  *Sha1Context,

+  OUT  VOID        *NewSha1Context

+  )

+{

+  CopyMem (NewSha1Context, Sha1Context, sizeof (SHA_CTX));

+

+  return TRUE;

+}

 

 /**

-  Performs SHA-1 digest on a data buffer of the specified length. This function can

-  be called multiple times to compute the digest of long or discontinuous data streams.

+  Digests the input data and updates SHA-1 context.

+

+  This function performs SHA-1 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be finalized

+  by Sha1Final(). Behavior with invalid context is undefined.

 

   If Sha1Context is NULL, then ASSERT().

 

   @param[in, out]  Sha1Context  Pointer to the SHA-1 context.

   @param[in]       Data         Pointer to the buffer containing the data to be hashed.

-  @param[in]       DataLength   Length of Data buffer in bytes.

+  @param[in]       DataSize     Size of Data buffer in bytes.

 

   @retval TRUE   SHA-1 data digest succeeded.

-  @retval FALSE  Invalid SHA-1 context. After Sha1Final function has been called, the

-                 SHA-1 context cannot be reused.

+  @retval FALSE  SHA-1 data digest failed.

 

 **/

 BOOLEAN

@@ -88,7 +111,7 @@
 Sha1Update (

   IN OUT  VOID        *Sha1Context,

   IN      CONST VOID  *Data,

-  IN      UINTN       DataLength

+  IN      UINTN       DataSize

   )

 {

   //

@@ -100,24 +123,28 @@
   // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL

   //

   if (Data == NULL) {

-    ASSERT (DataLength == 0);

+    ASSERT (DataSize == 0);

   }

 

   //

   // OpenSSL SHA-1 Hash Update

   //

-  return (BOOLEAN) (SHA1_Update ((SHA_CTX *)Sha1Context, Data, DataLength));

+  return (BOOLEAN) (SHA1_Update ((SHA_CTX *)Sha1Context, Data, DataSize));

 }

 

-

 /**

-  Completes SHA-1 hash computation and retrieves the digest value into the specified

-  memory. After this function has been called, the SHA-1 context cannot be used again.

+  Completes computation of the SHA-1 digest value.

+

+  This function completes SHA-1 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the SHA-1 context cannot

+  be used again.

+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be

+  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.

 

   If Sha1Context is NULL, then ASSERT().

   If HashValue is NULL, then ASSERT().

 

-  @param[in, out]  Sha1Context  Pointer to the SHA-1 context

+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.

   @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest

                                 value (20 bytes).

 

diff --git a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c
index 9b566a4..7e6c6c6 100644
--- a/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c
+++ b/CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c
@@ -12,17 +12,13 @@
 

 **/

 

-#include <Library/BaseLib.h>

-#include <Library/DebugLib.h>

-

-#include <Library/BaseCryptLib.h>

+#include "InternalCryptLib.h"

 #include <openssl/sha.h>

 

-

 /**

-  Retrieves the size, in bytes, of the context buffer required for SHA-256 operations.

+  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.

 

-  @return  The size, in bytes, of the context buffer required for SHA-256 operations.

+  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.

 

 **/

 UINTN

@@ -37,14 +33,13 @@
   return (UINTN)(sizeof (SHA256_CTX));

 }

 

-

 /**

   Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for

   subsequent use.

 

   If Sha256Context is NULL, then ASSERT().

 

-  @param[in, out]  Sha256Context  Pointer to SHA-256 Context being initialized.

+  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.

 

   @retval TRUE   SHA-256 context initialization succeeded.

   @retval FALSE  SHA-256 context initialization failed.

@@ -53,7 +48,7 @@
 BOOLEAN

 EFIAPI

 Sha256Init (

-  IN OUT  VOID  *Sha256Context

+  OUT  VOID  *Sha256Context

   )

 {

   //

@@ -67,20 +62,47 @@
   return (BOOLEAN) (SHA256_Init ((SHA256_CTX *)Sha256Context));

 }

 

+/**

+  Makes a copy of an existing SHA-256 context.

+

+  If Sha256Context is NULL, then ASSERT().

+  If NewSha256Context is NULL, then ASSERT().

+

+  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.

+  @param[out] NewSha256Context  Pointer to new SHA-256 context.

+

+  @retval TRUE   SHA-256 context copy succeeded.

+  @retval FALSE  SHA-256 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+Sha256Duplicate (

+  IN   CONST VOID  *Sha256Context,

+  OUT  VOID        *NewSha256Context

+  )

+{

+  CopyMem (NewSha256Context, Sha256Context, sizeof (SHA256_CTX));

+

+  return TRUE;

+}

 

 /**

-  Performs SHA-256 digest on a data buffer of the specified length. This function can

-  be called multiple times to compute the digest of long or discontinuous data streams.

+  Digests the input data and updates SHA-256 context.

+

+  This function performs SHA-256 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be finalized

+  by Sha256Final(). Behavior with invalid context is undefined.

 

   If Sha256Context is NULL, then ASSERT().

 

   @param[in, out]  Sha256Context  Pointer to the SHA-256 context.

   @param[in]       Data           Pointer to the buffer containing the data to be hashed.

-  @param[in]       DataLength     Length of Data buffer in bytes.

+  @param[in]       DataSize       Size of Data buffer in bytes.

 

   @retval TRUE   SHA-256 data digest succeeded.

-  @retval FALSE  Invalid SHA-256 context. After Sha256Final function has been called, the

-                 SHA-256 context cannot be reused.

+  @retval FALSE  SHA-256 data digest failed.

 

 **/

 BOOLEAN

@@ -88,7 +110,7 @@
 Sha256Update (

   IN OUT  VOID        *Sha256Context,

   IN      CONST VOID  *Data,

-  IN      UINTN       DataLength

+  IN      UINTN       DataSize

   )

 {

   //

@@ -100,24 +122,28 @@
   // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL

   //

   if (Data == NULL) {

-    ASSERT (DataLength == 0);

+    ASSERT (DataSize == 0);

   }

 

   //

   // OpenSSL SHA-256 Hash Update

   //

-  return (BOOLEAN) (SHA256_Update ((SHA256_CTX *)Sha256Context, Data, DataLength));

+  return (BOOLEAN) (SHA256_Update ((SHA256_CTX *)Sha256Context, Data, DataSize));

 }

 

-

 /**

-  Completes SHA-256 hash computation and retrieves the digest value into the specified

-  memory. After this function has been called, the SHA-256 context cannot be used again.

+  Completes computation of the SHA-256 digest value.

+

+  This function completes SHA-256 hash computation and retrieves the digest value into

+  the specified memory. After this function has been called, the SHA-256 context cannot

+  be used again.

+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be

+  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.

 

   If Sha256Context is NULL, then ASSERT().

   If HashValue is NULL, then ASSERT().

 

-  @param[in, out]  Sha256Context  Pointer to SHA-256 context

+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.

   @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest

                                   value (32 bytes).

 

diff --git a/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c b/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c
new file mode 100644
index 0000000..1eff5c4
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c
@@ -0,0 +1,185 @@
+/** @file

+  HMAC-MD5 Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/hmac.h>

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.

+

+  @return  The size, in bytes, of the context buffer required for HMAC-MD5 operations.

+

+**/

+UINTN

+EFIAPI

+HmacMd5GetContextSize (

+  VOID

+  )

+{

+  //

+  // Retrieves the OpenSSL HMAC-MD5 Context Size

+  //

+  return (UINTN)(sizeof (HMAC_CTX));

+}

+

+/**

+  Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for

+  subsequent use.

+

+  If HmacMd5Context is NULL, then ASSERT().

+

+  @param[out]  HmacMd5Context  Pointer to HMAC-MD5 context being initialized.

+  @param[in]   Key             Pointer to the user-supplied key.

+  @param[in]   KeySize         Key size in bytes.

+

+  @retval TRUE   HMAC-MD5 context initialization succeeded.

+  @retval FALSE  HMAC-MD5 context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Init (

+  OUT  VOID         *HmacMd5Context,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeySize

+  )

+{

+  //

+  // ASSERT if HmacMd5Context is NULL.

+  //

+  ASSERT (HmacMd5Context != NULL);

+

+  //

+  // OpenSSL HMAC-MD5 Context Initialization

+  //

+  HMAC_CTX_init (HmacMd5Context);

+  HMAC_Init_ex (HmacMd5Context, Key, (UINT32) KeySize, EVP_md5(), NULL);

+

+  return TRUE;

+}

+

+/**

+  Makes a copy of an existing HMAC-MD5 context.

+

+  If HmacMd5Context is NULL, then ASSERT().

+  If NewHmacMd5Context is NULL, then ASSERT().

+

+  @param[in]  HmacMd5Context     Pointer to HMAC-MD5 context being copied.

+  @param[out] NewHmacMd5Context  Pointer to new HMAC-MD5 context.

+

+  @retval TRUE   HMAC-MD5 context copy succeeded.

+  @retval FALSE  HMAC-MD5 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Duplicate (

+  IN   CONST VOID  *HmacMd5Context,

+  OUT  VOID        *NewHmacMd5Context

+  )

+{

+  CopyMem (NewHmacMd5Context, HmacMd5Context, sizeof (HMAC_CTX));

+

+  return TRUE;

+}

+

+/**

+  Digests the input data and updates HMAC-MD5 context.

+

+  This function performs HMAC-MD5 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be

+  finalized by HmacMd5Final(). Behavior with invalid context is undefined.

+

+  If HmacMd5Context is NULL, then ASSERT().

+

+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.

+  @param[in]       Data            Pointer to the buffer containing the data to be digested.

+  @param[in]       DataSize        Size of Data buffer in bytes.

+

+  @retval TRUE   HMAC-MD5 data digest succeeded.

+  @retval FALSE  HMAC-MD5 data digest failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Update (

+  IN OUT  VOID        *HmacMd5Context,

+  IN      CONST VOID  *Data,

+  IN      UINTN       DataSize

+  )

+{

+  //

+  // ASSERT if HmacMd5Context is NULL

+  //

+  ASSERT (HmacMd5Context != NULL);

+

+  //

+  // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL

+  //

+  if (Data == NULL) {

+    ASSERT (DataSize == 0);

+  }

+

+  //

+  // OpenSSL HMAC-MD5 digest update

+  //

+  HMAC_Update (HmacMd5Context, Data, DataSize);

+

+  return TRUE;

+}

+

+/**

+  Completes computation of the HMAC-MD5 digest value.

+

+  This function completes HMAC-MD5 digest computation and retrieves the digest value into

+  the specified memory. After this function has been called, the HMAC-MD5 context cannot

+  be used again.

+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be

+  finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.

+

+  If HmacMd5Context is NULL, then ASSERT().

+  If HmacValue is NULL, then ASSERT().

+

+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.

+  @param[out]      HmacValue       Pointer to a buffer that receives the HMAC-MD5 digest

+                                   value (16 bytes).

+

+  @retval TRUE   HMAC-MD5 digest computation succeeded.

+  @retval FALSE  HMAC-MD5 digest computation failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacMd5Final (

+  IN OUT  VOID   *HmacMd5Context,

+  OUT     UINT8  *HmacValue

+  )

+{

+  UINT32  Length;

+

+  //

+  // ASSERT if HmacMd5Context is NULL or HmacValue is NULL

+  //

+  ASSERT (HmacMd5Context != NULL);

+  ASSERT (HmacValue != NULL);

+

+  //

+  // OpenSSL HMAC-MD5 digest finalization

+  //

+  HMAC_Final (HmacMd5Context, HmacValue, &Length);

+  HMAC_CTX_cleanup (HmacMd5Context);

+

+  return TRUE;

+}

diff --git a/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c b/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c
new file mode 100644
index 0000000..0298b80
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c
@@ -0,0 +1,185 @@
+/** @file

+  HMAC-SHA1 Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/hmac.h>

+

+/**

+  Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.

+

+  @return  The size, in bytes, of the context buffer required for HMAC-SHA1 operations.

+

+**/

+UINTN

+EFIAPI

+HmacSha1GetContextSize (

+  VOID

+  )

+{

+  //

+  // Retrieves the OpenSSL HMAC-SHA1 Context Size

+  //

+  return (UINTN)(sizeof (HMAC_CTX));

+}

+

+/**

+  Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for

+  subsequent use.

+

+  If HmacSha1Context is NULL, then ASSERT().

+

+  @param[out]  HmacSha1Context  Pointer to HMAC-SHA1 context being initialized.

+  @param[in]   Key              Pointer to the user-supplied key.

+  @param[in]   KeySize          Key size in bytes.

+

+  @retval TRUE   HMAC-SHA1 context initialization succeeded.

+  @retval FALSE  HMAC-SHA1 context initialization failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Init (

+  OUT  VOID         *HmacSha1Context,

+  IN   CONST UINT8  *Key,

+  IN   UINTN        KeySize

+  )

+{

+  //

+  // ASSERT if HmacSha1Context is NULL.

+  //

+  ASSERT (HmacSha1Context != NULL);

+

+  //

+  // OpenSSL HMAC-SHA1 Context Initialization

+  //

+  HMAC_CTX_init (HmacSha1Context);

+  HMAC_Init_ex (HmacSha1Context, Key, (UINT32) KeySize, EVP_sha1(), NULL);

+

+  return TRUE;

+}

+

+/**

+  Makes a copy of an existing HMAC-SHA1 context.

+

+  If HmacSha1Context is NULL, then ASSERT().

+  If NewHmacSha1Context is NULL, then ASSERT().

+

+  @param[in]  HmacSha1Context     Pointer to HMAC-SHA1 context being copied.

+  @param[out] NewHmacSha1Context  Pointer to new HMAC-SHA1 context.

+

+  @retval TRUE   HMAC-SHA1 context copy succeeded.

+  @retval FALSE  HMAC-SHA1 context copy failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Duplicate (

+  IN   CONST VOID  *HmacSha1Context,

+  OUT  VOID        *NewHmacSha1Context

+  )

+{

+  CopyMem (NewHmacSha1Context, HmacSha1Context, sizeof (HMAC_CTX));

+

+  return TRUE;

+}

+

+/**

+  Digests the input data and updates HMAC-SHA1 context.

+

+  This function performs HMAC-SHA1 digest on a data buffer of the specified size.

+  It can be called multiple times to compute the digest of long or discontinuous data streams.

+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not

+  be finalized by HmacSha1Final(). Behavior with invalid context is undefined.

+

+  If HmacSha1Context is NULL, then ASSERT().

+

+  @param[in, out]  HmacSha1Context Pointer to the HMAC-SHA1 context.

+  @param[in]       Data            Pointer to the buffer containing the data to be digested.

+  @param[in]       DataSize        Size of Data buffer in bytes.

+

+  @retval TRUE   HMAC-SHA1 data digest succeeded.

+  @retval FALSE  HMAC-SHA1 data digest failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Update (

+  IN OUT  VOID        *HmacSha1Context,

+  IN      CONST VOID  *Data,

+  IN      UINTN       DataSize

+  )

+{

+  //

+  // ASSERT if HmacSha1Context is NULL

+  //

+  ASSERT (HmacSha1Context != NULL);

+

+  //

+  // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL

+  //

+  if (Data == NULL) {

+    ASSERT (DataSize == 0);

+  }

+

+  //

+  // OpenSSL HMAC-SHA1 digest update

+  //

+  HMAC_Update (HmacSha1Context, Data, DataSize);

+

+  return TRUE;

+}

+

+/**

+  Completes computation of the HMAC-SHA1 digest value.

+

+  This function completes HMAC-SHA1 digest computation and retrieves the digest value into

+  the specified memory. After this function has been called, the HMAC-SHA1 context cannot

+  be used again.

+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should

+  not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.

+

+  If HmacSha1Context is NULL, then ASSERT().

+  If HmacValue is NULL, then ASSERT().

+

+  @param[in, out]  HmacSha1Context  Pointer to the HMAC-SHA1 context.

+  @param[out]      HmacValue        Pointer to a buffer that receives the HMAC-SHA1 digest

+                                    value (20 bytes).

+

+  @retval TRUE   HMAC-SHA1 digest computation succeeded.

+  @retval FALSE  HMAC-SHA1 digest computation failed.

+

+**/

+BOOLEAN

+EFIAPI

+HmacSha1Final (

+  IN OUT  VOID   *HmacSha1Context,

+  OUT     UINT8  *HmacValue

+  )

+{

+  UINT32  Length;

+

+  //

+  // ASSERT if HmacSha1Context is NULL or HmacValue is NULL

+  //

+  ASSERT (HmacSha1Context != NULL);

+  ASSERT (HmacValue != NULL);

+

+  //

+  // OpenSSL HMAC-SHA1 digest finalization

+  //

+  HMAC_Final (HmacSha1Context, HmacValue, &Length);

+  HMAC_CTX_cleanup (HmacSha1Context);

+

+  return TRUE;

+}

diff --git a/CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h b/CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h
new file mode 100644
index 0000000..6a898a8
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h
@@ -0,0 +1,32 @@
+/** @file  

+  Internal include file for BaseCryptLib.

+

+Copyright (c) 2010, 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.

+

+**/

+

+#ifndef __INTERNAL_CRYPT_LIB_H__

+#define __INTERNAL_CRYPT_LIB_H__

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseCryptLib.h>

+

+//

+// Environment Setting for OpenSSL-based UEFI Crypto Library.

+//

+#ifndef OPENSSL_SYSNAME_UWIN

+#define OPENSSL_SYSNAME_UWIN

+#endif

+

+#endif

+

diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index 30061a6..14a2b19 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -55,8 +55,6 @@
   SysCall/Ia32/MathLShiftS64.S      | GCC

   SysCall/Ia32/MathRShiftU64.S      | GCC

 

-  SysCall/Ia32/Alloca.S             | GCC

-

 [Packages]

   MdePkg/MdePkg.dec

   CryptoPkg/CryptoPkg.dec

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c
new file mode 100644
index 0000000..b7e164c
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c
@@ -0,0 +1,238 @@
+/** @file

+  Diffie-Hellman Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/dh.h>

+

+

+/**

+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.

+

+  @return  Pointer to the Diffie-Hellman Context that has been initialized.

+           If the allocations fails, DhNew() returns NULL.

+

+**/

+VOID *

+EFIAPI

+DhNew (

+  VOID

+  )

+{

+  //

+  // Allocates & Initializes DH Context by OpenSSL DH_new()

+  //

+  return (VOID *)DH_new ();

+}

+

+/**

+  Release the specified DH context.

+

+  If DhContext is NULL, then ASSERT().

+

+  @param[in]  DhContext  Pointer to the DH context to be released.

+

+**/

+VOID

+EFIAPI

+DhFree (

+  IN  VOID  *DhContext

+  )

+{

+  //

+  // Free OpenSSL DH Context

+  //

+  DH_free ((DH *)DhContext);

+}

+

+/**

+  Generates DH parameter.

+

+  Given generator g, and length of prime number p in bits, this function generates p,

+  and sets DH context according to value of g and p.

+  

+  Before this function can be invoked, pseudorandom number generator must be correctly

+  initialized by RandomSeed().

+

+  If DhContext is NULL, then ASSERT().

+  If Prime is NULL, then ASSERT().

+

+  @param[in, out]  DhContext    Pointer to the DH context.

+  @param[in]       Generator    Value of generator.

+  @param[in]       PrimeLength  Length in bits of prime to be generated.

+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.

+

+  @retval TRUE   DH pamameter generation succeeded.

+  @retval FALSE  Value of Generator is not supported.

+  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.

+

+**/

+BOOLEAN

+EFIAPI

+DhGenerateParameter (

+  IN OUT  VOID   *DhContext,

+  IN      UINTN  Generator,

+  IN      UINTN  PrimeLength,

+  OUT     UINT8  *Prime

+  )

+{

+  BOOLEAN RetVal;

+

+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {

+    return FALSE;

+  }

+

+  RetVal = (BOOLEAN) DH_generate_parameters_ex (DhContext, (UINT32) PrimeLength, (UINT32) Generator, NULL);

+  if (!RetVal) {

+    return FALSE;

+  }

+

+  BN_bn2bin (((DH *) DhContext)->p, Prime);

+

+  return TRUE;

+}

+

+/**

+  Sets generator and prime parameters for DH.

+

+  Given generator g, and prime number p, this function and sets DH

+  context accordingly.

+

+  If DhContext is NULL, then ASSERT().

+  If Prime is NULL, then ASSERT().

+

+  @param[in, out]  DhContext    Pointer to the DH context.

+  @param[in]       Generator    Value of generator.

+  @param[in]       PrimeLength  Length in bits of prime to be generated.

+  @param[in]       Prime        Pointer to the prime number.

+

+  @retval TRUE   DH pamameter setting succeeded.

+  @retval FALSE  Value of Generator is not supported.

+  @retval FALSE  Value of Generator is not suitable for the Prime.

+  @retval FALSE  Value of Prime is not a prime number.

+  @retval FALSE  Value of Prime is not a safe prime number.

+

+**/

+BOOLEAN

+EFIAPI

+DhSetParameter (

+  IN OUT  VOID         *DhContext,

+  IN      UINTN        Generator,

+  IN      UINTN        PrimeLength,

+  IN      CONST UINT8  *Prime

+  )

+{

+  DH  *Dh;

+

+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {

+    return FALSE;

+  }

+

+  Dh = (DH *) DhContext;

+  Dh->p = BN_new();

+  Dh->g = BN_new();

+

+  BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p);

+  BN_set_word (Dh->g, (UINT32) Generator);

+

+  return TRUE;

+}

+

+/**

+  Generates DH public key.

+

+  This function generates random secret exponent, and computes the public key, which is 

+  returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.

+  If the PublicKey buffer is too small to hold the public key, FALSE is returned and

+  PublicKeySize is set to the required buffer size to obtain the public key.

+

+  If DhContext is NULL, then ASSERT().

+  If PublicKeySize is NULL, then ASSERT().

+  If PublicKeySize is large enough but PublicKey is NULL, then ASSERT().

+

+  @param[in, out]  DhContext      Pointer to the DH context.

+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.

+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.

+                                  On output, the size of data returned in PublicKey buffer in bytes.

+

+  @retval TRUE   DH public key generation succeeded.

+  @retval FALSE  DH public key generation failed.

+  @retval FALSE  PublicKeySize is not large enough.

+

+**/

+BOOLEAN

+EFIAPI

+DhGenerateKey (

+  IN OUT  VOID   *DhContext,

+  OUT     UINT8  *PublicKey,

+  IN OUT  UINTN  *PublicKeySize

+  )

+{

+  BOOLEAN RetVal;

+  DH      *Dh;

+

+  Dh = (DH *) DhContext;

+  *PublicKeySize = 0;

+

+  RetVal = (BOOLEAN) DH_generate_key (DhContext);

+  if (RetVal) {

+    BN_bn2bin (Dh->pub_key, PublicKey);

+    *PublicKeySize  = BN_num_bytes (Dh->pub_key);

+  }

+

+  return RetVal;

+}

+

+/**

+  Computes exchanged common key.

+

+  Given peer's public key, this function computes the exchanged common key, based on its own

+  context including value of prime modulus and random secret exponent. 

+

+  If DhContext is NULL, then ASSERT().

+  If PeerPublicKey is NULL, then ASSERT().

+  If KeySize is NULL, then ASSERT().

+  If KeySize is large enough but Key is NULL, then ASSERT().

+

+  @param[in, out]  DhContext          Pointer to the DH context.

+  @param[in]       PeerPublicKey      Pointer to the peer's public key.

+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.

+  @param[out]      Key                Pointer to the buffer to receive generated key.

+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.

+                                      On output, the size of data returned in Key buffer in bytes.

+

+  @retval TRUE   DH exchanged key generation succeeded.

+  @retval FALSE  DH exchanged key generation failed.

+  @retval FALSE  KeySize is not large enough.

+

+**/

+BOOLEAN

+EFIAPI

+DhComputeKey (

+  IN OUT  VOID         *DhContext,

+  IN      CONST UINT8  *PeerPublicKey,

+  IN      UINTN        PeerPublicKeySize,

+  OUT     UINT8        *Key,

+  IN OUT  UINTN        *KeySize

+  )

+{

+  BIGNUM  *Bn;

+

+  Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL);

+

+  *KeySize = (BOOLEAN) DH_compute_key (Key, Bn, DhContext);

+

+  BN_free (Bn);

+

+  return TRUE;

+}

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c
index d0a6ea5..ca0dd4f 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c
@@ -12,11 +12,8 @@
 

 **/

 

-#include <Library/BaseLib.h>

-#include <Library/BaseMemoryLib.h>

-#include <Library/DebugLib.h>

+#include "InternalCryptLib.h"

 

-#include <Library/BaseCryptLib.h>

 #include <openssl/objects.h>

 #include <openssl/x509.h>

 #include <openssl/pkcs7.h>

@@ -36,8 +33,8 @@
   @param[in]  InData       Pointer to the content to be verified.

   @param[in]  DataLength   Length of InData in bytes.

 

-  @return  TRUE  The specified PKCS#7 signed data is valid.

-  @return  FALSE Invalid PKCS#7 signed data.

+  @retval  TRUE  The specified PKCS#7 signed data is valid.

+  @retval  FALSE Invalid PKCS#7 signed data.

 

 **/

 BOOLEAN

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c
index 763213a..2e84a2f 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c
@@ -12,18 +12,36 @@
 

 **/

 

-#include <Library/BaseLib.h>

-#include <Library/DebugLib.h>

-#include <Library/BaseMemoryLib.h>

+#include "InternalCryptLib.h"

 

-#include <Library/BaseCryptLib.h>

 #include <openssl/rsa.h>

+#include <openssl/err.h>

+

+//

+// ASN.1 value for Hash Algorithm ID with the Distringuished Encoding Rules (DER)

+// Refer to Section 9.2 of PKCS#1 v2.1

+//                           

+CONST UINT8  Asn1IdMd5[] = {

+  0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,

+  0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10

+  };

+

+CONST UINT8  Asn1IdSha1[] = {

+  0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,

+  0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14

+  };

+

+CONST UINT8  Asn1IdSha256[] = {

+  0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,

+  0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,

+  0x00, 0x04, 0x20

+  };

 

 

 /**

-  Allocates and Initializes one RSA Context for subsequent use.

+  Allocates and initializes one RSA context for subsequent use.

 

-  @return  Pointer to the RSA Context that has been initialized.

+  @return  Pointer to the RSA context that has been initialized.

            If the allocations fails, RsaNew() returns NULL.

 

 **/

@@ -39,9 +57,10 @@
   return (VOID *)RSA_new ();

 }

 

-

 /**

-  Release the specified RSA Context.

+  Release the specified RSA context.

+

+  If RsaContext is NULL, then ASSERT().

 

   @param[in]  RsaContext  Pointer to the RSA context to be released.

 

@@ -52,36 +71,43 @@
   IN  VOID  *RsaContext

   )

 {

+  ASSERT (RsaContext != NULL);

+

   //

   // Free OpenSSL RSA Context

   //

   RSA_free ((RSA *)RsaContext);

 }

 

-

 /**

-  Sets the tag-designated RSA key component into the established RSA context from

-  the user-specified nonnegative integer (octet string format represented in RSA

-  PKCS#1).

+  Sets the tag-designated key component into the established RSA context.

+

+  This function sets the tag-designated RSA key component into the established

+  RSA context from the user-specified non-negative integer (octet string format

+  represented in RSA PKCS#1).

+  If BigNumber is NULL, then the specified key componenet in RSA context is cleared.

 

   If RsaContext is NULL, then ASSERT().

 

   @param[in, out]  RsaContext  Pointer to RSA context being set.

   @param[in]       KeyTag      Tag of RSA key component being set.

   @param[in]       BigNumber   Pointer to octet integer buffer.

-  @param[in]       BnLength    Length of big number buffer in bytes.

+                               If NULL, then the specified key componenet in RSA

+                               context is cleared.

+  @param[in]       BnSize      Size of big number buffer in bytes.

+                               If BigNumber is NULL, then it is ignored.

 

-  @return  TRUE   RSA key component was set successfully.

-  @return  FALSE  Invalid RSA key component tag.

+  @retval  TRUE   RSA key component was set successfully.

+  @retval  FALSE  Invalid RSA key component tag.

 

 **/

 BOOLEAN

 EFIAPI

 RsaSetKey (

-  IN OUT VOID         *RsaContext,

-  IN     RSA_KEY_TAG  KeyTag,

-  IN     CONST UINT8  *BigNumber,

-  IN     UINTN        BnLength

+  IN OUT  VOID         *RsaContext,

+  IN      RSA_KEY_TAG  KeyTag,

+  IN      CONST UINT8  *BigNumber,

+  IN      UINTN        BnSize

   )

 {

   RSA  *RsaKey;

@@ -107,7 +133,11 @@
     if (RsaKey->n != NULL) {

       BN_free (RsaKey->n);

     }

-    RsaKey->n = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->n);

+    RsaKey->n = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n);

     break;

 

   //

@@ -117,7 +147,11 @@
     if (RsaKey->e != NULL) {

       BN_free (RsaKey->e);

     }

-    RsaKey->e = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->e);

+    RsaKey->e = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e);

     break;

 

   //

@@ -127,7 +161,11 @@
     if (RsaKey->d != NULL) {

       BN_free (RsaKey->d);

     }

-    RsaKey->d = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->d);

+    RsaKey->d = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d);

     break;

 

   //

@@ -137,7 +175,11 @@
     if (RsaKey->p != NULL) {

       BN_free (RsaKey->p);

     }

-    RsaKey->p = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->p);

+    RsaKey->p = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p);

     break;

 

   //

@@ -147,7 +189,11 @@
     if (RsaKey->q != NULL) {

       BN_free (RsaKey->q);

     }

-    RsaKey->q = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->q);

+    RsaKey->q = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q);

     break;

 

   //

@@ -157,7 +203,11 @@
     if (RsaKey->dmp1 != NULL) {

       BN_free (RsaKey->dmp1);

     }

-    RsaKey->dmp1 = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->dmp1);

+    RsaKey->dmp1 = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1);

     break;

 

   //

@@ -167,7 +217,11 @@
     if (RsaKey->dmq1 != NULL) {

       BN_free (RsaKey->dmq1);

     }

-    RsaKey->dmq1 = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->dmq1);

+    RsaKey->dmq1 = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1);

     break;

 

   //

@@ -177,7 +231,11 @@
     if (RsaKey->iqmp != NULL) {

       BN_free (RsaKey->iqmp);

     }

-    RsaKey->iqmp = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->iqmp);

+    RsaKey->iqmp = NULL;

+    if (BigNumber == NULL) {

+      break;

+    }

+    RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp);

     break;

 

   default:

@@ -187,6 +245,368 @@
   return TRUE;

 }

 

+/**

+  Gets the tag-designated RSA key component from the established RSA context.

+

+  This function retrieves the tag-designated RSA key component from the

+  established RSA context as a non-negative integer (octet string format

+  represented in RSA PKCS#1).

+  If specified key component has not been set or has been cleared, then returned

+  BnSize is set to 0.

+  If the BigNumber buffer is too small to hold the contents of the key, FALSE

+  is returned and BnSize is set to the required buffer size to obtain the key.

+

+  If RsaContext is NULL, then ASSERT().

+  If BnSize is NULL, then ASSERT().

+  If BnSize is large enough but BigNumber is NULL, then ASSERT().

+

+  @param[in, out]  RsaContext  Pointer to RSA context being set.

+  @param[in]       KeyTag      Tag of RSA key component being set.

+  @param[out]      BigNumber   Pointer to octet integer buffer.

+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.

+                               On output, the size of data returned in big number buffer in bytes.

+

+  @retval  TRUE   RSA key component was retrieved successfully.

+  @retval  FALSE  Invalid RSA key component tag.

+  @retval  FALSE  BnSize is too small.

+

+**/

+BOOLEAN

+EFIAPI

+RsaGetKey (

+  IN OUT  VOID         *RsaContext,

+  IN      RSA_KEY_TAG  KeyTag,

+  OUT     UINT8        *BigNumber,

+  IN OUT  UINTN        *BnSize

+  )

+{

+  RSA    *RsaKey;

+  BIGNUM *BnKey;

+  UINTN  Size;

+

+  ASSERT (RsaContext != NULL);

+  ASSERT (BnSize != NULL);

+

+  RsaKey  = (RSA *) RsaContext;

+  Size    = *BnSize;

+  *BnSize = 0;

+

+  switch (KeyTag) {

+

+  //

+  // RSA Public Modulus (N)

+  //

+  case RsaKeyN:

+    if (RsaKey->n == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->n;

+    break;

+

+  //

+  // RSA Public Exponent (e)

+  //

+  case RsaKeyE:

+    if (RsaKey->e == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->e;

+    break;

+

+  //

+  // RSA Private Exponent (d)

+  //

+  case RsaKeyD:

+    if (RsaKey->d == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->d;

+    break;

+

+  //

+  // RSA Secret Prime Factor of Modulus (p)

+  //

+  case RsaKeyP:

+    if (RsaKey->p == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->p;

+    break;

+

+  //

+  // RSA Secret Prime Factor of Modules (q)

+  //

+  case RsaKeyQ:

+    if (RsaKey->q == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->q;

+    break;

+

+  //

+  // p's CRT Exponent (== d mod (p - 1))

+  //

+  case RsaKeyDp:

+    if (RsaKey->dmp1 == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->dmp1;

+    break;

+

+  //

+  // q's CRT Exponent (== d mod (q - 1))

+  //

+  case RsaKeyDq:

+    if (RsaKey->dmq1 == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->dmq1;

+    break;

+

+  //

+  // The CRT Coefficient (== 1/q mod p)

+  //

+  case RsaKeyQInv:

+    if (RsaKey->iqmp == NULL) {

+      return TRUE;

+    }

+    BnKey = RsaKey->iqmp;

+    break;

+

+  default:

+    return FALSE;

+  }

+

+  *BnSize = Size;

+  Size    = BN_num_bytes (BnKey);

+

+  if (*BnSize < Size) {

+    *BnSize = Size;

+    return FALSE;

+  }

+

+  ASSERT (BigNumber != NULL);

+  *BnSize = BN_bn2bin (BnKey, BigNumber) ;

+  

+  return TRUE;

+}

+

+/**

+  Generates RSA key components.

+

+  This function generates RSA key components. It takes RSA public exponent E and

+  length in bits of RSA modulus N as input, and generates all key components.

+  If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.

+

+  Before this function can be invoked, pseudorandom number generator must be correctly

+  initialized by RandomSeed().

+

+  If RsaContext is NULL, then ASSERT().

+

+  @param[in, out]  RsaContext           Pointer to RSA context being set.

+  @param[in]       ModulusLength        Length of RSA modulus N in bits.

+  @param[in]       PublicExponent       Pointer to RSA public exponent.

+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes. 

+

+  @retval  TRUE   RSA key component was generated successfully.

+  @retval  FALSE  Invalid RSA key component tag.

+

+**/

+BOOLEAN

+EFIAPI

+RsaGenerateKey (

+  IN OUT  VOID         *RsaContext,

+  IN      UINTN        ModulusLength,

+  IN      CONST UINT8  *PublicExponent,

+  IN      UINTN        PublicExponentSize

+  )

+{

+  BIGNUM   *KeyE;

+  BOOLEAN  RetVal;

+

+  ASSERT (RsaContext != NULL);

+

+  KeyE = BN_new ();

+  if (PublicExponent == NULL) {

+    BN_set_word (KeyE, 0x10001);

+  } else {

+    BN_bin2bn (PublicExponent, (UINT32) PublicExponentSize, KeyE);

+  }

+

+  RetVal = FALSE;

+  if (RSA_generate_key_ex ((RSA *) RsaContext, (UINT32) ModulusLength, KeyE, NULL) == 1) {

+   RetVal = TRUE;

+  }

+

+  BN_free (KeyE);

+  return RetVal;

+}

+

+/**

+  Validates key components of RSA context.

+

+  This function validates key compoents of RSA context in following aspects:

+  - Whether p is a prime

+  - Whether q is a prime

+  - Whether n = p * q

+  - Whether d*e = 1  mod lcm(p-1,q-1)

+

+  If RsaContext is NULL, then ASSERT().

+

+  @param[in]  RsaContext  Pointer to RSA context to check.

+

+  @retval  TRUE   RSA key components are valid.

+  @retval  FALSE  RSA key components are not valid.

+

+**/

+BOOLEAN

+EFIAPI

+RsaCheckKey (

+  IN  VOID  *RsaContext

+  )

+{

+  UINTN  Reason;

+

+  ASSERT (RsaContext != NULL);

+

+  if  (RSA_check_key ((RSA *) RsaContext) != 1) {

+    Reason = ERR_GET_REASON (ERR_peek_last_error ());

+    if (Reason == RSA_R_P_NOT_PRIME ||

+        Reason == RSA_R_Q_NOT_PRIME ||

+        Reason == RSA_R_N_DOES_NOT_EQUAL_P_Q ||

+        Reason == RSA_R_D_E_NOT_CONGRUENT_TO_1) {

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+/**

+  Performs the PKCS1-v1_5 encoding methods defined in RSA PKCS #1.

+

+  @param  Message      Message buffer to be encoded.

+  @param  MessageSize  Size of message buffer in bytes.

+  @param  DigestInfo   Pointer to buffer of digest info for output.

+

+  @return  Size of DigestInfo in bytes.

+

+**/  

+UINTN

+DigestInfoEncoding (

+  IN   CONST UINT8  *Message,

+  IN   UINTN        MessageSize,

+  OUT  UINT8        *DigestInfo

+  )

+{

+  CONST UINT8  *HashDer;

+  UINTN        DerSize;

+

+  ASSERT (Message != NULL);

+  ASSERT (DigestInfo != NULL);

+

+  //

+  // The original message length is used to determine the hash algorithm since

+  // message is digest value hashed by the specified algorithm.

+  //

+  switch (MessageSize) {

+  case MD5_DIGEST_SIZE:

+    HashDer = Asn1IdMd5;

+    DerSize = sizeof (Asn1IdMd5);

+    break;

+  

+  case SHA1_DIGEST_SIZE:

+    HashDer = Asn1IdSha1;

+    DerSize = sizeof (Asn1IdSha1);

+    break;

+   

+  case SHA256_DIGEST_SIZE:

+    HashDer = Asn1IdSha256;

+    DerSize = sizeof (Asn1IdSha256);

+    break;

+  

+  default:

+    return FALSE;

+  }

+

+  CopyMem (DigestInfo, HashDer, DerSize);

+  CopyMem (DigestInfo + DerSize, Message, MessageSize);

+

+  return (DerSize + MessageSize);

+}

+

+/**

+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.

+

+  This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in

+  RSA PKCS#1.

+  If the Signature buffer is too small to hold the contents of signature, FALSE

+  is returned and SigSize is set to the required buffer size to obtain the signature.

+

+  If RsaContext is NULL, then ASSERT().

+  If MessageHash is NULL, then ASSERT().

+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().

+  If SigSize is large enough but Signature is NULL, then ASSERT().

+

+  @param[in]       RsaContext   Pointer to RSA context for signature generation.

+  @param[in]       MessageHash  Pointer to octet message hash to be signed.

+  @param[in]       HashSize     Size of the message hash in bytes.

+  @param[out]      Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.

+  @param[in, out]  SigSize      On input, the size of Signature buffer in bytes.

+                                On output, the size of data returned in Signature buffer in bytes.

+

+  @retval  TRUE   Signature successfully generated in PKCS1-v1_5.

+  @retval  FALSE  Signature generation failed.

+  @retval  FALSE  SigSize is too small.

+

+**/

+BOOLEAN

+EFIAPI

+RsaPkcs1Sign (

+  IN      VOID         *RsaContext,

+  IN      CONST UINT8  *MessageHash,

+  IN      UINTN        HashSize,

+  OUT     UINT8        *Signature,

+  IN OUT  UINTN        *SigSize

+  )

+{

+  RSA      *Rsa;

+  UINTN    Size;

+  INTN     ReturnVal;

+

+  ASSERT (RsaContext != NULL);

+  ASSERT (MessageHash != NULL);

+  ASSERT ((HashSize == MD5_DIGEST_SIZE) ||

+          (HashSize == SHA1_DIGEST_SIZE) ||

+          (HashSize == SHA256_DIGEST_SIZE));

+

+  Rsa = (RSA *) RsaContext;

+  Size = BN_num_bytes (Rsa->n);

+

+  if (*SigSize < Size) {

+    *SigSize = Size;

+    return FALSE;

+  }

+

+  ASSERT (Signature != NULL);

+

+  Size = DigestInfoEncoding (MessageHash, HashSize, Signature);

+

+  ReturnVal = RSA_private_encrypt (

+                (UINT32) Size,

+                Signature,

+                Signature,

+                Rsa,

+                RSA_PKCS1_PADDING

+                );

+

+  if (ReturnVal < (INTN) Size) {

+    return FALSE;

+  }

+

+  *SigSize = (UINTN)ReturnVal;

+  return TRUE;

+}

 

 /**

   Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in

@@ -195,16 +615,16 @@
   If RsaContext is NULL, then ASSERT().

   If MessageHash is NULL, then ASSERT().

   If Signature is NULL, then ASSERT().

-  If HashLength is not equal to the size of MD5, SHA-1 or SHA-256 digest, then ASSERT().

+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().

 

   @param[in]  RsaContext   Pointer to RSA context for signature verification.

   @param[in]  MessageHash  Pointer to octet message hash to be checked.

-  @param[in]  HashLength   Length of the message hash in bytes.

+  @param[in]  HashSize     Size of the message hash in bytes.

   @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.

-  @param[in]  SigLength    Length of signature in bytes.

+  @param[in]  SigSize      Size of signature in bytes.

 

-  @return  TRUE   Valid signature encoded in PKCS1-v1_5.

-  @return  FALSE  Invalid signature or invalid RSA context.

+  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.

+  @retval  FALSE  Invalid signature or invalid RSA context.

 

 **/

 BOOLEAN

@@ -212,9 +632,9 @@
 RsaPkcs1Verify (

   IN  VOID         *RsaContext,

   IN  CONST UINT8  *MessageHash,

-  IN  UINTN        HashLength,

+  IN  UINTN        HashSize,

   IN  UINT8        *Signature,

-  IN  UINTN        SigLength

+  IN  UINTN        SigSize

   )

 {

   INTN     Length;

@@ -227,17 +647,17 @@
   ASSERT (Signature   != NULL);

 

   //

-  // ASSERT if unsupported hash length:

+  // ASSERT if unsupported hash size:

   //    Only MD5, SHA-1 or SHA-256 digest size is supported

   //

-  ASSERT ((HashLength == MD5_DIGEST_SIZE) || (HashLength == SHA1_DIGEST_SIZE) ||

-          (HashLength == SHA256_DIGEST_SIZE));

+  ASSERT ((HashSize == MD5_DIGEST_SIZE) || (HashSize == SHA1_DIGEST_SIZE) ||

+          (HashSize == SHA256_DIGEST_SIZE));

 

   //

   // RSA PKCS#1 Signature Decoding using OpenSSL RSA Decryption with Public Key

   //

   Length = RSA_public_decrypt (

-             (int)SigLength,

+             (UINT32) SigSize,

              Signature,

              Signature,

              RsaContext,

@@ -246,10 +666,10 @@
 

   //

   // Invalid RSA Key or PKCS#1 Padding Checking Failed (if Length < 0)

-  // NOTE: Length should be the addition of HashLength and some DER value.

+  // NOTE: Length should be the addition of HashSize and some DER value.

   //       Ignore more strict length checking here.

   //

-  if (Length < (INTN) HashLength) {

+  if (Length < (INTN) HashSize) {

     return FALSE;

   }

 

@@ -263,7 +683,7 @@
   //       Then Memory Comparing should skip the DER value of the underlying SEQUENCE

   //       type and AlgorithmIdentifier.

   //

-  if (CompareMem (MessageHash, Signature + Length - HashLength, HashLength) == 0) {

+  if (CompareMem (MessageHash, Signature + Length - HashSize, HashSize) == 0) {

     //

     // Valid RSA PKCS#1 Signature

     //

diff --git a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c
new file mode 100644
index 0000000..3ead6d1
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c
@@ -0,0 +1,88 @@
+/** @file

+  Pseudorandom Number Generator Wrapper Implementation over OpenSSL.

+

+Copyright (c) 2010, 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/rand.h>

+

+//

+// Default seed for UEFI Crypto Library

+//

+CONST UINT8  DefaultSeed[] = "UEFI Crypto Library default seed";

+

+/**

+  Sets up the seed value for the pseudorandom number generator.

+

+  This function sets up the seed value for the pseudorandom number generator.

+  If Seed is not NULL, then the seed passed in is used.

+  If Seed is NULL, then default seed is used.

+

+  @param[in]  Seed      Pointer to seed value.

+                        If NULL, default seed is used.

+  @param[in]  SeedSize  Size of seed value.

+                        If Seed is NULL, this parameter is ignored.

+

+  @retval TRUE   Pseudorandom number generator has enough entropy for random generation.

+  @retval FALSE  Pseudorandom number generator does not have enough entropy for random generation.

+

+**/

+BOOLEAN

+EFIAPI

+RandomSeed (

+  IN  CONST  UINT8  *Seed  OPTIONAL,

+  IN  UINTN         SeedSize

+  )

+{

+  //

+  // Seed the pseudorandom number generator with user-supplied value.

+  // NOTE: A cryptographic PRNG must be seeded with unpredictable data.

+  //

+  if (Seed != NULL) {

+    RAND_seed (Seed, (UINT32) SeedSize);

+  } else {

+    RAND_seed (DefaultSeed, sizeof (DefaultSeed));

+  }

+

+  return TRUE;

+}

+

+/**

+  Generates a pseudorandom byte stream of the specified size.

+

+  If Output is NULL, then ASSERT().

+

+  @param[out]  Output  Pointer to buffer to receive random value.

+  @param[in]   Size    Size of randome bytes to generate.

+

+  @retval TRUE   Pseudorandom byte stream generated successfully.

+  @retval FALSE  Pseudorandom number generator fails to generate due to lack of entropy.

+

+**/

+BOOLEAN

+EFIAPI

+RandomBytes (

+  OUT  UINT8  *Output,

+  IN   UINTN  Size

+  )

+{

+  ASSERT (Output != NULL);

+

+  //

+  // Generate random data.

+  //

+  if (RAND_bytes (Output, (UINT32) Size) != 1) {

+    return FALSE;

+  }

+

+  return TRUE;

+}

diff --git a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
index d31095b..4b5ffd1 100644
--- a/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
@@ -57,8 +57,6 @@
   SysCall/Ia32/MathLShiftS64.S      | GCC

   SysCall/Ia32/MathRShiftU64.S      | GCC

 

-  SysCall/Ia32/Alloca.S             | GCC

-

 [Packages]

   MdePkg/MdePkg.dec

   CryptoPkg/CryptoPkg.dec

diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
new file mode 100644
index 0000000..21ebd00
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -0,0 +1,78 @@
+## @file

+#  Cryptographic Library Instance for SMM driver.

+#

+#  Copyright (c) 2010, 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.

+#  

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmCryptLib

+  FILE_GUID                      = 028080a3-8958-4a62-a1a8-0fa1da162007

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseCryptLib|DXE_SMM_DRIVER SMM_CORE

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  Hash/CryptMd5.c

+  Hash/CryptSha1.c

+  Hash/CryptSha256.c

+  Pk/CryptRsa.c

+  Pk/CryptPkcs7.c

+

+  SysCall/CrtWrapper.c

+  SysCall/RealTimeClock.c

+  SysCall/BaseMemAllocation.c

+

+[Sources.Ia32]

+  SysCall/HelperWrapper.c

+

+  SysCall/Ia32/MathMultS64x64.c     | MSFT

+  SysCall/Ia32/MathDivU64x64.c      | MSFT

+  SysCall/Ia32/MathReminderU64x64.c | MSFT

+  SysCall/Ia32/MathLShiftS64.c      | MSFT

+  SysCall/Ia32/MathRShiftU64.c      | MSFT

+

+  SysCall/Ia32/MathMultS64x64.c     | INTEL

+  SysCall/Ia32/MathDivU64x64.c      | INTEL

+  SysCall/Ia32/MathReminderU64x64.c | INTEL

+  SysCall/Ia32/MathLShiftS64.c      | INTEL

+  SysCall/Ia32/MathRShiftU64.c      | INTEL

+

+  SysCall/Ia32/MathMultS64x64.S     | GCC

+  SysCall/Ia32/MathDivU64x64.S      | GCC

+  SysCall/Ia32/MathReminderU64x64.S | GCC

+  SysCall/Ia32/MathLShiftS64.S      | GCC

+  SysCall/Ia32/MathRShiftU64.S      | GCC

+

+[Packages]

+  MdePkg/MdePkg.dec

+  CryptoPkg/CryptoPkg.dec

+

+[LibraryClasses]

+  BaseLib

+  IoLib

+  BaseMemoryLib

+  MemoryAllocationLib

+  OpensslLib

+  IntrinsicLib

+

+#

+# Remove these [BuildOptions] after this library is cleaned up

+#

+[BuildOptions]

+  GCC:*_GCC44_IA32_CC_FLAGS = "-D__cdecl=__attribute__((cdecl))" "-D__declspec(t)=__attribute__((t))"

+  

diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S
deleted file mode 100644
index 8496833..0000000
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S
+++ /dev/null
@@ -1,59 +0,0 @@
-#------------------------------------------------------------------------------

-#

-# Copyright (c) 2009 - 2010, 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.

-#

-# Module Name:

-#

-#   Alloca.S

-#

-# Abstract:

-#

-#   Implementation for allocation of automatically reclaimed memory, which is

-#   used to allocate space off the runtime stack.

-#   (NOTE: There is a assumption in this code that the page size equal to 4K)

-#

-#------------------------------------------------------------------------------

-

-

-    .686:

-    .code:

-

-ASM_GLOBAL ASM_PFX(_alloca)

-

-#------------------------------------------------------------------------------

-#

-# void __cdecl _alloca (unsigned size)

-#

-#------------------------------------------------------------------------------

-ASM_PFX(_alloca):

-

-    pushl   %ecx

-    cmpl    $0x1000, %eax

-    leal    8(%esp), %ecx

-    jb      LastPage

-

-ProbePages:

-    subl    $0x1000, %ecx

-    subl    $0x1000, %eax

-    testl   %eax, 0(%ecx)

-    cmpl    $0x1000, %eax

-    jae     ProbePages

-

-LastPage:

-    subl    %eax, %ecx

-    movl    %esp, %eax

-    testl   %eax, 0(%ecx)

-

-    movl    %ecx, %esp

-    movl    0(%eax), %ecx

-    movl    4(%eax), %eax

-    pushl   %eax

-

-    ret

diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/RealTimeClock.c b/CryptoPkg/Library/BaseCryptLib/SysCall/RealTimeClock.c
new file mode 100644
index 0000000..84617b4
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/RealTimeClock.c
@@ -0,0 +1,222 @@
+/** @file

+  C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation

+  for OpenSSL-based Cryptographic Library (used in SMM).

+

+Copyright (c) 2010, 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 <Library/BaseLib.h>

+#include <Library/IoLib.h>

+#include <OpenSslSupport.h>

+

+#define PCAT_RTC_ADDRESS_REGISTER 0x70

+#define PCAT_RTC_DATA_REGISTER    0x71

+

+#define RTC_ADDRESS_SECONDS           0   // R/W  Range 0..59

+#define RTC_ADDRESS_SECONDS_ALARM     1   // R/W  Range 0..59

+#define RTC_ADDRESS_MINUTES           2   // R/W  Range 0..59

+#define RTC_ADDRESS_MINUTES_ALARM     3   // R/W  Range 0..59

+#define RTC_ADDRESS_HOURS             4   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM

+#define RTC_ADDRESS_HOURS_ALARM       5   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM

+#define RTC_ADDRESS_DAY_OF_THE_WEEK   6   // R/W  Range 1..7

+#define RTC_ADDRESS_DAY_OF_THE_MONTH  7   // R/W  Range 1..31

+#define RTC_ADDRESS_MONTH             8   // R/W  Range 1..12

+#define RTC_ADDRESS_YEAR              9   // R/W  Range 0..99

+#define RTC_ADDRESS_REGISTER_A        10  // R/W[0..6]  R0[7]

+#define RTC_ADDRESS_REGISTER_B        11  // R/W

+#define RTC_ADDRESS_REGISTER_C        12  // RO

+#define RTC_ADDRESS_REGISTER_D        13  // RO

+#define RTC_ADDRESS_CENTURY           50  // R/W  Range 19..20 Bit 8 is R/W

+

+//

+// Register A

+//

+typedef struct {

+  UINT8 RS : 4;   // Rate Selection Bits

+  UINT8 DV : 3;   // Divisor

+  UINT8 UIP : 1;  // Update in progress

+} RTC_REGISTER_A_BITS;

+

+typedef union {

+  RTC_REGISTER_A_BITS Bits;

+  UINT8               Data;

+} RTC_REGISTER_A;

+

+//

+// Register B

+//

+typedef struct {

+  UINT8 DSE : 1;  // 0 - Daylight saving disabled  1 - Daylight savings enabled

+  UINT8 MIL : 1;  // 0 - 12 hour mode              1 - 24 hour mode

+  UINT8 DM : 1;   // 0 - BCD Format                1 - Binary Format

+  UINT8 SQWE : 1; // 0 - Disable SQWE output       1 - Enable SQWE output

+  UINT8 UIE : 1;  // 0 - Update INT disabled       1 - Update INT enabled

+  UINT8 AIE : 1;  // 0 - Alarm INT disabled        1 - Alarm INT Enabled

+  UINT8 PIE : 1;  // 0 - Periodic INT disabled     1 - Periodic INT Enabled

+  UINT8 SET : 1;  // 0 - Normal operation.         1 - Updates inhibited

+} RTC_REGISTER_B_BITS;

+

+typedef union {

+  RTC_REGISTER_B_BITS Bits;

+  UINT8               Data;

+} RTC_REGISTER_B;

+

+//

+// -- Time Management Routines --

+//

+

+#define IsLeap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))

+#define SECSPERHOUR (60 * 60)

+#define SECSPERDAY  (24 * SECSPERHOUR)

+

+//

+//  The arrays give the cumulative number of days up to the first of the

+//  month number used as the index (1 -> 12) for regular and leap years.

+//  The value at index 13 is for the whole year.

+//

+UINTN CumulativeDays[2][14] = {

+  {

+    0,

+    0,

+    31,

+    31 + 28,

+    31 + 28 + 31,

+    31 + 28 + 31 + 30,

+    31 + 28 + 31 + 30 + 31,

+    31 + 28 + 31 + 30 + 31 + 30,

+    31 + 28 + 31 + 30 + 31 + 30 + 31,

+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,

+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,

+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,

+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,

+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31

+  },

+  {

+    0,

+    0,

+    31,

+    31 + 29,

+    31 + 29 + 31,

+    31 + 29 + 31 + 30,

+    31 + 29 + 31 + 30 + 31,

+    31 + 29 + 31 + 30 + 31 + 30,

+    31 + 29 + 31 + 30 + 31 + 30 + 31,

+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,

+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,

+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,

+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,

+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 

+  }

+};

+

+/**

+  Read RTC content through its registers.

+

+  @param  Address  Address offset of RTC. It is recommended to use macros such as

+                   RTC_ADDRESS_SECONDS.

+

+  @return The data of UINT8 type read from RTC.

+**/

+UINT8

+RtcRead (

+  IN  UINT8 Address

+  )

+{

+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & BIT7)));

+  return IoRead8 (PCAT_RTC_DATA_REGISTER);

+}

+

+/* Get the system time as seconds elapsed since midnight, January 1, 1970. */

+//INTN time(

+//  INTN *timer

+//  )

+time_t time (time_t *timer)

+{

+  UINT16          Year;

+  UINT8           Month;

+  UINT8           Day;

+  UINT8           Hour;

+  UINT8           Minute;

+  UINT8           Second;

+  UINT8           Century;

+  RTC_REGISTER_A  RegisterA;

+  RTC_REGISTER_B  RegisterB;

+  BOOLEAN         IsPM;

+  UINT16          YearIndex;

+

+  RegisterA.Data  = RtcRead (RTC_ADDRESS_REGISTER_A);

+  while (RegisterA.Bits.UIP == 1) {

+    CpuPause();

+    RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);

+  }

+

+  Second  = RtcRead (RTC_ADDRESS_SECONDS);

+  Minute  = RtcRead (RTC_ADDRESS_MINUTES);

+  Hour    = RtcRead (RTC_ADDRESS_HOURS);

+  Day     = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);

+  Month   = RtcRead (RTC_ADDRESS_MONTH);

+  Year    = RtcRead (RTC_ADDRESS_YEAR);

+  Century = RtcRead (RTC_ADDRESS_CENTURY);

+

+  RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);

+

+  if ((Hour & BIT7) != 0) {

+    IsPM = TRUE;

+  } else {

+    IsPM = FALSE;

+  }

+  Hour = (UINT8) (Hour & 0x7f);

+

+  if (RegisterB.Bits.DM == 0) {

+    Year    = BcdToDecimal8 ((UINT8) Year);

+    Month   = BcdToDecimal8 (Month);

+    Day     = BcdToDecimal8 (Day);

+    Hour    = BcdToDecimal8 (Hour);

+    Minute  = BcdToDecimal8 (Minute);

+    Second  = BcdToDecimal8 (Second);

+  }

+  Century   = BcdToDecimal8 (Century);

+

+  Year = (UINT16) (Century * 100 + Year);

+

+  //

+  // If time is in 12 hour format, convert it to 24 hour format

+  //

+  if (RegisterB.Bits.MIL == 0) {

+    if (IsPM && Hour < 12) {

+      Hour = (UINT8) (Hour + 12);

+    }

+    if (!IsPM && Hour == 12) {

+      Hour = 0;

+    }

+  }

+

+  //

+  // Years Handling

+  // UTime should now be set to 00:00:00 on Jan 1 of the current year.

+  //

+  for (YearIndex = 1970, *timer = 0; YearIndex != Year; YearIndex++) {

+    *timer = *timer + (time_t)(CumulativeDays[IsLeap(YearIndex)][13] * SECSPERDAY);

+  }

+

+  //

+  // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment

+  //

+  ASSERT (Month <= 12);

+  *timer = *timer + 

+           (time_t)(CumulativeDays[IsLeap(Year)][Month] * SECSPERDAY) + 

+           (time_t)((Day - 1) * SECSPERDAY) + 

+           (time_t)(Hour * SECSPERHOUR) + 

+           (time_t)(Minute * 60) + 

+           (time_t)Second;

+

+  return *timer;

+}

diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
index 1e1a840..9c1083d 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -21,6 +21,7 @@
   LIBRARY_CLASS                  = OpensslLib

   OPENSSL_PATH                   = openssl-0.9.8l

   OPENSSL_FLAGS                  = -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_ASM

+  OPENSSL_EXFLAGS                = -DOPENSSL_SMALL_FOOTPRINT -DOPENSSL_NO_SHA0 -DOPENSSL_NO_SHA512 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED

   

 #

 # OPENSSL_FLAGS is set to define the following flags to be compatible with 

@@ -574,6 +575,6 @@
   DebugLib

 

 [BuildOptions]

-   MSFT:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /WX- /GL- 

-  INTEL:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) /WX- 

-    GCC:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) -w

+   MSFT:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) $(OPENSSL_EXFLAGS) /WX- /GL- 

+  INTEL:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) $(OPENSSL_EXFLAGS) /WX- 

+    GCC:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_EXFLAGS) -w