Update CryptoPkg for new ciphers (HMAC, Block Cipher, etc) supports.
authorqlong <qlong@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 2 Nov 2010 06:06:38 +0000 (06:06 +0000)
committerqlong <qlong@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 2 Nov 2010 06:06:38 +0000 (06:06 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10997 6f19259b-4bc3-4df7-8a09-765794883524

32 files changed:
CryptoPkg/Application/Cryptest/AuthenticodeVerify.c
CryptoPkg/Application/Cryptest/BlockCipherVerify.c [new file with mode: 0644]
CryptoPkg/Application/Cryptest/Cryptest.c
CryptoPkg/Application/Cryptest/Cryptest.h [new file with mode: 0644]
CryptoPkg/Application/Cryptest/Cryptest.inf
CryptoPkg/Application/Cryptest/DhVerify.c [new file with mode: 0644]
CryptoPkg/Application/Cryptest/HashVerify.c [new file with mode: 0644]
CryptoPkg/Application/Cryptest/HmacVerify.c [new file with mode: 0644]
CryptoPkg/Application/Cryptest/RandVerify.c [new file with mode: 0644]
CryptoPkg/Application/Cryptest/RsaVerify.c [new file with mode: 0644]
CryptoPkg/CryptoPkg.dsc
CryptoPkg/Include/Library/BaseCryptLib.h
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/Hash/CryptMd5.c
CryptoPkg/Library/BaseCryptLib/Hash/CryptSha1.c
CryptoPkg/Library/BaseCryptLib/Hash/CryptSha256.c
CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7.c
CryptoPkg/Library/BaseCryptLib/Pk/CryptRsa.c
CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf [new file with mode: 0644]
CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S [deleted file]
CryptoPkg/Library/BaseCryptLib/SysCall/RealTimeClock.c [new file with mode: 0644]
CryptoPkg/Library/OpensslLib/OpensslLib.inf

index 72c4092..7a4e294 100644 (file)
@@ -12,11 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-\r
-#include <Library/BaseCryptLib.h>\r
+#include "Cryptest.h"\r
 \r
 //\r
 // DER encoding of SpcIndirectDataContent (Authenticode-specific Structure)\r
@@ -656,3 +652,30 @@ AuthenticodeVerify (
 \r
   return Status;\r
 }\r
+\r
+/**\r
+  Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateAuthenticode (\r
+  VOID\r
+  )\r
+{\r
+  Print (L"\nUEFI-OpenSSL PKCS#7-Signed-Data Testing: ");\r
+\r
+  Print (L"\n- Authenticode (PKCS#7 Signed Data) Verification ... ");\r
+\r
+  if (AuthenticodeVerify ()) {\r
+    Print (L"[Pass]");\r
+  } else {\r
+    Print (L"[Fail]");\r
+  }   \r
+\r
+  Print (L"\n");\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/CryptoPkg/Application/Cryptest/BlockCipherVerify.c b/CryptoPkg/Application/Cryptest/BlockCipherVerify.c
new file mode 100644 (file)
index 0000000..de8f6ec
--- /dev/null
@@ -0,0 +1,473 @@
+/** @file  \r
+  Application for Block Cipher Primitives Validation.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Cryptest.h"\r
+\r
+//\r
+// TDES test vectors are extracted from OpenSSL 0.9.8l, crypto\des\destest.c\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcbData[] = {\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcbKey[] = {\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcbCipher[] = {\r
+  0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7,\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesEcb2Cipher[] = {\r
+  0x92, 0x95, 0xB5, 0x9B, 0xB3, 0x84, 0x73, 0x6E,\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesCbcData[] = {\r
+  0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,\r
+  0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,\r
+  0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesCbcKey[] = {\r
+  0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, \r
+  0xf1, 0xe0, 0xd3, 0xc2, 0xb5, 0xa4, 0x97, 0x86,\r
+  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 TdesCbcIvec[] = {\r
+  0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 TdesCbc3Cipher[] = {\r
+  0x3F, 0xE3, 0x01, 0xC9, 0x62, 0xAC, 0x01, 0xD0,\r
+  0x22, 0x13, 0x76, 0x3C, 0x1C, 0xBD, 0x4C, 0xDC,\r
+  0x79, 0x96, 0x57, 0xC0, 0x64, 0xEC, 0xF5, 0xD4\r
+  };\r
+\r
+//\r
+// AES test vectors are from NIST KAT of AES\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128EcbData[] = {\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128EcbKey[] = {\r
+  0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128EcbCipher[] = {\r
+  0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes192EcbData[] = {\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes192EcbKey[] = {\r
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes192EcbCipher[] = {\r
+  0xdd, 0x8a, 0x49, 0x35, 0x14, 0x23, 0x1c, 0xbf, 0x56, 0xec, 0xce, 0xe4, 0xc4, 0x08, 0x89, 0xfb\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes256EcbData[] = {\r
+  0x01, 0x47, 0x30, 0xf8, 0x0a, 0xc6, 0x25, 0xfe, 0x84, 0xf0, 0x26, 0xc6, 0x0b, 0xfd, 0x54, 0x7d\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes256EcbKey[] = {\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes256EcbCipher[] = {\r
+  0x5c, 0x9d, 0x84, 0x4e, 0xd4, 0x6f, 0x98, 0x85, 0x08, 0x5e, 0x5d, 0x6a, 0x4f, 0x94, 0xc7, 0xd7\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcData[] = {\r
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\r
+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcKey[] = {\r
+  0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcIvec[] = {\r
+  0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Aes128CbcCipher[] = {\r
+  0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,\r
+  0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1\r
+  };\r
+\r
+//\r
+// ARC4 Test Vector defined in "Appendix A.1 Test Vectors from [CRYPTLIB]" of\r
+// IETF Draft draft-kaukonen-cipher-arcfour-03 ("A Stream Cipher Encryption Algorithm 'Arcfour'").\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Arc4Data[] = {\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Arc4Key[] = {\r
+  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF\r
+  };\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Arc4Cipher[] = {\r
+  0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79\r
+  };\r
+\r
+/**\r
+  Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptBlockCipher (\r
+  VOID\r
+  )\r
+{\r
+  UINTN    CtxSize;\r
+  VOID     *CipherCtx;\r
+  UINT8    Encrypt[256];\r
+  UINT8    Decrypt[256];\r
+  BOOLEAN  Status;\r
+\r
+  Print (L"\nUEFI-OpenSSL Block Cipher Engine Testing: ");\r
+\r
+  CtxSize   = TdesGetContextSize ();\r
+  CipherCtx = AllocatePool (CtxSize);\r
+\r
+  Print (L"\n- TDES Validation: ");\r
+\r
+\r
+  Print (L"ECB... ");\r
+\r
+  //\r
+  // TDES ECB Validation\r
+  //\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = TdesInit (CipherCtx, TdesEcbKey, 64);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = TdesEcbEncrypt (CipherCtx, TdesEcbData, 8, Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = TdesEcbDecrypt (CipherCtx, Encrypt, 8, Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, TdesEcbCipher, 8) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Decrypt, TdesEcbData, 8) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"EDE2 ECB... ");\r
+\r
+  //\r
+  // TDES EDE2 ECB Validation\r
+  //\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = TdesInit (CipherCtx, TdesEcbKey, 128);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = TdesEcbEncrypt (CipherCtx, TdesEcbData, 8, Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = TdesEcbDecrypt (CipherCtx, Encrypt, 8, Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, TdesEcb2Cipher, 8) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  } \r
+\r
+  if (CompareMem (Decrypt, TdesEcbData, 8) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"EDE3 CBC... ");\r
+\r
+  //\r
+  // TDES EDE3 CBC Validation\r
+  //\r
+  ZeroMem (Encrypt, 256);\r
+  ZeroMem (Decrypt, 256);\r
+\r
+  Status = TdesInit (CipherCtx, TdesCbcKey, 192);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = TdesCbcEncrypt (CipherCtx, TdesCbcData, sizeof (TdesCbcData), TdesCbcIvec, Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = TdesCbcDecrypt (CipherCtx, Encrypt, sizeof (TdesCbcData), TdesCbcIvec, Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, TdesCbc3Cipher, sizeof (TdesCbc3Cipher)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Decrypt, TdesCbcData, sizeof (TdesCbcData)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]");\r
+\r
+  FreePool (CipherCtx);\r
+\r
+  CtxSize   = AesGetContextSize ();\r
+  CipherCtx = AllocatePool (CtxSize);\r
+  \r
+  Print (L"\n- AES Validation:  ");\r
+\r
+  Print (L"ECB-128... ");\r
+\r
+  //\r
+  // AES-128 ECB Validation\r
+  //\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = AesInit (CipherCtx, Aes128EcbKey, 128);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesEcbEncrypt (CipherCtx, Aes128EcbData, sizeof (Aes128EcbData), Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesEcbDecrypt (CipherCtx, Encrypt, sizeof (Aes128EcbData), Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, Aes128EcbCipher, sizeof (Aes128EcbCipher)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  } \r
+\r
+  if (CompareMem (Decrypt, Aes128EcbData, sizeof (Aes128EcbData)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"ECB-192... ");\r
+\r
+  //\r
+  // AES-192 ECB Validation\r
+  //\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = AesInit (CipherCtx, Aes192EcbKey, 192);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesEcbEncrypt (CipherCtx, Aes192EcbData, sizeof (Aes192EcbData), Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesEcbDecrypt (CipherCtx, Encrypt, sizeof (Aes192EcbData), Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, Aes192EcbCipher, sizeof (Aes192EcbCipher)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Decrypt, Aes192EcbData, sizeof (Aes192EcbData)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"ECB-256... ");\r
+\r
+  //\r
+  // AES-256 ECB Validation\r
+  //\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = AesInit (CipherCtx, Aes256EcbKey, 256);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesEcbEncrypt (CipherCtx, Aes256EcbData, sizeof (Aes256EcbData), Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesEcbDecrypt (CipherCtx, Encrypt, sizeof (Aes256EcbData), Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, Aes256EcbCipher, sizeof (Aes256EcbCipher)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Decrypt, Aes256EcbData, sizeof (Aes256EcbData)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"CBC-128... ");\r
+\r
+  //\r
+  // AES-128 CBC Validation\r
+  //\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = AesInit (CipherCtx, Aes128CbcKey, 128);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesCbcEncrypt (CipherCtx, Aes128CbcData, sizeof (Aes128CbcData), Aes128CbcIvec, Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = AesCbcDecrypt (CipherCtx, Encrypt, sizeof (Aes128CbcData), Aes128CbcIvec, Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, Aes128CbcCipher, sizeof (Aes128CbcCipher)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Decrypt, Aes128CbcData, sizeof (Aes128CbcData)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]");\r
+\r
+  Print (L"\n- ARC4 Validation: ");\r
+\r
+  //\r
+  // ARC4 Validation\r
+  //\r
+  CtxSize   = Arc4GetContextSize ();\r
+  CipherCtx = AllocatePool (CtxSize);\r
+\r
+  ZeroMem (Encrypt, sizeof (Encrypt));\r
+  ZeroMem (Decrypt, sizeof (Decrypt));\r
+\r
+  Status = Arc4Init (CipherCtx, Arc4Key, sizeof (Arc4Key));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = Arc4Encrypt (CipherCtx, Arc4Data, sizeof (Arc4Data), Encrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = Arc4Reset (CipherCtx);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = Arc4Decrypt (CipherCtx, Encrypt, sizeof (Arc4Data), Decrypt);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Encrypt, Arc4Cipher, sizeof (Arc4Cipher)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Decrypt, Arc4Data, sizeof (Arc4Data)) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]");\r
+\r
+  Print (L"\n");\r
+\r
+  return EFI_SUCCESS;\r
+}\r
index 6afe299..188a36c 100644 (file)
@@ -12,332 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Uefi.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/UefiApplicationEntryPoint.h>\r
-#include <Library/DebugLib.h>\r
-\r
-#include <Library/BaseCryptLib.h>\r
-\r
-//\r
-// Max Known Digest Size is SHA512 Output (64 bytes) by far\r
-//\r
-#define MAX_DIGEST_SIZE    64\r
-\r
-//\r
-// Message string for digest validation\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HashData = "abc";\r
-\r
-//\r
-// Result for MD5("abc"). (From "A.5 Test suite" of IETF RFC1321)\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Md5Digest[MD5_DIGEST_SIZE] = {\r
-  0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72\r
-  };\r
-\r
-//\r
-// Result for SHA-1("abc"). (From "A.1 SHA-1 Example" of NIST FIPS 180-2)\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha1Digest[SHA1_DIGEST_SIZE] = {\r
-  0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,\r
-  0x9c, 0xd0, 0xd8, 0x9d\r
-  };\r
-\r
-//\r
-// Result for SHA-256("abc"). (From "B.1 SHA-256 Example" of NIST FIPS 180-2)\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha256Digest[SHA256_DIGEST_SIZE] = {\r
-  0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,\r
-  0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad\r
-  };\r
-\r
-//\r
-// RSA PKCS#1 Validation Data from OpenSSL "Fips_rsa_selftest.c"\r
-//\r
-\r
-// Public Modulus of RSA Key\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaN[] = {\r
-  0xBB, 0xF8, 0x2F, 0x09, 0x06, 0x82, 0xCE, 0x9C, 0x23, 0x38, 0xAC, 0x2B, 0x9D, 0xA8, 0x71, 0xF7, \r
-  0x36, 0x8D, 0x07, 0xEE, 0xD4, 0x10, 0x43, 0xA4, 0x40, 0xD6, 0xB6, 0xF0, 0x74, 0x54, 0xF5, 0x1F,\r
-  0xB8, 0xDF, 0xBA, 0xAF, 0x03, 0x5C, 0x02, 0xAB, 0x61, 0xEA, 0x48, 0xCE, 0xEB, 0x6F, 0xCD, 0x48,\r
-  0x76, 0xED, 0x52, 0x0D, 0x60, 0xE1, 0xEC, 0x46, 0x19, 0x71, 0x9D, 0x8A, 0x5B, 0x8B, 0x80, 0x7F,\r
-  0xAF, 0xB8, 0xE0, 0xA3, 0xDF, 0xC7, 0x37, 0x72, 0x3E, 0xE6, 0xB4, 0xB7, 0xD9, 0x3A, 0x25, 0x84,\r
-  0xEE, 0x6A, 0x64, 0x9D, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xB2, 0x45, 0x45, 0x98, 0x39, 0x4E,\r
-  0xE0, 0xAA, 0xB1, 0x2D, 0x7B, 0x61, 0xA5, 0x1F, 0x52, 0x7A, 0x9A, 0x41, 0xF6, 0xC1, 0x68, 0x7F,\r
-  0xE2, 0x53, 0x72, 0x98, 0xCA, 0x2A, 0x8F, 0x59, 0x46, 0xF8, 0xE5, 0xFD, 0x09, 0x1D, 0xBD, 0xCB\r
-  };\r
-\r
-// Public Exponent of RSA Key\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaE[] = { 0x11 };\r
-\r
-// Known Answer Test (KAT) Data for RSA PKCS#1 Signing\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 RsaSignData[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";\r
-\r
-// Known Signature for the above message, under SHA-1 Digest\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaPkcs1Signature[] = {\r
-  0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, 0x4A, 0xFD, 0x1A, 0x05,\r
-  0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51,\r
-  0x55, 0x77, 0x90, 0xCF, 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,\r
-  0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, 0x20, 0x22, 0xBE, 0x59,\r
-  0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF,\r
-  0x4E, 0xCA, 0x2E, 0x4E, 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,\r
-  0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, 0x72, 0x05, 0xDE, 0xE6,\r
-  0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4\r
-  };\r
-\r
-/**\r
-  Validate MSFT Authenticode using PKCS#7 Verification Interfaces.\r
-\r
-  @return  EFI_SUCCESS  Validation succeeds. \r
-\r
-**/\r
-BOOLEAN\r
-AuthenticodeVerify (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Validate UEFI-OpenSSL Digest Interfaces.\r
-\r
-  @return  EFI_SUCCESS  Validation succeeded.\r
-\r
-**/\r
-EFI_STATUS\r
-ValidateCryptDigest (\r
-  VOID\r
-  )\r
-{\r
-  UINTN    CtxSize;\r
-  VOID     *HashCtx;\r
-  UINTN    DataSize;\r
-  UINT8    Digest[MAX_DIGEST_SIZE];\r
-  UINTN    Index;\r
-  BOOLEAN  Status;\r
-\r
-  Print (L" UEFI-OpenSSL Hash Engine Testing (Hashing(\"abc\")): ");\r
-  DataSize = AsciiStrLen (HashData);\r
-\r
-  //\r
-  // MD5 Digest Validation\r
-  //\r
-  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
-  CtxSize = Md5GetContextSize ();\r
-  HashCtx = AllocatePool (CtxSize);\r
-  Status  = Md5Init (HashCtx);\r
-  Status  = Md5Update (HashCtx, HashData, DataSize);\r
-  Status  = Md5Final (HashCtx, Digest);\r
-  FreePool (HashCtx);\r
-  Print (L"\n   - MD5 Digest: \n     = 0x");\r
-  for (Index = 0; Index < MD5_DIGEST_SIZE; Index++) {\r
-    Print (L"%02x", Digest[Index]);\r
-  }\r
-  if (CompareMem (Digest, Md5Digest, MD5_DIGEST_SIZE) == 0) {\r
-    Print (L" [Pass]");\r
-  } else {\r
-    Print (L" [Failed]");\r
-  }\r
-\r
-  //\r
-  // SHA-1 Digest Validation\r
-  //\r
-  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
-  CtxSize = Sha1GetContextSize ();\r
-  HashCtx = AllocatePool (CtxSize);\r
-  Status  = Sha1Init (HashCtx);\r
-  Status  = Sha1Update (HashCtx, HashData, DataSize);\r
-  Status  = Sha1Final (HashCtx, Digest);\r
-  FreePool (HashCtx);\r
-  Print (L"\n   - SHA-1 Digest: \n     = 0x");\r
-  for (Index = 0; Index < SHA1_DIGEST_SIZE; Index++) {\r
-    Print (L"%02x", Digest[Index]);\r
-  }\r
-  if (CompareMem (Digest, Sha1Digest, SHA1_DIGEST_SIZE) == 0) {\r
-    Print (L" [Pass]");\r
-  } else {\r
-    Print (L" [Failed]");\r
-  }\r
-\r
-  //\r
-  // SHA256 Digest Validation\r
-  //\r
-  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
-  CtxSize = Sha256GetContextSize ();\r
-  HashCtx = AllocatePool (CtxSize);\r
-  Status  = Sha256Init (HashCtx);\r
-  Status  = Sha256Update (HashCtx, HashData, DataSize);\r
-  Status  = Sha256Final (HashCtx, Digest);\r
-  FreePool (HashCtx);\r
-  Print (L"\n   - SHA-256 Digest: \n     = 0x");\r
-  for (Index = 0; Index < SHA256_DIGEST_SIZE; Index++) {\r
-    Print (L"%02x", Digest[Index]);\r
-  }\r
-  if (CompareMem (Digest, Sha256Digest, SHA256_DIGEST_SIZE) == 0) {\r
-    Print (L" [Pass]");\r
-  } else {\r
-    Print (L" [Failed]");\r
-  }  \r
-\r
-  Print (L"\n");\r
-  \r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Validate UEFI-OpenSSL Message Authentication Codes Interfaces.\r
-\r
-  @return  EFI_SUCCESS  Validation succeeded. \r
-\r
-**/\r
-EFI_STATUS\r
-ValidateCryptHmac (\r
-  VOID\r
-  )\r
-{\r
-  Print (L"\n UEFI-OpenSSL HMAC Engine Testing: ");\r
-  Print (L"\n   ==> No HMAC Support in Base Crypto Library!\n");\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.\r
-\r
-  @return  EFI_SUCCESS  Validation succeeded.\r
-\r
-**/\r
-EFI_STATUS\r
-ValidateCryptBlockCipher (\r
-  VOID\r
-  )\r
-{\r
-  Print (L"\n UEFI-OpenSSL Block Cipher Engine Testing: ");\r
-  Print (L"\n   ==> No Block Cipher Support in Base Crypto Library!\n");\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Validate UEFI-OpenSSL RSA Interfaces.\r
-\r
-  @return  EFI_SUCCESS  Validation succeeded.\r
-\r
-**/\r
-EFI_STATUS\r
-ValidateCryptRsa (\r
-  VOID\r
-  )\r
-{\r
-  VOID     *Rsa;\r
-  UINT8    mHash[SHA1_DIGEST_SIZE];\r
-  UINTN    HashSize;\r
-  UINTN    CtxSize;\r
-  VOID     *Sha1Ctx;\r
-  UINT8    *Signature;\r
-  UINTN    SigSize;\r
-  BOOLEAN  Status;\r
-\r
-  Print (L"\n UEFI-OpenSSL RSA Engine Testing: ");\r
-\r
-  //\r
-  // Generate & Initialize RSA Context\r
-  //\r
-  Rsa = RsaNew ();\r
-  Print (L"\n   - Generate RSA Context .............. ");\r
-  if (Rsa != NULL) {\r
-    Print (L"[Pass]");\r
-  } else {\r
-    Print (L"[Failed]");\r
-  }\r
-\r
-  //\r
-  // Set RSA Key Components\r
-  // NOTE: Only N and E are needed to be set as RSA public key for signature verification\r
-  //\r
-  Print (L"\n   - Set RSA Key Components ............ ");\r
-  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));\r
-  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));\r
-  if (Status) {\r
-    Print (L"[Pass]");\r
-  } else {\r
-    Print (L"[Failed]");\r
-  }\r
-\r
-  //\r
-  // SHA-1 Digest Message for PKCS#1 Signature \r
-  //\r
-  Print (L"\n   - Hash Original Message ............. ");\r
-  HashSize = SHA1_DIGEST_SIZE;\r
-  ZeroMem (mHash, HashSize);\r
-  CtxSize = Sha1GetContextSize ();\r
-  Sha1Ctx = AllocatePool (CtxSize);\r
-  Status  = Sha1Init (Sha1Ctx);\r
-  Status  = Sha1Update (Sha1Ctx, RsaSignData, AsciiStrLen (RsaSignData));\r
-  Status  = Sha1Final (Sha1Ctx, mHash);\r
-  FreePool (Sha1Ctx);\r
-  if (Status) {\r
-    Print (L"[Pass]");\r
-  } else {\r
-    Print (L"[Failed]");\r
-  }\r
-\r
-  //\r
-  // Verify RSA PKCS#1-encoded Signature\r
-  //\r
-  Print (L"\n   - PKCS#1 Signature Verification ..... ");\r
-  SigSize   = sizeof (RsaPkcs1Signature);\r
-  Signature = (UINT8 *)AllocatePool (SigSize);\r
-  CopyMem (Signature, RsaPkcs1Signature, SigSize);\r
-  Status = RsaPkcs1Verify (Rsa, mHash, HashSize, Signature, SigSize);\r
-  if (Status) {\r
-    Print (L"[Pass]");\r
-  } else {\r
-    Print (L"[Failed]");\r
-  }   \r
-\r
-  //\r
-  // Release Resources\r
-  //\r
-  RsaFree (Rsa);\r
-  Print (L"\n   - Release RSA Context ............... [Pass]");\r
-\r
-  Print (L"\n");\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.\r
-\r
-  @return  EFI_SUCCESS  Validation succeeded.\r
-\r
-**/\r
-EFI_STATUS\r
-ValidateAuthenticode (\r
-  VOID\r
-  )\r
-{\r
-  Print (L"\n UEFI-OpenSSL PKCS#7-Signed-Data Testing: ");\r
-\r
-  Print (L"\n   - Authenticode (PKCS#7 Signed Data) Verification ... ");\r
-\r
-  if (AuthenticodeVerify ()) {\r
-    Print (L"[Pass]");\r
-  } else {\r
-    Print (L"[Failed]");\r
-  }   \r
-\r
-  Print (L"\n");\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
+#include "Cryptest.h"\r
 \r
 /**\r
   Entry Point of Cryptographic Validation Utility.\r
@@ -361,12 +36,42 @@ CryptestMain (
   Print (L"\nUEFI-OpenSSL Wrapper Cryptosystem Testing: \n");\r
   Print (L"-------------------------------------------- \n");\r
 \r
-  Status = EFI_SUCCESS;\r
+  RandomSeed (NULL, 0);\r
+\r
   Status = ValidateCryptDigest ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Status = ValidateCryptHmac ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Status = ValidateCryptBlockCipher ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Status = ValidateCryptRsa ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   Status = ValidateAuthenticode ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = ValidateCryptDh ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  return Status;\r
+  Status = ValidateCryptPrng ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
diff --git a/CryptoPkg/Application/Cryptest/Cryptest.h b/CryptoPkg/Application/Cryptest/Cryptest.h
new file mode 100644 (file)
index 0000000..b631285
--- /dev/null
@@ -0,0 +1,111 @@
+/** @file  \r
+  Application for Cryptographic Primitives Validation.\r
+\r
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __CRYPTEST_H__\r
+#define __CRYPTEST_H__\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+\r
+/**\r
+  Validate UEFI-OpenSSL Digest Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptDigest (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Validate UEFI-OpenSSL Message Authentication Codes Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptHmac (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptBlockCipher (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Validate UEFI-OpenSSL RSA Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptRsa (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateAuthenticode (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Validate UEFI-OpenSSL DH Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptDh (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Validate UEFI-OpenSSL pseudorandom number generator interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptPrng (\r
+  VOID\r
+  );\r
+\r
+#endif\r
index 8517294..0e61760 100644 (file)
 #\r
 \r
 [Sources]\r
+  Cryptest.h\r
   Cryptest.c\r
+  HashVerify.c\r
+  HmacVerify.c\r
+  BlockCipherVerify.c\r
+  RsaVerify.c\r
   AuthenticodeVerify.c\r
-\r
+  DhVerify.c\r
+  RandVerify.c\r
+  \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   CryptoPkg/CryptoPkg.dec\r
diff --git a/CryptoPkg/Application/Cryptest/DhVerify.c b/CryptoPkg/Application/Cryptest/DhVerify.c
new file mode 100644 (file)
index 0000000..455d85b
--- /dev/null
@@ -0,0 +1,117 @@
+/** @file  \r
+  Application for Diffie-Hellman Primitives Validation.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Cryptest.h"\r
+\r
+/**\r
+  Validate UEFI-OpenSSL DH Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptDh (\r
+  VOID\r
+  )\r
+{\r
+  VOID    *Dh1;\r
+  VOID    *Dh2;\r
+  UINT8   Prime[64];\r
+  UINT8   PublicKey1[64];\r
+  UINTN   PublicKey1Length;\r
+  UINT8   PublicKey2[64];\r
+  UINTN   PublicKey2Length;\r
+  UINT8   Key1[64];\r
+  UINTN   Key1Length;\r
+  UINT8   Key2[64];\r
+  UINTN   Key2Length;\r
+  BOOLEAN Status;\r
+\r
+  Print (L"\nUEFI-OpenSSL DH Engine Testing:\n");\r
+\r
+  //\r
+  // Generate & Initialize DH Context\r
+  //\r
+  Print (L"- Context1 ... ");\r
+  Dh1 = DhNew ();\r
+  if (Dh1 == NULL) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Context2 ... ");\r
+  Dh2 = DhNew ();\r
+  if (Dh2 == NULL) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Parameter1 ... ");\r
+  Status = DhGenerateParameter (Dh1, 2, 64, Prime);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Parameter2 ... ");\r
+  Status = DhSetParameter (Dh2, 2, 64, Prime);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Generate key1 ... ");\r
+  Status = DhGenerateKey (Dh1, PublicKey1, &PublicKey1Length);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Generate key2 ... ");\r
+  Status = DhGenerateKey (Dh2, PublicKey2, &PublicKey2Length);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Compute key1 ... ");\r
+  Status = DhComputeKey (Dh1, PublicKey2, PublicKey2Length, Key1, &Key1Length);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Compute key2 ... ");\r
+  Status = DhComputeKey (Dh2, PublicKey1, PublicKey1Length, Key2, &Key2Length);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Compare Keys ... ");\r
+  if (Key1Length != Key2Length) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Key1, Key2, Key1Length) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/CryptoPkg/Application/Cryptest/HashVerify.c b/CryptoPkg/Application/Cryptest/HashVerify.c
new file mode 100644 (file)
index 0000000..1b21896
--- /dev/null
@@ -0,0 +1,192 @@
+/** @file  \r
+  Application for Hash Primitives Validation.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Cryptest.h"\r
+\r
+//\r
+// Max Known Digest Size is SHA512 Output (64 bytes) by far\r
+//\r
+#define MAX_DIGEST_SIZE    64\r
+\r
+//\r
+// Message string for digest validation\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HashData = "abc";\r
+\r
+//\r
+// Result for MD5("abc"). (From "A.5 Test suite" of IETF RFC1321)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Md5Digest[MD5_DIGEST_SIZE] = {\r
+  0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72\r
+  };\r
+\r
+//\r
+// Result for SHA-1("abc"). (From "A.1 SHA-1 Example" of NIST FIPS 180-2)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha1Digest[SHA1_DIGEST_SIZE] = {\r
+  0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,\r
+  0x9c, 0xd0, 0xd8, 0x9d\r
+  };\r
+\r
+//\r
+// Result for SHA-256("abc"). (From "B.1 SHA-256 Example" of NIST FIPS 180-2)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha256Digest[SHA256_DIGEST_SIZE] = {\r
+  0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,\r
+  0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad\r
+  };\r
+\r
+/**\r
+  Validate UEFI-OpenSSL Digest Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptDigest (\r
+  VOID\r
+  )\r
+{\r
+  UINTN    CtxSize;\r
+  VOID     *HashCtx;\r
+  UINTN    DataSize;\r
+  UINT8    Digest[MAX_DIGEST_SIZE];\r
+  BOOLEAN  Status;\r
+\r
+  Print (L" UEFI-OpenSSL Hash Engine Testing:\n");\r
+  DataSize = AsciiStrLen (HashData);\r
+\r
+  Print (L"- MD5:    ");\r
+\r
+  //\r
+  // MD5 Digest Validation\r
+  //\r
+  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
+  CtxSize = Md5GetContextSize ();\r
+  HashCtx = AllocatePool (CtxSize);\r
+\r
+  Print (L"Init... ");\r
+  Status  = Md5Init (HashCtx);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Update... ");\r
+  Status  = Md5Update (HashCtx, HashData, DataSize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Finalize... ");\r
+  Status  = Md5Final (HashCtx, Digest);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (HashCtx);\r
+\r
+  Print (L"Check Value... ");\r
+  if (CompareMem (Digest, Md5Digest, MD5_DIGEST_SIZE) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+\r
+  Print (L"- SHA1:   ");\r
+\r
+  //\r
+  // SHA-1 Digest Validation\r
+  //\r
+  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
+  CtxSize = Sha1GetContextSize ();\r
+  HashCtx = AllocatePool (CtxSize);\r
+\r
+  Print (L"Init... ");\r
+  Status  = Sha1Init (HashCtx);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Update... ");\r
+  Status  = Sha1Update (HashCtx, HashData, DataSize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Finalize... ");\r
+  Status  = Sha1Final (HashCtx, Digest);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (HashCtx);\r
+\r
+  Print (L"Check Value... ");\r
+  if (CompareMem (Digest, Sha1Digest, SHA1_DIGEST_SIZE) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+\r
+  Print (L"- SHA256: ");\r
+\r
+  //\r
+  // SHA256 Digest Validation\r
+  //\r
+  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
+  CtxSize = Sha256GetContextSize ();\r
+  HashCtx = AllocatePool (CtxSize);\r
+\r
+  Print (L"Init... ");\r
+  Status  = Sha256Init (HashCtx);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Update... ");\r
+  Status  = Sha256Update (HashCtx, HashData, DataSize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Finalize... ");\r
+  Status  = Sha256Final (HashCtx, Digest);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (HashCtx);\r
+\r
+  Print (L"Check Value... ");\r
+  if (CompareMem (Digest, Sha256Digest, SHA256_DIGEST_SIZE) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/CryptoPkg/Application/Cryptest/HmacVerify.c b/CryptoPkg/Application/Cryptest/HmacVerify.c
new file mode 100644 (file)
index 0000000..73b38f3
--- /dev/null
@@ -0,0 +1,157 @@
+/** @file  \r
+  Application for HMAC Primitives Validation.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Cryptest.h"\r
+\r
+//\r
+// Max Known Digest Size is SHA512 Output (64 bytes) by far\r
+//\r
+#define MAX_DIGEST_SIZE    64\r
+\r
+//\r
+// Data string for HMAC validation\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HmacData = "Hi There";\r
+\r
+//\r
+// Key value for HMAC-MD5 validation. (From "2. Test Cases for HMAC-MD5" of IETF RFC2202)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacMd5Key[16] = {\r
+  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b\r
+  };\r
+\r
+//\r
+// Result for HMAC-MD5("Hi There"). (From "2. Test Cases for HMAC-MD5" of IETF RFC2202)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacMd5Digest[] = {\r
+  0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d\r
+  };\r
+\r
+//\r
+// Key value for HMAC-SHA-1 validation. (From "3. Test Cases for HMAC-SHA-1" of IETF RFC2202)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacSha1Key[20] = {\r
+  0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,\r
+  0x0b, 0x0b, 0x0b, 0x0b\r
+  };\r
+\r
+//\r
+// Result for HMAC-SHA-1 ("Hi There"). (From "3. Test Cases for HMAC-SHA-1" of IETF RFC2202)\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 HmacSha1Digest[] = {\r
+  0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,\r
+  0xf1, 0x46, 0xbe, 0x00\r
+  };\r
+\r
+/**\r
+  Validate UEFI-OpenSSL Message Authentication Codes Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptHmac (\r
+  VOID\r
+  )\r
+{\r
+  UINTN    CtxSize;\r
+  VOID     *HmacCtx;\r
+  UINT8    Digest[MAX_DIGEST_SIZE];\r
+  BOOLEAN  Status;\r
+\r
+  Print (L" \nUEFI-OpenSSL HMAC Engine Testing:\n");\r
+\r
+  Print (L"- HMAC-MD5:  ");\r
+\r
+  //\r
+  // HMAC-MD5 Digest Validation\r
+  //\r
+  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
+  CtxSize = HmacMd5GetContextSize ();\r
+  HmacCtx = AllocatePool (CtxSize);\r
+\r
+  Print (L"Init... ");\r
+  Status  = HmacMd5Init (HmacCtx, HmacMd5Key, sizeof (HmacMd5Key));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Update... ");\r
+  Status  = HmacMd5Update (HmacCtx, HmacData, 8);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Finalize... ");\r
+  Status  = HmacMd5Final (HmacCtx, Digest);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (HmacCtx);\r
+\r
+  Print (L"Check Value... ");\r
+  if (CompareMem (Digest, HmacMd5Digest, MD5_DIGEST_SIZE) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+\r
+  Print (L"- HMAC-SHA1: ");\r
+\r
+  //\r
+  // HMAC-SHA1 Digest Validation\r
+  //\r
+  ZeroMem (Digest, MAX_DIGEST_SIZE);\r
+  CtxSize = HmacSha1GetContextSize ();\r
+  HmacCtx = AllocatePool (CtxSize);\r
+\r
+  Print (L"Init... ");\r
+  Status  = HmacSha1Init (HmacCtx, HmacSha1Key, sizeof (HmacSha1Key));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Update... ");\r
+  Status  = HmacSha1Update (HmacCtx, HmacData, 8);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"Finalize... ");\r
+  Status  = HmacSha1Final (HmacCtx, Digest);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (HmacCtx);\r
+\r
+  Print (L"Check Value... ");\r
+  if (CompareMem (Digest, HmacSha1Digest, SHA1_DIGEST_SIZE) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/CryptoPkg/Application/Cryptest/RandVerify.c b/CryptoPkg/Application/Cryptest/RandVerify.c
new file mode 100644 (file)
index 0000000..c9e7341
--- /dev/null
@@ -0,0 +1,69 @@
+/** @file  \r
+  Application for Pseudorandom Number Generator Validation.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Cryptest.h"\r
+\r
+#define  RANDOM_NUMBER_SIZE  256\r
+\r
+CONST  UINT8  SeedString[] = "This is the random seed for PRNG verification.";\r
+\r
+UINT8  PreviousRandomBuffer[RANDOM_NUMBER_SIZE] = { 0x0 };\r
+\r
+UINT8  RandomBuffer[RANDOM_NUMBER_SIZE] = { 0x0 };\r
+\r
+/**\r
+  Validate UEFI-OpenSSL pseudorandom number generator interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptPrng (\r
+  VOID\r
+  )\r
+{\r
+  UINTN    Index;\r
+  BOOLEAN  Status;\r
+\r
+  Print (L" \nUEFI-OpenSSL PRNG Engine Testing:\n");\r
+\r
+  Print (L"- Random Generation...");\r
+\r
+  Status = RandomSeed (SeedString, sizeof (SeedString));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  for (Index = 0; Index < 10; Index ++) {\r
+    Status = RandomBytes (RandomBuffer, RANDOM_NUMBER_SIZE);\r
+    if (!Status) {\r
+      Print (L"[Fail]");\r
+      return EFI_ABORTED;\r
+    }\r
+\r
+    if (CompareMem (PreviousRandomBuffer, RandomBuffer, RANDOM_NUMBER_SIZE) == 0) {\r
+      Print (L"[Fail]");\r
+      return EFI_ABORTED;\r
+    }\r
+\r
+    CopyMem (PreviousRandomBuffer, RandomBuffer, RANDOM_NUMBER_SIZE);\r
+  }\r
+\r
+  Print (L"[Pass]\n");\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
diff --git a/CryptoPkg/Application/Cryptest/RsaVerify.c b/CryptoPkg/Application/Cryptest/RsaVerify.c
new file mode 100644 (file)
index 0000000..bbcad68
--- /dev/null
@@ -0,0 +1,406 @@
+/** @file  \r
+  Application for RSA Primitives Validation.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "Cryptest.h"\r
+\r
+#define  RSA_MODULUS_LENGTH  512\r
+\r
+//\r
+// RSA PKCS#1 Validation Data from OpenSSL "Fips_rsa_selftest.c"\r
+//\r
+\r
+//\r
+// Public Modulus of RSA Key\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaN[] = {\r
+  0xBB, 0xF8, 0x2F, 0x09, 0x06, 0x82, 0xCE, 0x9C, 0x23, 0x38, 0xAC, 0x2B, 0x9D, 0xA8, 0x71, 0xF7, \r
+  0x36, 0x8D, 0x07, 0xEE, 0xD4, 0x10, 0x43, 0xA4, 0x40, 0xD6, 0xB6, 0xF0, 0x74, 0x54, 0xF5, 0x1F,\r
+  0xB8, 0xDF, 0xBA, 0xAF, 0x03, 0x5C, 0x02, 0xAB, 0x61, 0xEA, 0x48, 0xCE, 0xEB, 0x6F, 0xCD, 0x48,\r
+  0x76, 0xED, 0x52, 0x0D, 0x60, 0xE1, 0xEC, 0x46, 0x19, 0x71, 0x9D, 0x8A, 0x5B, 0x8B, 0x80, 0x7F,\r
+  0xAF, 0xB8, 0xE0, 0xA3, 0xDF, 0xC7, 0x37, 0x72, 0x3E, 0xE6, 0xB4, 0xB7, 0xD9, 0x3A, 0x25, 0x84,\r
+  0xEE, 0x6A, 0x64, 0x9D, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xB2, 0x45, 0x45, 0x98, 0x39, 0x4E,\r
+  0xE0, 0xAA, 0xB1, 0x2D, 0x7B, 0x61, 0xA5, 0x1F, 0x52, 0x7A, 0x9A, 0x41, 0xF6, 0xC1, 0x68, 0x7F,\r
+  0xE2, 0x53, 0x72, 0x98, 0xCA, 0x2A, 0x8F, 0x59, 0x46, 0xF8, 0xE5, 0xFD, 0x09, 0x1D, 0xBD, 0xCB\r
+  };\r
+\r
+//\r
+// Public Exponent of RSA Key\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaE[] = { 0x11 };\r
+\r
+//\r
+// Private Exponent of RSA Key\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaD[] = {\r
+  0xA5, 0xDA, 0xFC, 0x53, 0x41, 0xFA, 0xF2, 0x89, 0xC4, 0xB9, 0x88, 0xDB, 0x30, 0xC1, 0xCD, 0xF8,\r
+  0x3F, 0x31, 0x25, 0x1E, 0x06, 0x68, 0xB4, 0x27, 0x84, 0x81, 0x38, 0x01, 0x57, 0x96, 0x41, 0xB2,\r
+  0x94, 0x10, 0xB3, 0xC7, 0x99, 0x8D, 0x6B, 0xC4, 0x65, 0x74, 0x5E, 0x5C, 0x39, 0x26, 0x69, 0xD6,\r
+  0x87, 0x0D, 0xA2, 0xC0, 0x82, 0xA9, 0x39, 0xE3, 0x7F, 0xDC, 0xB8, 0x2E, 0xC9, 0x3E, 0xDA, 0xC9,\r
+  0x7F, 0xF3, 0xAD, 0x59, 0x50, 0xAC, 0xCF, 0xBC, 0x11, 0x1C, 0x76, 0xF1, 0xA9, 0x52, 0x94, 0x44,\r
+  0xE5, 0x6A, 0xAF, 0x68, 0xC5, 0x6C, 0x09, 0x2C, 0xD3, 0x8D, 0xC3, 0xBE, 0xF5, 0xD2, 0x0A, 0x93,\r
+  0x99, 0x26, 0xED, 0x4F, 0x74, 0xA1, 0x3E, 0xDD, 0xFB, 0xE1, 0xA1, 0xCE, 0xCC, 0x48, 0x94, 0xAF,\r
+  0x94, 0x28, 0xC2, 0xB7, 0xB8, 0x88, 0x3F, 0xE4, 0x46, 0x3A, 0x4B, 0xC8, 0x5B, 0x1C, 0xB3, 0xC1\r
+  };\r
+\r
+//\r
+// Known Answer Test (KAT) Data for RSA PKCS#1 Signing\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 RsaSignData[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";\r
+\r
+//\r
+// Known Signature for the above message, under SHA-1 Digest\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaPkcs1Signature[] = {\r
+  0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, 0x4A, 0xFD, 0x1A, 0x05,\r
+  0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51,\r
+  0x55, 0x77, 0x90, 0xCF, 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,\r
+  0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, 0x20, 0x22, 0xBE, 0x59,\r
+  0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF,\r
+  0x4E, 0xCA, 0x2E, 0x4E, 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,\r
+  0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, 0x72, 0x05, 0xDE, 0xE6,\r
+  0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4\r
+  };\r
+\r
+//\r
+// Default public key 0x10001 = 65537\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 DefaultPublicKey[] = {\r
+  0x01, 0x00, 0x01\r
+};\r
+\r
+/**\r
+  Validate UEFI-OpenSSL RSA Interfaces.\r
+\r
+  @retval  EFI_SUCCESS  Validation succeeded.\r
+  @retval  EFI_ABORTED  Validation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+ValidateCryptRsa (\r
+  VOID\r
+  )\r
+{\r
+  VOID     *Rsa;\r
+  UINT8    HashValue[SHA1_DIGEST_SIZE];\r
+  UINTN    HashSize;\r
+  UINTN    CtxSize;\r
+  VOID     *Sha1Ctx;\r
+  UINT8    *Signature;\r
+  UINTN    SigSize;\r
+  BOOLEAN  Status;\r
+  UINTN    KeySize;\r
+  UINT8    *KeyBuffer;\r
+\r
+  Print (L"\nUEFI-OpenSSL RSA Engine Testing: ");\r
+\r
+  //\r
+  // Generate & Initialize RSA Context\r
+  //\r
+  Rsa = RsaNew ();\r
+  Print (L"\n- Generate RSA Context ... ");\r
+  if (Rsa == NULL) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Set/Get RSA Key Components\r
+  //\r
+  Print (L"Set/Get RSA Key Components ... ");\r
+\r
+  //\r
+  // Set/Get RSA Key N\r
+  //\r
+  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeySize = 0;\r
+  Status = RsaGetKey (Rsa, RsaKeyN, NULL, &KeySize);\r
+  if (Status || KeySize != sizeof (RsaN)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeyBuffer = AllocatePool (KeySize);\r
+  Status = RsaGetKey (Rsa, RsaKeyN, KeyBuffer, &KeySize);\r
+  if (!Status || KeySize != sizeof (RsaN)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (KeyBuffer, RsaN, KeySize) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (KeyBuffer);\r
+\r
+  //\r
+  // Set/Get RSA Key E\r
+  //\r
+  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeySize = 0;\r
+  Status = RsaGetKey (Rsa, RsaKeyE, NULL, &KeySize);\r
+  if (Status || KeySize != sizeof (RsaE)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeyBuffer = AllocatePool (KeySize);\r
+  Status = RsaGetKey (Rsa, RsaKeyE, KeyBuffer, &KeySize);\r
+  if (!Status || KeySize != sizeof (RsaE)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (KeyBuffer, RsaE, KeySize) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (KeyBuffer);\r
+\r
+  //\r
+  // Clear/Get RSA Key Components\r
+  //\r
+  Print (L"Clear/Get RSA Key Components ... ");\r
+\r
+  //\r
+  // Clear/Get RSA Key N\r
+  //\r
+  Status = RsaSetKey (Rsa, RsaKeyN, NULL, 0);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeySize = 1;\r
+  Status = RsaGetKey (Rsa, RsaKeyN, NULL, &KeySize);\r
+  if (!Status || KeySize != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Clear/Get RSA Key E\r
+  //\r
+  Status = RsaSetKey (Rsa, RsaKeyE, NULL, 0);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeySize = 1;\r
+  Status = RsaGetKey (Rsa, RsaKeyE, NULL, &KeySize);\r
+  if (!Status || KeySize != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Generate RSA Key Components\r
+  //\r
+  Print (L"Generate RSA Key Components ... ");\r
+\r
+  Status = RsaGenerateKey (Rsa, RSA_MODULUS_LENGTH, NULL, 0);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeySize = RSA_MODULUS_LENGTH / 8;\r
+  KeyBuffer = AllocatePool (KeySize);\r
+  Status = RsaGetKey (Rsa, RsaKeyE, KeyBuffer, &KeySize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+  \r
+  if (KeySize != 3 ||\r
+      CompareMem (KeyBuffer, DefaultPublicKey, 3) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  KeySize = RSA_MODULUS_LENGTH / 8;\r
+  Status = RsaGetKey (Rsa, RsaKeyN, KeyBuffer, &KeySize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (KeySize != RSA_MODULUS_LENGTH / 8) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (!RsaCheckKey (Rsa)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Check invalid RSA key components\r
+  //\r
+  Print (L"Check Invalid RSA Key Components ... ");\r
+\r
+  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (RsaCheckKey (Rsa)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = RsaSetKey (Rsa, RsaKeyN, KeyBuffer, KeySize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (!RsaCheckKey (Rsa)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (RsaCheckKey (Rsa)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (KeyBuffer);\r
+\r
+  //\r
+  // SHA-1 Digest Message for PKCS#1 Signature \r
+  //\r
+  Print (L"Hash Original Message ... ");\r
+  HashSize = SHA1_DIGEST_SIZE;\r
+  ZeroMem (HashValue, HashSize);\r
+  CtxSize = Sha1GetContextSize ();\r
+  Sha1Ctx = AllocatePool (CtxSize);\r
+\r
+  Status  = Sha1Init (Sha1Ctx);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status  = Sha1Update (Sha1Ctx, RsaSignData, AsciiStrLen (RsaSignData));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status  = Sha1Final (Sha1Ctx, HashValue);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  FreePool (Sha1Ctx);\r
+\r
+  //\r
+  // Sign RSA PKCS#1-encoded Signature\r
+  //\r
+  Print (L"PKCS#1 Signature ... ");\r
+\r
+  RsaFree (Rsa);\r
+\r
+  Rsa = RsaNew ();\r
+  if (Rsa == NULL) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = RsaSetKey (Rsa, RsaKeyD, RsaD, sizeof (RsaD));\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  SigSize = 0;\r
+  Status  = RsaPkcs1Sign (Rsa, HashValue, HashSize, NULL, &SigSize);\r
+  if (Status || SigSize == 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Signature = AllocatePool (SigSize);\r
+  Status  = RsaPkcs1Sign (Rsa, HashValue, HashSize, Signature, &SigSize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (SigSize != sizeof (RsaPkcs1Signature)) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  if (CompareMem (Signature, RsaPkcs1Signature, SigSize) != 0) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Verify RSA PKCS#1-encoded Signature\r
+  //\r
+\r
+  Print (L"PKCS#1 Signature Verification ... ");\r
+\r
+  Status = RsaPkcs1Verify (Rsa, HashValue, HashSize, Signature, SigSize);\r
+  if (!Status) {\r
+    Print (L"[Fail]");\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  //\r
+  // Release Resources\r
+  //\r
+  RsaFree (Rsa);\r
+  Print (L"Release RSA Context ... [Pass]");\r
+\r
+  Print (L"\n");\r
+\r
+  return EFI_SUCCESS;\r
+}\r
index c5a7d4a..8df9e30 100644 (file)
 #\r
 ################################################################################\r
 [PcdsFeatureFlag]\r
-  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE\r
-  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|FALSE\r
   gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE\r
   gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE\r
 \r
 [PcdsFixedAtBuild]\r
-  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000\r
-  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000\r
-  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000\r
-\r
   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f\r
   gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000\r
   gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06\r
-  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF\r
-  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0\r
-  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0\r
-  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320\r
 \r
 ###################################################################################################\r
 #\r
 \r
   CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf\r
 \r
+[Components.IA32, Components.X64]\r
+  CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf\r
+\r
 [Components.IPF]\r
   CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/BaseCryptLibRuntimeCryptProtocol.inf\r
index 556026e..ee8c44d 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Defines base cryptographic library APIs.\r
   The Base Cryptographic Library provides implementations of basic cryptography\r
-  primitives (MD5, SHA-1, SHA-256, RSA, etc) for UEFI security functionality enabling.\r
+  primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security\r
+  functionality enabling.\r
 \r
 Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
@@ -32,6 +33,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 ///\r
 #define SHA256_DIGEST_SIZE  32\r
 \r
+///\r
+/// TDES block size in bytes\r
+///\r
+#define TDES_BLOCK_SIZE     8\r
+\r
+///\r
+/// AES block size in bytes\r
+///\r
+#define AES_BLOCK_SIZE      16\r
+\r
 ///\r
 /// RSA Key Tags Definition used in RsaSetKey() function for key component identification.\r
 ///\r
@@ -62,14 +73,13 @@ Md5GetContextSize (
   VOID\r
   );\r
 \r
-\r
 /**\r
   Initializes user-supplied memory pointed by Md5Context as MD5 hash context for\r
   subsequent use.\r
 \r
   If Md5Context is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Md5Context  Pointer to MD5 Context being initialized.\r
+  @param[out]  Md5Context  Pointer to MD5 context being initialized.\r
 \r
   @retval TRUE   MD5 context initialization succeeded.\r
   @retval FALSE  MD5 context initialization failed.\r
@@ -78,23 +88,45 @@ Md5GetContextSize (
 BOOLEAN\r
 EFIAPI\r
 Md5Init (\r
-  IN OUT  VOID  *Md5Context\r
+  OUT  VOID  *Md5Context\r
   );\r
 \r
+/**\r
+  Makes a copy of an existing MD5 context.\r
+\r
+  If Md5Context is NULL, then ASSERT().\r
+  If NewMd5Context is NULL, then ASSERT().\r
+\r
+  @param[in]  Md5Context     Pointer to MD5 context being copied.\r
+  @param[out] NewMd5Context  Pointer to new MD5 context.\r
+\r
+  @retval TRUE   MD5 context copy succeeded.\r
+  @retval FALSE  MD5 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Duplicate (\r
+  IN   CONST VOID  *Md5Context,\r
+  OUT  VOID        *NewMd5Context\r
+  );\r
 \r
 /**\r
-  Performs MD5 digest on a data buffer of the specified length. This function can\r
-  be called multiple times to compute the digest of long or discontinuous data streams.\r
+  Digests the input data and updates MD5 context.\r
+\r
+  This function performs MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized\r
+  by Md5Final(). Behavior with invalid context is undefined.\r
 \r
   If Md5Context is NULL, then ASSERT().\r
 \r
   @param[in, out]  Md5Context  Pointer to the MD5 context.\r
   @param[in]       Data        Pointer to the buffer containing the data to be hashed.\r
-  @param[in]       DataLength  Length of Data buffer in bytes.\r
+  @param[in]       DataSize    Size of Data buffer in bytes.\r
 \r
   @retval TRUE   MD5 data digest succeeded.\r
-  @retval FALSE  Invalid MD5 context. After Md5Final function has been called, the\r
-                 MD5 context cannot be reused.\r
+  @retval FALSE  MD5 data digest failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -102,18 +134,22 @@ EFIAPI
 Md5Update (\r
   IN OUT  VOID        *Md5Context,\r
   IN      CONST VOID  *Data,\r
-  IN      UINTN       DataLength\r
+  IN      UINTN       DataSize\r
   );\r
 \r
-\r
 /**\r
-  Completes MD5 hash computation and retrieves the digest value into the specified\r
-  memory. After this function has been called, the MD5 context cannot be used again.\r
+  Completes computation of the MD5 digest value.\r
+\r
+  This function completes MD5 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the MD5 context cannot\r
+  be used again.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be\r
+  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.\r
 \r
   If Md5Context is NULL, then ASSERT().\r
   If HashValue is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Md5Context  Pointer to the MD5 context\r
+  @param[in, out]  Md5Context  Pointer to the MD5 context.\r
   @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest\r
                                value (16 bytes).\r
 \r
@@ -128,7 +164,6 @@ Md5Final (
   OUT     UINT8  *HashValue\r
   );\r
 \r
-\r
 /**\r
   Retrieves the size, in bytes, of the context buffer required for SHA-1 hash operations.\r
 \r
@@ -141,39 +176,60 @@ Sha1GetContextSize (
   VOID\r
   );\r
 \r
-\r
 /**\r
-  Initializes user-supplied memory pointed by Sha1Context as the SHA-1 hash context for\r
+  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for\r
   subsequent use.\r
 \r
   If Sha1Context is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha1Context  Pointer to the SHA-1 Context being initialized.\r
+  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.\r
 \r
-  @retval TRUE   SHA-1 initialization succeeded.\r
-  @retval FALSE  SHA-1 initialization failed.\r
+  @retval TRUE   SHA-1 context initialization succeeded.\r
+  @retval FALSE  SHA-1 context initialization failed.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 Sha1Init (\r
-  IN OUT  VOID  *Sha1Context\r
+  OUT  VOID  *Sha1Context\r
   );\r
 \r
+/**\r
+  Makes a copy of an existing SHA-1 context.\r
+\r
+  If Sha1Context is NULL, then ASSERT().\r
+  If NewSha1Context is NULL, then ASSERT().\r
+\r
+  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.\r
+  @param[out] NewSha1Context  Pointer to new SHA-1 context.\r
+\r
+  @retval TRUE   SHA-1 context copy succeeded.\r
+  @retval FALSE  SHA-1 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Duplicate (\r
+  IN   CONST VOID  *Sha1Context,\r
+  OUT  VOID        *NewSha1Context\r
+  );\r
 \r
 /**\r
-  Performs SHA-1 digest on a data buffer of the specified length. This function can\r
-  be called multiple times to compute the digest of long or discontinuous data streams.\r
+  Digests the input data and updates SHA-1 context.\r
+\r
+  This function performs SHA-1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be finalized\r
+  by Sha1Final(). Behavior with invalid context is undefined.\r
 \r
   If Sha1Context is NULL, then ASSERT().\r
 \r
   @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
   @param[in]       Data         Pointer to the buffer containing the data to be hashed.\r
-  @param[in]       DataLength   Length of Data buffer in bytes.\r
+  @param[in]       DataSize     Size of Data buffer in bytes.\r
 \r
   @retval TRUE   SHA-1 data digest succeeded.\r
-  @retval FALSE  Invalid SHA-1 context. After Sha1Final function has been called, the\r
-                 SHA-1 context cannot be reused.\r
+  @retval FALSE  SHA-1 data digest failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -181,18 +237,22 @@ EFIAPI
 Sha1Update (\r
   IN OUT  VOID        *Sha1Context,\r
   IN      CONST VOID  *Data,\r
-  IN      UINTN       DataLength\r
+  IN      UINTN       DataSize\r
   );\r
 \r
-\r
 /**\r
-  Completes SHA-1 hash computation and retrieves the digest value into the specified\r
-  memory. After this function has been called, the SHA-1 context cannot be used again.\r
+  Completes computation of the SHA-1 digest value.\r
+\r
+  This function completes SHA-1 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-1 context cannot\r
+  be used again.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be\r
+  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.\r
 \r
   If Sha1Context is NULL, then ASSERT().\r
   If HashValue is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha1Context  Pointer to the SHA-1 context\r
+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
   @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest\r
                                 value (20 bytes).\r
 \r
@@ -207,11 +267,10 @@ Sha1Final (
   OUT     UINT8  *HashValue\r
   );\r
 \r
-\r
 /**\r
-  Retrieves the size, in bytes, of the context buffer required for SHA-256 operations.\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.\r
 \r
-  @return  The size, in bytes, of the context buffer required for SHA-256 operations.\r
+  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.\r
 \r
 **/\r
 UINTN\r
@@ -220,14 +279,13 @@ Sha256GetContextSize (
   VOID\r
   );\r
 \r
-\r
 /**\r
   Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for\r
   subsequent use.\r
 \r
   If Sha256Context is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha256Context  Pointer to SHA-256 Context being initialized.\r
+  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.\r
 \r
   @retval TRUE   SHA-256 context initialization succeeded.\r
   @retval FALSE  SHA-256 context initialization failed.\r
@@ -236,23 +294,45 @@ Sha256GetContextSize (
 BOOLEAN\r
 EFIAPI\r
 Sha256Init (\r
-  IN OUT  VOID  *Sha256Context\r
+  OUT  VOID  *Sha256Context\r
   );\r
 \r
+/**\r
+  Makes a copy of an existing SHA-256 context.\r
+\r
+  If Sha256Context is NULL, then ASSERT().\r
+  If NewSha256Context is NULL, then ASSERT().\r
+\r
+  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.\r
+  @param[out] NewSha256Context  Pointer to new SHA-256 context.\r
+\r
+  @retval TRUE   SHA-256 context copy succeeded.\r
+  @retval FALSE  SHA-256 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Duplicate (\r
+  IN   CONST VOID  *Sha256Context,\r
+  OUT  VOID        *NewSha256Context\r
+  );\r
 \r
 /**\r
-  Performs SHA-256 digest on a data buffer of the specified length. This function can\r
-  be called multiple times to compute the digest of long or discontinuous data streams.\r
+  Digests the input data and updates SHA-256 context.\r
+\r
+  This function performs SHA-256 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be finalized\r
+  by Sha256Final(). Behavior with invalid context is undefined.\r
 \r
   If Sha256Context is NULL, then ASSERT().\r
 \r
   @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
   @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
-  @param[in]       DataLength     Length of Data buffer in bytes.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
 \r
   @retval TRUE   SHA-256 data digest succeeded.\r
-  @retval FALSE  Invalid SHA-256 context. After Sha256Final function has been called, the\r
-                 SHA-256 context cannot be reused.\r
+  @retval FALSE  SHA-256 data digest failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -260,18 +340,22 @@ EFIAPI
 Sha256Update (\r
   IN OUT  VOID        *Sha256Context,\r
   IN      CONST VOID  *Data,\r
-  IN      UINTN       DataLength\r
+  IN      UINTN       DataSize\r
   );\r
 \r
-\r
 /**\r
-  Completes SHA-256 hash computation and retrieves the digest value into the specified\r
-  memory. After this function has been called, the SHA-256 context cannot be used again.\r
+  Completes computation of the SHA-256 digest value.\r
+\r
+  This function completes SHA-256 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-256 context cannot\r
+  be used again.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be\r
+  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.\r
 \r
   If Sha256Context is NULL, then ASSERT().\r
   If HashValue is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha256Context  Pointer to SHA-256 context\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
   @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest\r
                                   value (32 bytes).\r
 \r
@@ -291,28 +375,717 @@ Sha256Final (
 //    MAC (Message Authentication Code) Primitive\r
 //=====================================================================================\r
 \r
-///\r
-/// No MAC supports for minimum scope required by UEFI\r
-///\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacMd5GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for\r
+  subsequent use.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+\r
+  @param[out]  HmacMd5Context  Pointer to HMAC-MD5 context being initialized.\r
+  @param[in]   Key             Pointer to the user-supplied key.\r
+  @param[in]   KeySize         Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 context initialization succeeded.\r
+  @retval FALSE  HMAC-MD5 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Init (\r
+  OUT  VOID         *HmacMd5Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-MD5 context.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+  If NewHmacMd5Context is NULL, then ASSERT().\r
+\r
+  @param[in]  HmacMd5Context     Pointer to HMAC-MD5 context being copied.\r
+  @param[out] NewHmacMd5Context  Pointer to new HMAC-MD5 context.\r
+\r
+  @retval TRUE   HMAC-MD5 context copy succeeded.\r
+  @retval FALSE  HMAC-MD5 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Duplicate (\r
+  IN   CONST VOID  *HmacMd5Context,\r
+  OUT  VOID        *NewHmacMd5Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates HMAC-MD5 context.\r
+\r
+  This function performs HMAC-MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 data digest succeeded.\r
+  @retval FALSE  HMAC-MD5 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Update (\r
+  IN OUT  VOID        *HmacMd5Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the HMAC-MD5 digest value.\r
+\r
+  This function completes HMAC-MD5 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-MD5 context cannot\r
+  be used again.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+  If HashValue is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[out]      HashValue       Pointer to a buffer that receives the HMAC-MD5 digest\r
+                                   value (16 bytes).\r
+\r
+  @retval TRUE   HMAC-MD5 digest computation succeeded.\r
+  @retval FALSE  HMAC-MD5 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Final (\r
+  IN OUT  VOID   *HmacMd5Context,\r
+  OUT     UINT8  *HmacValue\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacSha1GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for\r
+  subsequent use.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+\r
+  @param[out]  HmacSha1Context  Pointer to HMAC-SHA1 context being initialized.\r
+  @param[in]   Key              Pointer to the user-supplied key.\r
+  @param[in]   KeySize          Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 context initialization succeeded.\r
+  @retval FALSE  HMAC-SHA1 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Init (\r
+  OUT  VOID         *HmacSha1Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  );\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-SHA1 context.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+  If NewHmacSha1Context is NULL, then ASSERT().\r
+\r
+  @param[in]  HmacSha1Context     Pointer to HMAC-SHA1 context being copied.\r
+  @param[out] NewHmacSha1Context  Pointer to new HMAC-SHA1 context.\r
+\r
+  @retval TRUE   HMAC-SHA1 context copy succeeded.\r
+  @retval FALSE  HMAC-SHA1 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Duplicate (\r
+  IN   CONST VOID  *HmacSha1Context,\r
+  OUT  VOID        *NewHmacSha1Context\r
+  );\r
+\r
+/**\r
+  Digests the input data and updates HMAC-SHA1 context.\r
+\r
+  This function performs HMAC-SHA1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not\r
+  be finalized by HmacSha1Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacSha1Context Pointer to the HMAC-SHA1 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 data digest succeeded.\r
+  @retval FALSE  HMAC-SHA1 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Update (\r
+  IN OUT  VOID        *HmacSha1Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  );\r
+\r
+/**\r
+  Completes computation of the HMAC-SHA1 digest value.\r
+\r
+  This function completes HMAC-SHA1 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-SHA1 context cannot\r
+  be used again.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should\r
+  not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+  If HashValue is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacSha1Context  Pointer to the HMAC-SHA1 context.\r
+  @param[out]      HashValue        Pointer to a buffer that receives the HMAC-SHA1 digest\r
+                                    value (20 bytes).\r
+\r
+  @retval TRUE   HMAC-SHA1 digest computation succeeded.\r
+  @retval FALSE  HMAC-SHA1 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Final (\r
+  IN OUT  VOID   *HmacSha1Context,\r
+  OUT     UINT8  *HmacValue\r
+  );\r
 \r
 \r
 //=====================================================================================\r
 //    Symmetric Cryptography Primitive\r
 //=====================================================================================\r
 \r
-///\r
-/// No symmetric cryptographic supports for minimum scope required by UEFI\r
-///\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for TDES operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for TDES operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+TdesGetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory as TDES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by TdesContext as TDES context.\r
+  In addtion, it sets up all TDES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 key options as follows:\r
+  KeyLength = 64,  Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)\r
+  KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)\r
+  KeyLength = 192  Keying option 3: K1 != K2 != K3 (Strongest)\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Key is NULL, then ASSERT().\r
+  If KeyLength is not valid, then ASSERT().\r
+\r
+  @param[out]  TdesContext  Pointer to TDES context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied TDES key.\r
+  @param[in]   KeyLength    Length of TDES key in bits.\r
+\r
+  @retval TRUE   TDES context initialization succeeded.\r
+  @retval FALSE  TDES context initialization failed.\r
 \r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesInit (\r
+  OUT  VOID         *TdesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  );\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES decryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for AES operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for AES operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AesGetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory as AES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by AesContext as AES context.\r
+  In addtion, it sets up all AES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Key is NULL, then ASSERT().\r
+  If KeyLength is not valid, then ASSERT().\r
+\r
+  @param[out]  AesContext  Pointer to AES context being initialized.\r
+  @param[in]   Key         Pointer to the user-supplied AES key.\r
+  @param[in]   KeyLength   Length of AES key in bits.\r
+\r
+  @retval TRUE   AES context initialization succeeded.\r
+  @retval FALSE  AES context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesInit (\r
+  OUT  VOID         *AesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  );\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES decryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Arc4GetContextSize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initializes user-supplied memory as ARC4 context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.\r
+  In addtion, it sets up all ARC4 key materials for subsequent encryption and decryption\r
+  operations.\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+  If Key is NULL, then ASSERT().\r
+  If KeySize does not in the range of [5, 256] bytes, then ASSERT().\r
+\r
+  @param[out]  Arc4Context  Pointer to ARC4 context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied ARC4 key.\r
+  @param[in]   KeySize      Size of ARC4 key in bytes.\r
+\r
+  @retval TRUE   ARC4 context initialization succeeded.\r
+  @retval FALSE  ARC4 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Init (\r
+  OUT  VOID         *Arc4Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  );\r
+\r
+/**\r
+  Performs ARC4 encryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 encryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the ARC4 encryption output.\r
+\r
+  @retval TRUE   ARC4 encryption succeeded.\r
+  @retval FALSE  ARC4 encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Encrypt (\r
+  IN OUT  VOID         *Arc4Context,\r
+  IN      CONST UINT8  *Input,\r
+  IN      UINTN        InputSize,\r
+  OUT     UINT8        *Output\r
+  );\r
+\r
+/**\r
+  Performs ARC4 decryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 decryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the ARC4 decryption output.\r
+\r
+  @retval TRUE   ARC4 decryption succeeded.\r
+  @retval FALSE  ARC4 decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Decrypt (\r
+  IN OUT  VOID   *Arc4Context,\r
+  IN      UINT8  *Input,\r
+  IN      UINTN  InputSize,\r
+  OUT     UINT8  *Output\r
+  );\r
+\r
+/**\r
+  Resets the ARC4 context to the initial state.\r
+\r
+  The function resets the ARC4 context to the state it had immediately after the\r
+  ARC4Init() function call.\r
+  Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context\r
+  should be already correctly initialized by ARC4Init().\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+\r
+  @retval TRUE   ARC4 reset succeeded.\r
+  @retval FALSE  ARC4 reset failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Reset (\r
+  IN OUT  VOID  *Arc4Context\r
+  );\r
 \r
 //=====================================================================================\r
 //    Asymmetric Cryptography Primitive\r
 //=====================================================================================\r
 \r
 /**\r
-  Allocates and Initializes one RSA Context for subsequent use.\r
+  Allocates and initializes one RSA context for subsequent use.\r
 \r
-  @return  Pointer to the RSA Context that has been initialized.\r
+  @return  Pointer to the RSA context that has been initialized.\r
            If the allocations fails, RsaNew() returns NULL.\r
 \r
 **/\r
@@ -322,9 +1095,10 @@ RsaNew (
   VOID\r
   );\r
 \r
-\r
 /**\r
-  Release the specified RSA Context.\r
+  Release the specified RSA context.\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
 \r
   @param[in]  RsaContext  Pointer to the RSA context to be released.\r
 \r
@@ -335,32 +1109,159 @@ RsaFree (
   IN  VOID  *RsaContext\r
   );\r
 \r
-\r
 /**\r
-  Sets the tag-designated RSA key component into the established RSA context from\r
-  the user-specified nonnegative integer (octet string format represented in RSA\r
-  PKCS#1).\r
+  Sets the tag-designated key component into the established RSA context.\r
+\r
+  This function sets the tag-designated RSA key component into the established\r
+  RSA context from the user-specified non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If BigNumber is NULL, then the specified key componenet in RSA context is cleared.\r
 \r
   If RsaContext is NULL, then ASSERT().\r
 \r
   @param[in, out]  RsaContext  Pointer to RSA context being set.\r
   @param[in]       KeyTag      Tag of RSA key component being set.\r
   @param[in]       BigNumber   Pointer to octet integer buffer.\r
-  @param[in]       BnLength    Length of big number buffer in bytes.\r
+                               If NULL, then the specified key componenet in RSA\r
+                               context is cleared.\r
+  @param[in]       BnSize      Size of big number buffer in bytes.\r
+                               If BigNumber is NULL, then it is ignored.\r
 \r
-  @return  TRUE   RSA key component was set successfully.\r
-  @return  FALSE  Invalid RSA key component tag.\r
+  @retval  TRUE   RSA key component was set successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 RsaSetKey (\r
-  IN OUT VOID         *RsaContext,\r
-  IN     RSA_KEY_TAG  KeyTag,\r
-  IN     CONST UINT8  *BigNumber,\r
-  IN     UINTN        BnLength\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  IN      CONST UINT8  *BigNumber,\r
+  IN      UINTN        BnSize\r
+  );\r
+\r
+/**\r
+  Gets the tag-designated RSA key component from the established RSA context.\r
+\r
+  This function retrieves the tag-designated RSA key component from the\r
+  established RSA context as a non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If specified key component has not been set or has been cleared, then returned\r
+  BnSize is set to 0.\r
+  If the BigNumber buffer is too small to hold the contents of the key, FALSE\r
+  is returned and BnSize is set to the required buffer size to obtain the key.\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+  If BnSize is NULL, then ASSERT().\r
+  If BnSize is large enough but BigNumber is NULL, then ASSERT().\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[out]      BigNumber   Pointer to octet integer buffer.\r
+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.\r
+                               On output, the size of data returned in big number buffer in bytes.\r
+\r
+  @retval  TRUE   RSA key component was retrieved successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+  @retval  FALSE  BnSize is too small.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  OUT     UINT8        *BigNumber,\r
+  IN OUT  UINTN        *BnSize\r
+  );\r
+\r
+/**\r
+  Generates RSA key components.\r
+\r
+  This function generates RSA key components. It takes RSA public exponent E and\r
+  length in bits of RSA modulus N as input, and generates all key components.\r
+  If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.\r
+\r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+\r
+  @param[in, out]  RsaContext           Pointer to RSA context being set.\r
+  @param[in]       ModulusLength        Length of RSA modulus N in bits.\r
+  @param[in]       PublicExponent       Pointer to RSA public exponent.\r
+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes. \r
+\r
+  @retval  TRUE   RSA key component was generated successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGenerateKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      UINTN        ModulusLength,\r
+  IN      CONST UINT8  *PublicExponent,\r
+  IN      UINTN        PublicExponentSize\r
+  );\r
+\r
+/**\r
+  Validates key components of RSA context.\r
+\r
+  This function validates key compoents of RSA context in following aspects:\r
+  - Whether p is a prime\r
+  - Whether q is a prime\r
+  - Whether n = p * q\r
+  - Whether d*e = 1  mod lcm(p-1,q-1)\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+\r
+  @param[in]  RsaContext  Pointer to RSA context to check.\r
+\r
+  @retval  TRUE   RSA key components are valid.\r
+  @retval  FALSE  RSA key components are not valid.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaCheckKey (\r
+  IN  VOID  *RsaContext\r
   );\r
 \r
+/**\r
+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.\r
+\r
+  This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in\r
+  RSA PKCS#1.\r
+  If the Signature buffer is too small to hold the contents of signature, FALSE\r
+  is returned and SigSize is set to the required buffer size to obtain the signature.\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+  If MessageHash is NULL, then ASSERT().\r
+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().\r
+  If SigSize is large enough but Signature is NULL, then ASSERT().\r
+\r
+  @param[in]      RsaContext   Pointer to RSA context for signature generation.\r
+  @param[in]      MessageHash  Pointer to octet message hash to be signed.\r
+  @param[in]      HashSize     Size of the message hash in bytes.\r
+  @param[out]     Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.\r
+  @param[in, out] SigSize      On input, the size of Signature buffer in bytes.\r
+                              On output, the size of data returned in Signature buffer in bytes.\r
+\r
+  @retval  TRUE   Signature successfully generated in PKCS1-v1_5.\r
+  @retval  FALSE  Signature generation failed.\r
+  @retval  FALSE  SigSize is too small.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaPkcs1Sign (\r
+  IN      VOID         *RsaContext,\r
+  IN      CONST UINT8  *MessageHash,\r
+  IN      UINTN        HashSize,\r
+  OUT     UINT8        *Signature,\r
+  IN OUT  UINTN        *SigSize\r
+  );\r
 \r
 /**\r
   Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in\r
@@ -369,16 +1270,16 @@ RsaSetKey (
   If RsaContext is NULL, then ASSERT().\r
   If MessageHash is NULL, then ASSERT().\r
   If Signature is NULL, then ASSERT().\r
-  If HashLength is not equal to the size of MD5, SHA-1 or SHA-256 digest, then ASSERT().\r
+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().\r
 \r
   @param[in]  RsaContext   Pointer to RSA context for signature verification.\r
   @param[in]  MessageHash  Pointer to octet message hash to be checked.\r
-  @param[in]  HashLength   Length of the message hash in bytes.\r
+  @param[in]  HashSize     Size of the message hash in bytes.\r
   @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.\r
-  @param[in]  SigLength    Length of signature in bytes.\r
+  @param[in]  SigSize      Size of signature in bytes.\r
 \r
-  @return  TRUE   Valid signature encoded in PKCS1-v1_5.\r
-  @return  FALSE  Invalid signature or invalid RSA context.\r
+  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.\r
+  @retval  FALSE  Invalid signature or invalid RSA context.\r
 \r
 **/\r
 BOOLEAN\r
@@ -386,12 +1287,11 @@ EFIAPI
 RsaPkcs1Verify (\r
   IN  VOID         *RsaContext,\r
   IN  CONST UINT8  *MessageHash,\r
-  IN  UINTN        HashLength,\r
+  IN  UINTN        HashSize,\r
   IN  UINT8        *Signature,\r
-  IN  UINTN        SigLength\r
+  IN  UINTN        SigSize\r
   );\r
 \r
-\r
 /**\r
   Verifies the validility of a PKCS#7 signed data as described in "PKCS #7: Cryptographic\r
   Message Syntax Standard".\r
@@ -399,27 +1299,227 @@ RsaPkcs1Verify (
   If P7Data is NULL, then ASSERT().\r
 \r
   @param[in]  P7Data       Pointer to the PKCS#7 message to verify.\r
-  @param[in]  P7Length     Length of the PKCS#7 message in bytes.\r
+  @param[in]  P7Size       Size of the PKCS#7 message in bytes.\r
   @param[in]  TrustedCert  Pointer to a trusted/root certificate encoded in DER, which\r
                            is used for certificate chain verification.\r
-  @param[in]  CertLength   Length of the trusted certificate in bytes.\r
+  @param[in]  CertSize     Size of the trusted certificate in bytes.\r
   @param[in]  InData       Pointer to the content to be verified.\r
-  @param[in]  DataLength   Length of InData in bytes.\r
+  @param[in]  DataSize     Size of InData in bytes.\r
 \r
-  @return  TRUE  The specified PKCS#7 signed data is valid.\r
-  @return  FALSE Invalid PKCS#7 signed data.\r
+  @retval  TRUE  The specified PKCS#7 signed data is valid.\r
+  @retval  FALSE Invalid PKCS#7 signed data.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 Pkcs7Verify (\r
   IN  CONST UINT8  *P7Data,\r
-  IN  UINTN        P7Length,\r
+  IN  UINTN        P7Size,\r
   IN  CONST UINT8  *TrustedCert,\r
-  IN  UINTN        CertLength,\r
+  IN  UINTN        CertSize,\r
   IN  CONST UINT8  *InData,\r
-  IN  UINTN        DataLength\r
+  IN  UINTN        DataSize\r
+  );\r
+\r
+//=====================================================================================\r
+//    DH Key Exchange Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.\r
+\r
+  @return  Pointer to the Diffie-Hellman Context that has been initialized.\r
+           If the allocations fails, DhNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DhNew (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Release the specified DH context.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+\r
+  @param[in]  DhContext  Pointer to the DH context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DhFree (\r
+  IN  VOID  *DhContext\r
+  );\r
+\r
+/**\r
+  Generates DH parameter.\r
+\r
+  Given generator g, and length of prime number p in bits, this function generates p,\r
+  and sets DH context according to value of g and p.\r
+  \r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If Prime is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.\r
+\r
+  @retval TRUE   DH pamameter generation succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateParameter (\r
+  IN OUT  VOID   *DhContext,\r
+  IN      UINTN  Generator,\r
+  IN      UINTN  PrimeLength,\r
+  OUT     UINT8  *Prime\r
+  );\r
+\r
+/**\r
+  Sets generator and prime parameters for DH.\r
+\r
+  Given generator g, and prime number p, this function and sets DH\r
+  context accordingly.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If Prime is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[in]       Prime        Pointer to the prime number.\r
+\r
+  @retval TRUE   DH pamameter setting succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  Value of Generator is not suitable for the Prime.\r
+  @retval FALSE  Value of Prime is not a prime number.\r
+  @retval FALSE  Value of Prime is not a safe prime number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhSetParameter (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      UINTN        Generator,\r
+  IN      UINTN        PrimeLength,\r
+  IN      CONST UINT8  *Prime\r
   );\r
 \r
+/**\r
+  Generates DH public key.\r
+\r
+  This function generates random secret exponent, and computes the public key, which is \r
+  returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.\r
+  If the PublicKey buffer is too small to hold the public key, FALSE is returned and\r
+  PublicKeySize is set to the required buffer size to obtain the public key.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If PublicKeySize is NULL, then ASSERT().\r
+  If PublicKeySize is large enough but PublicKey is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext      Pointer to the DH context.\r
+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.\r
+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.\r
+                                 On output, the size of data returned in PublicKey buffer in bytes.\r
+\r
+  @retval TRUE   DH public key generation succeeded.\r
+  @retval FALSE  DH public key generation failed.\r
+  @retval FALSE  PublicKeySize is not large enough.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateKey (\r
+  IN OUT  VOID   *DhContext,\r
+  OUT     UINT8  *PublicKey,\r
+  IN OUT  UINTN  *PublicKeySize\r
+  );\r
+\r
+/**\r
+  Computes exchanged common key.\r
+\r
+  Given peer's public key, this function computes the exchanged common key, based on its own\r
+  context including value of prime modulus and random secret exponent. \r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If PeerPublicKey is NULL, then ASSERT().\r
+  If KeySize is NULL, then ASSERT().\r
+  If KeySize is large enough but Key is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext          Pointer to the DH context.\r
+  @param[in]       PeerPublicKey      Pointer to the peer's public key.\r
+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.\r
+  @param[out]      Key                Pointer to the buffer to receive generated key.\r
+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.\r
+                                     On output, the size of data returned in Key buffer in bytes.\r
+\r
+  @retval TRUE   DH exchanged key generation succeeded.\r
+  @retval FALSE  DH exchanged key generation failed.\r
+  @retval FALSE  KeySize is not large enough.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhComputeKey (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      CONST UINT8  *PeerPublicKey,\r
+  IN      UINTN        PeerPublicKeySize,\r
+  OUT     UINT8        *Key,\r
+  IN OUT  UINTN        *KeySize\r
+  );\r
+\r
+//=====================================================================================\r
+//    Pseudo-Random Generation Primitive\r
+//=====================================================================================\r
+\r
+/**\r
+  Sets up the seed value for the pseudorandom number generator.\r
+\r
+  This function sets up the seed value for the pseudorandom number generator.\r
+  If Seed is not NULL, then the seed passed in is used.\r
+  If Seed is NULL, then default seed is used.\r
+\r
+  @param[in]  Seed      Pointer to seed value.\r
+                        If NULL, default seed is used.\r
+  @param[in]  SeedSize  Size of seed value.\r
+                        If Seed is NULL, this parameter is ignored.\r
+\r
+  @retval TRUE   Pseudorandom number generator has enough entropy for random generation.\r
+  @retval FALSE  Pseudorandom number generator does not have enough entropy for random generation.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomSeed (\r
+  IN  CONST  UINT8  *Seed  OPTIONAL,\r
+  IN  UINTN         SeedSize\r
+  );\r
+\r
+/**\r
+  Generates a pseudorandom byte stream of the specified size.\r
+\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[out]  Output  Pointer to buffer to receive random value.\r
+  @param[in]   Size    Size of randome bytes to generate.\r
+\r
+  @retval TRUE   Pseudorandom byte stream generated successfully.\r
+  @retval FALSE  Pseudorandom number generator fails to generate due to lack of entropy.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomBytes (\r
+  OUT  UINT8  *Output,\r
+  IN   UINTN  Size\r
+  );\r
 \r
 #endif // __BASE_CRYPT_LIB_H__\r
index 5395da0..c941942 100644 (file)
 #\r
 \r
 [Sources]\r
+  InternalCryptLib.h\r
   Hash/CryptMd5.c\r
   Hash/CryptSha1.c\r
   Hash/CryptSha256.c\r
+  Hmac/CryptHmacMd5.c\r
+  Hmac/CryptHmacSha1.c\r
+  Cipher/CryptAes.c\r
+  Cipher/CryptTdes.c\r
+  Cipher/CryptArc4.c\r
+  Rand/CryptRand.c\r
   Pk/CryptRsa.c\r
   Pk/CryptPkcs7.c\r
+  Pk/CryptDh.c\r
 \r
   SysCall/CrtWrapper.c\r
   SysCall/TimerWrapper.c\r
@@ -58,8 +66,6 @@
   SysCall/Ia32/MathLShiftS64.S      | GCC\r
   SysCall/Ia32/MathRShiftU64.S      | GCC\r
 \r
-  SysCall/Ia32/Alloca.S             | GCC\r
-\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   CryptoPkg/CryptoPkg.dec\r
diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c
new file mode 100644 (file)
index 0000000..e32063c
--- /dev/null
@@ -0,0 +1,309 @@
+/** @file\r
+  AES Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/aes.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for AES operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for AES operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AesGetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // AES uses different key contexts for encryption and decryption, so here memory\r
+  // for 2 copies of AES_KEY is allocated.\r
+  //\r
+  return (UINTN) (2 * sizeof (AES_KEY));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory as AES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by AesContext as AES context.\r
+  In addtion, it sets up all AES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 options for key length, 128 bits, 192 bits, and 256 bits.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Key is NULL, then ASSERT().\r
+  If KeyLength is not valid, then ASSERT().\r
+\r
+  @param[out]  AesContext  Pointer to AES context being initialized.\r
+  @param[in]   Key         Pointer to the user-supplied AES key.\r
+  @param[in]   KeyLength   Length of AES key in bits.\r
+\r
+  @retval TRUE   AES context initialization succeeded.\r
+  @retval FALSE  AES context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesInit (\r
+  OUT  VOID         *AesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+\r
+  ASSERT (AesContext != NULL);\r
+  //\r
+  // AES Key Checking\r
+  //\r
+  ASSERT (Key != NULL);\r
+  ASSERT ((KeyLength == 128) || (KeyLength == 192) || (KeyLength == 256));\r
+\r
+  //\r
+  // Initialize AES encryption & decryption key schedule.\r
+  //\r
+  AesKey = (AES_KEY *) AesContext;\r
+  if (AES_set_encrypt_key (Key, (UINT32) KeyLength, AesKey) != 0) {\r
+    return FALSE;\r
+  }\r
+  if (AES_set_decrypt_key (Key, (UINT32) KeyLength, AesKey + 1) != 0) {\r
+    return FALSE;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+  \r
+  ASSERT (AesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);\r
+  ASSERT (Output != NULL);\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+\r
+  //\r
+  // Perform AES data encryption with ECB mode (block-by-block)\r
+  //\r
+  while (InputSize > 0) {\r
+    AES_ecb_encrypt (Input, Output, AesKey, AES_ENCRYPT);\r
+    Input     += AES_BLOCK_SIZE;\r
+    Output    += AES_BLOCK_SIZE;\r
+    InputSize -= AES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES decryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesEcbDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+  \r
+  ASSERT (AesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);\r
+  ASSERT (Output != NULL);\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+\r
+  //\r
+  // Perform AES data decryption with ECB mode (block-by-block)\r
+  //\r
+  while (InputSize > 0) {\r
+    AES_ecb_encrypt (Input, Output, AesKey + 1, AES_DECRYPT);\r
+    Input     += AES_BLOCK_SIZE;\r
+    Output    += AES_BLOCK_SIZE;\r
+    InputSize -= AES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES encryption succeeded.\r
+  @retval FALSE  AES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcEncrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+  UINT8    IvecBuffer[AES_BLOCK_SIZE];\r
+\r
+  ASSERT (AesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);\r
+  ASSERT (Ivec != NULL);\r
+  ASSERT (Output != NULL);\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
+\r
+  //\r
+  // Perform AES data encryption with CBC mode\r
+  //\r
+  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs AES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs AES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (16 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (16 bytes).\r
+  AesContext should be already correctly initialized by AesInit(). Behavior with\r
+  invalid AES context is undefined.\r
+\r
+  If AesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (16 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   AesContext  Pointer to the AES context.\r
+  @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize   Size of the Input buffer in bytes.\r
+  @param[in]   Ivec        Pointer to initialization vector.\r
+  @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
+\r
+  @retval TRUE   AES decryption succeeded.\r
+  @retval FALSE  AES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AesCbcDecrypt (\r
+  IN   VOID         *AesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  AES_KEY  *AesKey;\r
+  UINT8    IvecBuffer[AES_BLOCK_SIZE];\r
+  \r
+  ASSERT (AesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);\r
+  ASSERT (Ivec != NULL);\r
+  ASSERT (Output != NULL);\r
+\r
+  AesKey = (AES_KEY *) AesContext;\r
+  CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
+\r
+  //\r
+  // Perform AES data decryption with CBC mode\r
+  //\r
+  AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);\r
+\r
+  return TRUE;\r
+}\r
diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptArc4.c
new file mode 100644 (file)
index 0000000..fa8fd96
--- /dev/null
@@ -0,0 +1,197 @@
+/** @file\r
+  ARC4 Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/rc4.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for ARC4 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+Arc4GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Memory for 2 copies of RC4_KEY is allocated, one for working copy, and the other\r
+  // for backup copy. When Arc4Reset() is called, we can use the backup copy to restore\r
+  // the working copy to the initial state.\r
+  //\r
+  return (UINTN) (2 * sizeof(RC4_KEY));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory as ARC4 context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by Arc4Context as ARC4 context.\r
+  In addtion, it sets up all ARC4 key materials for subsequent encryption and decryption\r
+  operations.\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+  If Key is NULL, then ASSERT().\r
+  If KeySize does not in the range of [5, 256] bytes, then ASSERT().\r
+\r
+  @param[out]  Arc4Context  Pointer to ARC4 context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied ARC4 key.\r
+  @param[in]   KeySize      Size of ARC4 key in bytes.\r
+\r
+  @retval TRUE   ARC4 context initialization succeeded.\r
+  @retval FALSE  ARC4 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Init (\r
+  OUT  VOID         *Arc4Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  ASSERT (Arc4Context != NULL);\r
+  ASSERT (Key != NULL);\r
+  ASSERT ((KeySize >= 5) && (KeySize <= 256));\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  RC4_set_key (Rc4Key, (UINT32) KeySize, Key);\r
+\r
+  CopyMem (Rc4Key +  1, Rc4Key, sizeof(RC4_KEY));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs ARC4 encryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 encryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]       Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]       InputSize    Size of the Input buffer in bytes.\r
+  @param[out]      Output       Pointer to a buffer that receives the ARC4 encryption output.\r
+\r
+  @retval TRUE   ARC4 encryption succeeded.\r
+  @retval FALSE  ARC4 encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Encrypt (\r
+  IN OUT  VOID         *Arc4Context,\r
+  IN      CONST UINT8  *Input,\r
+  IN      UINTN        InputSize,\r
+  OUT     UINT8        *Output\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  ASSERT (Arc4Context != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT (Output != NULL);\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  RC4 (Rc4Key, (UINT32) InputSize, Input, Output);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs ARC4 decryption on a data buffer of the specified size.\r
+\r
+  This function performs ARC4 decryption on data buffer pointed by Input, of specified\r
+  size of InputSize.\r
+  Arc4Context should be already correctly initialized by Arc4Init(). Behavior with\r
+  invalid ARC4 context is undefined.\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+  @param[in]       Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]       InputSize    Size of the Input buffer in bytes.\r
+  @param[out]      Output       Pointer to a buffer that receives the ARC4 decryption output.\r
+\r
+  @retval TRUE   ARC4 decryption succeeded.\r
+  @retval FALSE  ARC4 decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Decrypt (\r
+  IN OUT  VOID   *Arc4Context,\r
+  IN      UINT8  *Input,\r
+  IN      UINTN  InputSize,\r
+  OUT     UINT8  *Output\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  ASSERT (Arc4Context != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT (Output != NULL);\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  RC4 (Rc4Key, (UINT32) InputSize, Input, Output);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Resets the ARC4 context to the initial state.\r
+\r
+  The function resets the ARC4 context to the state it had immediately after the\r
+  ARC4Init() function call.\r
+  Contrary to ARC4Init(), Arc4Reset() requires no secret key as input, but ARC4 context\r
+  should be already correctly initialized by ARC4Init().\r
+\r
+  If Arc4Context is NULL, then ASSERT().\r
+\r
+  @param[in, out]  Arc4Context  Pointer to the ARC4 context.\r
+\r
+  @retval TRUE   ARC4 reset succeeded.\r
+  @retval FALSE  ARC4 reset failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Arc4Reset (\r
+  IN OUT  VOID  *Arc4Context\r
+  )\r
+{\r
+  RC4_KEY  *Rc4Key;\r
+\r
+  ASSERT (Arc4Context != NULL);\r
+\r
+  Rc4Key = (RC4_KEY *) Arc4Context;\r
+\r
+  CopyMem (Rc4Key, Rc4Key + 1, sizeof(RC4_KEY));\r
+\r
+  return TRUE;\r
+}\r
diff --git a/CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c b/CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c
new file mode 100644 (file)
index 0000000..5535ab3
--- /dev/null
@@ -0,0 +1,353 @@
+/** @file\r
+  TDES Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/des.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for TDES operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for TDES operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+TdesGetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Memory for 3 copies of DES_key_schedule is allocated, for K1, K2 and K3 each.\r
+  //\r
+  return (UINTN) (3 * sizeof (DES_key_schedule));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory as TDES context for subsequent use.\r
+\r
+  This function initializes user-supplied memory pointed by TdesContext as TDES context.\r
+  In addtion, it sets up all TDES key materials for subsequent encryption and decryption\r
+  operations.\r
+  There are 3 key options as follows:\r
+  KeyLength = 64,  Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)\r
+  KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)\r
+  KeyLength = 192  Keying option 3: K1 != K2 != K3 (Strongest)\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Key is NULL, then ASSERT().\r
+  If KeyLength is not valid, then ASSERT().\r
+\r
+  @param[out]  TdesContext  Pointer to TDES context being initialized.\r
+  @param[in]   Key          Pointer to the user-supplied TDES key.\r
+  @param[in]   KeyLength    Length of TDES key in bits.\r
+\r
+  @retval TRUE   TDES context initialization succeeded.\r
+  @retval FALSE  TDES context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesInit (\r
+  OUT  VOID         *TdesContext,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeyLength\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+\r
+  ASSERT (TdesContext != NULL);\r
+  ASSERT (Key != NULL);\r
+  ASSERT ((KeyLength == 64) || (KeyLength == 128) || (KeyLength == 192));\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+\r
+  //\r
+  // \r
+  //\r
+  if (DES_is_weak_key ((const_DES_cblock *) Key)) {\r
+    return FALSE;\r
+  }\r
+\r
+  DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);\r
+\r
+  if (KeyLength == 64) {\r
+    CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));\r
+    CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
+    return TRUE;\r
+  }\r
+\r
+  if (DES_is_weak_key ((const_DES_cblock *) Key + 8)) {\r
+    return FALSE;\r
+  }\r
+\r
+  DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);\r
+\r
+  if (KeyLength == 128) {\r
+    CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
+    return TRUE;\r
+  }\r
+\r
+  if (DES_is_weak_key ((const_DES_cblock *) Key + 16)) {\r
+    return FALSE;\r
+  }\r
+\r
+  DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+\r
+  ASSERT (TdesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
+  ASSERT (Output != NULL);\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+\r
+  while (InputSize > 0) {\r
+    DES_ecb3_encrypt (\r
+      (const_DES_cblock *) Input,\r
+      (DES_cblock *) Output,\r
+      KeySchedule,\r
+      KeySchedule + 1,\r
+      KeySchedule + 2,\r
+      DES_ENCRYPT\r
+      );\r
+    Input     += TDES_BLOCK_SIZE;\r
+    Output    += TDES_BLOCK_SIZE;\r
+    InputSize -= TDES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in ECB mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be decrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES decryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesEcbDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+\r
+  ASSERT (TdesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
+  ASSERT (Output != NULL);\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+\r
+  while (InputSize > 0) {\r
+    DES_ecb3_encrypt (\r
+      (const_DES_cblock *) Input,\r
+      (DES_cblock *) Output,\r
+      KeySchedule,\r
+      KeySchedule + 1,\r
+      KeySchedule + 2,\r
+      DES_DECRYPT\r
+      );\r
+    Input     += TDES_BLOCK_SIZE;\r
+    Output    += TDES_BLOCK_SIZE;\r
+    InputSize -= TDES_BLOCK_SIZE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES encryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES encryption succeeded.\r
+  @retval FALSE  TDES encryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcEncrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+  UINT8             IvecBuffer[TDES_BLOCK_SIZE];\r
+\r
+  ASSERT (TdesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
+  ASSERT (Ivec != NULL);\r
+  ASSERT (Output != NULL);\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+  CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
+\r
+  DES_ede3_cbc_encrypt (\r
+    Input,\r
+    Output,\r
+    (UINT32) InputSize,\r
+    KeySchedule,\r
+    KeySchedule + 1,\r
+    KeySchedule + 2,\r
+    (DES_cblock *) IvecBuffer,\r
+    DES_ENCRYPT\r
+    );\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
+\r
+  This function performs TDES decryption on data buffer pointed by Input, of specified\r
+  size of InputSize, in CBC mode.\r
+  InputSize must be multiple of block size (8 bytes). This function does not perform\r
+  padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
+  Initialization vector should be one block size (8 bytes).\r
+  TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
+  invalid TDES context is undefined.\r
+\r
+  If TdesContext is NULL, then ASSERT().\r
+  If Input is NULL, then ASSERT().\r
+  If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
+  If Ivec is NULL, then ASSERT().\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[in]   TdesContext  Pointer to the TDES context.\r
+  @param[in]   Input        Pointer to the buffer containing the data to be encrypted.\r
+  @param[in]   InputSize    Size of the Input buffer in bytes.\r
+  @param[in]   Ivec         Pointer to initialization vector.\r
+  @param[out]  Output       Pointer to a buffer that receives the TDES encryption output.\r
+\r
+  @retval TRUE   TDES decryption succeeded.\r
+  @retval FALSE  TDES decryption failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+TdesCbcDecrypt (\r
+  IN   VOID         *TdesContext,\r
+  IN   CONST UINT8  *Input,\r
+  IN   UINTN        InputSize,\r
+  IN   CONST UINT8  *Ivec,\r
+  OUT  UINT8        *Output\r
+  )\r
+{\r
+  DES_key_schedule  *KeySchedule;\r
+  UINT8             IvecBuffer[TDES_BLOCK_SIZE];\r
+\r
+  ASSERT (TdesContext != NULL);\r
+  ASSERT (Input != NULL);\r
+  ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
+  ASSERT (Ivec != NULL);\r
+  ASSERT (Output != NULL);\r
+\r
+  KeySchedule = (DES_key_schedule *) TdesContext;\r
+  CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
+\r
+  DES_ede3_cbc_encrypt (\r
+    Input,\r
+    Output,\r
+    (UINT32) InputSize,\r
+    KeySchedule,\r
+    KeySchedule + 1,\r
+    KeySchedule + 2,\r
+    (DES_cblock *) IvecBuffer,\r
+    DES_DECRYPT\r
+    );\r
+\r
+  return TRUE;\r
+}\r
+\r
index 99471a0..73f3d21 100644 (file)
@@ -12,10 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-\r
-#include <Library/BaseCryptLib.h>\r
+#include "InternalCryptLib.h"\r
 #include <openssl/md5.h>\r
 \r
 \r
@@ -44,7 +41,7 @@ Md5GetContextSize (
 \r
   If Md5Context is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Md5Context  Pointer to MD5 Context being initialized.\r
+  @param[out]  Md5Context  Pointer to MD5 context being initialized.\r
 \r
   @retval TRUE   MD5 context initialization succeeded.\r
   @retval FALSE  MD5 context initialization failed.\r
@@ -53,7 +50,7 @@ Md5GetContextSize (
 BOOLEAN\r
 EFIAPI\r
 Md5Init (\r
-  IN OUT  VOID  *Md5Context\r
+  OUT  VOID  *Md5Context\r
   )\r
 {\r
   //\r
@@ -67,20 +64,47 @@ Md5Init (
   return (BOOLEAN) (MD5_Init ((MD5_CTX *)Md5Context));\r
 }\r
 \r
+/**\r
+  Makes a copy of an existing MD5 context.\r
+\r
+  If Md5Context is NULL, then ASSERT().\r
+  If NewMd5Context is NULL, then ASSERT().\r
+\r
+  @param[in]  Md5Context     Pointer to MD5 context being copied.\r
+  @param[out] NewMd5Context  Pointer to new MD5 context.\r
+\r
+  @retval TRUE   MD5 context copy succeeded.\r
+  @retval FALSE  MD5 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Md5Duplicate (\r
+  IN   CONST VOID  *Md5Context,\r
+  OUT  VOID        *NewMd5Context\r
+  )\r
+{\r
+  CopyMem (NewMd5Context, Md5Context, sizeof (MD5_CTX));\r
+\r
+  return TRUE;\r
+}\r
 \r
 /**\r
-  Performs MD5 digest on a data buffer of the specified length. This function can\r
-  be called multiple times to compute the digest of long or discontinuous data streams.\r
+  Digests the input data and updates MD5 context.\r
+\r
+  This function performs MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be finalized\r
+  by Md5Final(). Behavior with invalid context is undefined.\r
 \r
   If Md5Context is NULL, then ASSERT().\r
 \r
   @param[in, out]  Md5Context  Pointer to the MD5 context.\r
   @param[in]       Data        Pointer to the buffer containing the data to be hashed.\r
-  @param[in]       DataLength  Length of Data buffer in bytes.\r
+  @param[in]       DataSize    Size of Data buffer in bytes.\r
 \r
   @retval TRUE   MD5 data digest succeeded.\r
-  @retval FALSE  Invalid MD5 context. After Md5Final function has been called, the\r
-                 MD5 context cannot be reused.\r
+  @retval FALSE  MD5 data digest failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -88,7 +112,7 @@ EFIAPI
 Md5Update (\r
   IN OUT  VOID        *Md5Context,\r
   IN      CONST VOID  *Data,\r
-  IN      UINTN       DataLength\r
+  IN      UINTN       DataSize\r
   )\r
 {\r
   //\r
@@ -100,24 +124,28 @@ Md5Update (
   // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL\r
   //\r
   if (Data == NULL) {\r
-    ASSERT (DataLength == 0);\r
+    ASSERT (DataSize == 0);\r
   }\r
 \r
   //\r
   // OpenSSL MD5 Hash Update\r
   //\r
-  return (BOOLEAN) (MD5_Update ((MD5_CTX *)Md5Context, Data, DataLength));\r
+  return (BOOLEAN) (MD5_Update ((MD5_CTX *)Md5Context, Data, DataSize));\r
 }\r
 \r
-\r
 /**\r
-  Completes MD5 hash computation and retrieves the digest value into the specified\r
-  memory. After this function has been called, the MD5 context cannot be used again.\r
+  Completes computation of the MD5 digest value.\r
+\r
+  This function completes MD5 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the MD5 context cannot\r
+  be used again.\r
+  MD5 context should be already correctly intialized by Md5Init(), and should not be\r
+  finalized by Md5Final(). Behavior with invalid MD5 context is undefined.\r
 \r
   If Md5Context is NULL, then ASSERT().\r
   If HashValue is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Md5Context  Pointer to the MD5 context\r
+  @param[in, out]  Md5Context  Pointer to the MD5 context.\r
   @param[out]      HashValue   Pointer to a buffer that receives the MD5 digest\r
                                value (16 bytes).\r
 \r
index d774059..9a317ec 100644 (file)
@@ -12,10 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-\r
-#include <Library/BaseCryptLib.h>\r
+#include "InternalCryptLib.h"\r
 #include <openssl/sha.h>\r
 \r
 \r
@@ -37,23 +34,22 @@ Sha1GetContextSize (
   return (UINTN)(sizeof (SHA_CTX));\r
 }\r
 \r
-\r
 /**\r
-  Initializes user-supplied memory pointed by Sha1Context as the SHA-1 hash context for\r
+  Initializes user-supplied memory pointed by Sha1Context as SHA-1 hash context for\r
   subsequent use.\r
 \r
   If Sha1Context is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha1Context  Pointer to the SHA-1 Context being initialized.\r
+  @param[out]  Sha1Context  Pointer to SHA-1 context being initialized.\r
 \r
-  @retval TRUE   SHA-1 initialization succeeded.\r
-  @retval FALSE  SHA-1 initialization failed.\r
+  @retval TRUE   SHA-1 context initialization succeeded.\r
+  @retval FALSE  SHA-1 context initialization failed.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 Sha1Init (\r
-  IN OUT  VOID  *Sha1Context\r
+  OUT  VOID  *Sha1Context\r
   )\r
 {\r
   //\r
@@ -67,20 +63,47 @@ Sha1Init (
   return (BOOLEAN) (SHA1_Init ((SHA_CTX *)Sha1Context));\r
 }\r
 \r
+/**\r
+  Makes a copy of an existing SHA-1 context.\r
+\r
+  If Sha1Context is NULL, then ASSERT().\r
+  If NewSha1Context is NULL, then ASSERT().\r
+\r
+  @param[in]  Sha1Context     Pointer to SHA-1 context being copied.\r
+  @param[out] NewSha1Context  Pointer to new SHA-1 context.\r
+\r
+  @retval TRUE   SHA-1 context copy succeeded.\r
+  @retval FALSE  SHA-1 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha1Duplicate (\r
+  IN   CONST VOID  *Sha1Context,\r
+  OUT  VOID        *NewSha1Context\r
+  )\r
+{\r
+  CopyMem (NewSha1Context, Sha1Context, sizeof (SHA_CTX));\r
+\r
+  return TRUE;\r
+}\r
 \r
 /**\r
-  Performs SHA-1 digest on a data buffer of the specified length. This function can\r
-  be called multiple times to compute the digest of long or discontinuous data streams.\r
+  Digests the input data and updates SHA-1 context.\r
+\r
+  This function performs SHA-1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be finalized\r
+  by Sha1Final(). Behavior with invalid context is undefined.\r
 \r
   If Sha1Context is NULL, then ASSERT().\r
 \r
   @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
   @param[in]       Data         Pointer to the buffer containing the data to be hashed.\r
-  @param[in]       DataLength   Length of Data buffer in bytes.\r
+  @param[in]       DataSize     Size of Data buffer in bytes.\r
 \r
   @retval TRUE   SHA-1 data digest succeeded.\r
-  @retval FALSE  Invalid SHA-1 context. After Sha1Final function has been called, the\r
-                 SHA-1 context cannot be reused.\r
+  @retval FALSE  SHA-1 data digest failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -88,7 +111,7 @@ EFIAPI
 Sha1Update (\r
   IN OUT  VOID        *Sha1Context,\r
   IN      CONST VOID  *Data,\r
-  IN      UINTN       DataLength\r
+  IN      UINTN       DataSize\r
   )\r
 {\r
   //\r
@@ -100,24 +123,28 @@ Sha1Update (
   // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL\r
   //\r
   if (Data == NULL) {\r
-    ASSERT (DataLength == 0);\r
+    ASSERT (DataSize == 0);\r
   }\r
 \r
   //\r
   // OpenSSL SHA-1 Hash Update\r
   //\r
-  return (BOOLEAN) (SHA1_Update ((SHA_CTX *)Sha1Context, Data, DataLength));\r
+  return (BOOLEAN) (SHA1_Update ((SHA_CTX *)Sha1Context, Data, DataSize));\r
 }\r
 \r
-\r
 /**\r
-  Completes SHA-1 hash computation and retrieves the digest value into the specified\r
-  memory. After this function has been called, the SHA-1 context cannot be used again.\r
+  Completes computation of the SHA-1 digest value.\r
+\r
+  This function completes SHA-1 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-1 context cannot\r
+  be used again.\r
+  SHA-1 context should be already correctly intialized by Sha1Init(), and should not be\r
+  finalized by Sha1Final(). Behavior with invalid SHA-1 context is undefined.\r
 \r
   If Sha1Context is NULL, then ASSERT().\r
   If HashValue is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha1Context  Pointer to the SHA-1 context\r
+  @param[in, out]  Sha1Context  Pointer to the SHA-1 context.\r
   @param[out]      HashValue    Pointer to a buffer that receives the SHA-1 digest\r
                                 value (20 bytes).\r
 \r
index 9b566a4..7e6c6c6 100644 (file)
@@ -12,17 +12,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-\r
-#include <Library/BaseCryptLib.h>\r
+#include "InternalCryptLib.h"\r
 #include <openssl/sha.h>\r
 \r
-\r
 /**\r
-  Retrieves the size, in bytes, of the context buffer required for SHA-256 operations.\r
+  Retrieves the size, in bytes, of the context buffer required for SHA-256 hash operations.\r
 \r
-  @return  The size, in bytes, of the context buffer required for SHA-256 operations.\r
+  @return  The size, in bytes, of the context buffer required for SHA-256 hash operations.\r
 \r
 **/\r
 UINTN\r
@@ -37,14 +33,13 @@ Sha256GetContextSize (
   return (UINTN)(sizeof (SHA256_CTX));\r
 }\r
 \r
-\r
 /**\r
   Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for\r
   subsequent use.\r
 \r
   If Sha256Context is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha256Context  Pointer to SHA-256 Context being initialized.\r
+  @param[out]  Sha256Context  Pointer to SHA-256 context being initialized.\r
 \r
   @retval TRUE   SHA-256 context initialization succeeded.\r
   @retval FALSE  SHA-256 context initialization failed.\r
@@ -53,7 +48,7 @@ Sha256GetContextSize (
 BOOLEAN\r
 EFIAPI\r
 Sha256Init (\r
-  IN OUT  VOID  *Sha256Context\r
+  OUT  VOID  *Sha256Context\r
   )\r
 {\r
   //\r
@@ -67,20 +62,47 @@ Sha256Init (
   return (BOOLEAN) (SHA256_Init ((SHA256_CTX *)Sha256Context));\r
 }\r
 \r
+/**\r
+  Makes a copy of an existing SHA-256 context.\r
+\r
+  If Sha256Context is NULL, then ASSERT().\r
+  If NewSha256Context is NULL, then ASSERT().\r
+\r
+  @param[in]  Sha256Context     Pointer to SHA-256 context being copied.\r
+  @param[out] NewSha256Context  Pointer to new SHA-256 context.\r
+\r
+  @retval TRUE   SHA-256 context copy succeeded.\r
+  @retval FALSE  SHA-256 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+Sha256Duplicate (\r
+  IN   CONST VOID  *Sha256Context,\r
+  OUT  VOID        *NewSha256Context\r
+  )\r
+{\r
+  CopyMem (NewSha256Context, Sha256Context, sizeof (SHA256_CTX));\r
+\r
+  return TRUE;\r
+}\r
 \r
 /**\r
-  Performs SHA-256 digest on a data buffer of the specified length. This function can\r
-  be called multiple times to compute the digest of long or discontinuous data streams.\r
+  Digests the input data and updates SHA-256 context.\r
+\r
+  This function performs SHA-256 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be finalized\r
+  by Sha256Final(). Behavior with invalid context is undefined.\r
 \r
   If Sha256Context is NULL, then ASSERT().\r
 \r
   @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
   @param[in]       Data           Pointer to the buffer containing the data to be hashed.\r
-  @param[in]       DataLength     Length of Data buffer in bytes.\r
+  @param[in]       DataSize       Size of Data buffer in bytes.\r
 \r
   @retval TRUE   SHA-256 data digest succeeded.\r
-  @retval FALSE  Invalid SHA-256 context. After Sha256Final function has been called, the\r
-                 SHA-256 context cannot be reused.\r
+  @retval FALSE  SHA-256 data digest failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -88,7 +110,7 @@ EFIAPI
 Sha256Update (\r
   IN OUT  VOID        *Sha256Context,\r
   IN      CONST VOID  *Data,\r
-  IN      UINTN       DataLength\r
+  IN      UINTN       DataSize\r
   )\r
 {\r
   //\r
@@ -100,24 +122,28 @@ Sha256Update (
   // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL\r
   //\r
   if (Data == NULL) {\r
-    ASSERT (DataLength == 0);\r
+    ASSERT (DataSize == 0);\r
   }\r
 \r
   //\r
   // OpenSSL SHA-256 Hash Update\r
   //\r
-  return (BOOLEAN) (SHA256_Update ((SHA256_CTX *)Sha256Context, Data, DataLength));\r
+  return (BOOLEAN) (SHA256_Update ((SHA256_CTX *)Sha256Context, Data, DataSize));\r
 }\r
 \r
-\r
 /**\r
-  Completes SHA-256 hash computation and retrieves the digest value into the specified\r
-  memory. After this function has been called, the SHA-256 context cannot be used again.\r
+  Completes computation of the SHA-256 digest value.\r
+\r
+  This function completes SHA-256 hash computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the SHA-256 context cannot\r
+  be used again.\r
+  SHA-256 context should be already correctly intialized by Sha256Init(), and should not be\r
+  finalized by Sha256Final(). Behavior with invalid SHA-256 context is undefined.\r
 \r
   If Sha256Context is NULL, then ASSERT().\r
   If HashValue is NULL, then ASSERT().\r
 \r
-  @param[in, out]  Sha256Context  Pointer to SHA-256 context\r
+  @param[in, out]  Sha256Context  Pointer to the SHA-256 context.\r
   @param[out]      HashValue      Pointer to a buffer that receives the SHA-256 digest\r
                                   value (32 bytes).\r
 \r
diff --git a/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c b/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacMd5.c
new file mode 100644 (file)
index 0000000..1eff5c4
--- /dev/null
@@ -0,0 +1,185 @@
+/** @file\r
+  HMAC-MD5 Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/hmac.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-MD5 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacMd5GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves the OpenSSL HMAC-MD5 Context Size\r
+  //\r
+  return (UINTN)(sizeof (HMAC_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacMd5Context as HMAC-MD5 context for\r
+  subsequent use.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+\r
+  @param[out]  HmacMd5Context  Pointer to HMAC-MD5 context being initialized.\r
+  @param[in]   Key             Pointer to the user-supplied key.\r
+  @param[in]   KeySize         Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 context initialization succeeded.\r
+  @retval FALSE  HMAC-MD5 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Init (\r
+  OUT  VOID         *HmacMd5Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  )\r
+{\r
+  //\r
+  // ASSERT if HmacMd5Context is NULL.\r
+  //\r
+  ASSERT (HmacMd5Context != NULL);\r
+\r
+  //\r
+  // OpenSSL HMAC-MD5 Context Initialization\r
+  //\r
+  HMAC_CTX_init (HmacMd5Context);\r
+  HMAC_Init_ex (HmacMd5Context, Key, (UINT32) KeySize, EVP_md5(), NULL);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-MD5 context.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+  If NewHmacMd5Context is NULL, then ASSERT().\r
+\r
+  @param[in]  HmacMd5Context     Pointer to HMAC-MD5 context being copied.\r
+  @param[out] NewHmacMd5Context  Pointer to new HMAC-MD5 context.\r
+\r
+  @retval TRUE   HMAC-MD5 context copy succeeded.\r
+  @retval FALSE  HMAC-MD5 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Duplicate (\r
+  IN   CONST VOID  *HmacMd5Context,\r
+  OUT  VOID        *NewHmacMd5Context\r
+  )\r
+{\r
+  CopyMem (NewHmacMd5Context, HmacMd5Context, sizeof (HMAC_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates HMAC-MD5 context.\r
+\r
+  This function performs HMAC-MD5 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-MD5 data digest succeeded.\r
+  @retval FALSE  HMAC-MD5 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Update (\r
+  IN OUT  VOID        *HmacMd5Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // ASSERT if HmacMd5Context is NULL\r
+  //\r
+  ASSERT (HmacMd5Context != NULL);\r
+\r
+  //\r
+  // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL) {\r
+    ASSERT (DataSize == 0);\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-MD5 digest update\r
+  //\r
+  HMAC_Update (HmacMd5Context, Data, DataSize);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Completes computation of the HMAC-MD5 digest value.\r
+\r
+  This function completes HMAC-MD5 digest computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-MD5 context cannot\r
+  be used again.\r
+  HMAC-MD5 context should be already correctly intialized by HmacMd5Init(), and should not be\r
+  finalized by HmacMd5Final(). Behavior with invalid HMAC-MD5 context is undefined.\r
+\r
+  If HmacMd5Context is NULL, then ASSERT().\r
+  If HmacValue is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacMd5Context  Pointer to the HMAC-MD5 context.\r
+  @param[out]      HmacValue       Pointer to a buffer that receives the HMAC-MD5 digest\r
+                                   value (16 bytes).\r
+\r
+  @retval TRUE   HMAC-MD5 digest computation succeeded.\r
+  @retval FALSE  HMAC-MD5 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacMd5Final (\r
+  IN OUT  VOID   *HmacMd5Context,\r
+  OUT     UINT8  *HmacValue\r
+  )\r
+{\r
+  UINT32  Length;\r
+\r
+  //\r
+  // ASSERT if HmacMd5Context is NULL or HmacValue is NULL\r
+  //\r
+  ASSERT (HmacMd5Context != NULL);\r
+  ASSERT (HmacValue != NULL);\r
+\r
+  //\r
+  // OpenSSL HMAC-MD5 digest finalization\r
+  //\r
+  HMAC_Final (HmacMd5Context, HmacValue, &Length);\r
+  HMAC_CTX_cleanup (HmacMd5Context);\r
+\r
+  return TRUE;\r
+}\r
diff --git a/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c b/CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmacSha1.c
new file mode 100644 (file)
index 0000000..0298b80
--- /dev/null
@@ -0,0 +1,185 @@
+/** @file\r
+  HMAC-SHA1 Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/hmac.h>\r
+\r
+/**\r
+  Retrieves the size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+  @return  The size, in bytes, of the context buffer required for HMAC-SHA1 operations.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+HmacSha1GetContextSize (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Retrieves the OpenSSL HMAC-SHA1 Context Size\r
+  //\r
+  return (UINTN)(sizeof (HMAC_CTX));\r
+}\r
+\r
+/**\r
+  Initializes user-supplied memory pointed by HmacSha1Context as HMAC-SHA1 context for\r
+  subsequent use.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+\r
+  @param[out]  HmacSha1Context  Pointer to HMAC-SHA1 context being initialized.\r
+  @param[in]   Key              Pointer to the user-supplied key.\r
+  @param[in]   KeySize          Key size in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 context initialization succeeded.\r
+  @retval FALSE  HMAC-SHA1 context initialization failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Init (\r
+  OUT  VOID         *HmacSha1Context,\r
+  IN   CONST UINT8  *Key,\r
+  IN   UINTN        KeySize\r
+  )\r
+{\r
+  //\r
+  // ASSERT if HmacSha1Context is NULL.\r
+  //\r
+  ASSERT (HmacSha1Context != NULL);\r
+\r
+  //\r
+  // OpenSSL HMAC-SHA1 Context Initialization\r
+  //\r
+  HMAC_CTX_init (HmacSha1Context);\r
+  HMAC_Init_ex (HmacSha1Context, Key, (UINT32) KeySize, EVP_sha1(), NULL);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Makes a copy of an existing HMAC-SHA1 context.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+  If NewHmacSha1Context is NULL, then ASSERT().\r
+\r
+  @param[in]  HmacSha1Context     Pointer to HMAC-SHA1 context being copied.\r
+  @param[out] NewHmacSha1Context  Pointer to new HMAC-SHA1 context.\r
+\r
+  @retval TRUE   HMAC-SHA1 context copy succeeded.\r
+  @retval FALSE  HMAC-SHA1 context copy failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Duplicate (\r
+  IN   CONST VOID  *HmacSha1Context,\r
+  OUT  VOID        *NewHmacSha1Context\r
+  )\r
+{\r
+  CopyMem (NewHmacSha1Context, HmacSha1Context, sizeof (HMAC_CTX));\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Digests the input data and updates HMAC-SHA1 context.\r
+\r
+  This function performs HMAC-SHA1 digest on a data buffer of the specified size.\r
+  It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should not\r
+  be finalized by HmacSha1Final(). Behavior with invalid context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacSha1Context Pointer to the HMAC-SHA1 context.\r
+  @param[in]       Data            Pointer to the buffer containing the data to be digested.\r
+  @param[in]       DataSize        Size of Data buffer in bytes.\r
+\r
+  @retval TRUE   HMAC-SHA1 data digest succeeded.\r
+  @retval FALSE  HMAC-SHA1 data digest failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Update (\r
+  IN OUT  VOID        *HmacSha1Context,\r
+  IN      CONST VOID  *Data,\r
+  IN      UINTN       DataSize\r
+  )\r
+{\r
+  //\r
+  // ASSERT if HmacSha1Context is NULL\r
+  //\r
+  ASSERT (HmacSha1Context != NULL);\r
+\r
+  //\r
+  // ASSERT if invalid parameters, in case that only DataLength was checked in OpenSSL\r
+  //\r
+  if (Data == NULL) {\r
+    ASSERT (DataSize == 0);\r
+  }\r
+\r
+  //\r
+  // OpenSSL HMAC-SHA1 digest update\r
+  //\r
+  HMAC_Update (HmacSha1Context, Data, DataSize);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Completes computation of the HMAC-SHA1 digest value.\r
+\r
+  This function completes HMAC-SHA1 digest computation and retrieves the digest value into\r
+  the specified memory. After this function has been called, the HMAC-SHA1 context cannot\r
+  be used again.\r
+  HMAC-SHA1 context should be already correctly intialized by HmacSha1Init(), and should\r
+  not be finalized by HmacSha1Final(). Behavior with invalid HMAC-SHA1 context is undefined.\r
+\r
+  If HmacSha1Context is NULL, then ASSERT().\r
+  If HmacValue is NULL, then ASSERT().\r
+\r
+  @param[in, out]  HmacSha1Context  Pointer to the HMAC-SHA1 context.\r
+  @param[out]      HmacValue        Pointer to a buffer that receives the HMAC-SHA1 digest\r
+                                    value (20 bytes).\r
+\r
+  @retval TRUE   HMAC-SHA1 digest computation succeeded.\r
+  @retval FALSE  HMAC-SHA1 digest computation failed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+HmacSha1Final (\r
+  IN OUT  VOID   *HmacSha1Context,\r
+  OUT     UINT8  *HmacValue\r
+  )\r
+{\r
+  UINT32  Length;\r
+\r
+  //\r
+  // ASSERT if HmacSha1Context is NULL or HmacValue is NULL\r
+  //\r
+  ASSERT (HmacSha1Context != NULL);\r
+  ASSERT (HmacValue != NULL);\r
+\r
+  //\r
+  // OpenSSL HMAC-SHA1 digest finalization\r
+  //\r
+  HMAC_Final (HmacSha1Context, HmacValue, &Length);\r
+  HMAC_CTX_cleanup (HmacSha1Context);\r
+\r
+  return TRUE;\r
+}\r
diff --git a/CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h b/CryptoPkg/Library/BaseCryptLib/InternalCryptLib.h
new file mode 100644 (file)
index 0000000..6a898a8
--- /dev/null
@@ -0,0 +1,32 @@
+/** @file  \r
+  Internal include file for BaseCryptLib.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTERNAL_CRYPT_LIB_H__\r
+#define __INTERNAL_CRYPT_LIB_H__\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+\r
+//\r
+// Environment Setting for OpenSSL-based UEFI Crypto Library.\r
+//\r
+#ifndef OPENSSL_SYSNAME_UWIN\r
+#define OPENSSL_SYSNAME_UWIN\r
+#endif\r
+\r
+#endif\r
+\r
index 30061a6..14a2b19 100644 (file)
@@ -55,8 +55,6 @@
   SysCall/Ia32/MathLShiftS64.S      | GCC\r
   SysCall/Ia32/MathRShiftU64.S      | GCC\r
 \r
-  SysCall/Ia32/Alloca.S             | GCC\r
-\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   CryptoPkg/CryptoPkg.dec\r
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c
new file mode 100644 (file)
index 0000000..b7e164c
--- /dev/null
@@ -0,0 +1,238 @@
+/** @file\r
+  Diffie-Hellman Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/dh.h>\r
+\r
+\r
+/**\r
+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.\r
+\r
+  @return  Pointer to the Diffie-Hellman Context that has been initialized.\r
+           If the allocations fails, DhNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DhNew (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Allocates & Initializes DH Context by OpenSSL DH_new()\r
+  //\r
+  return (VOID *)DH_new ();\r
+}\r
+\r
+/**\r
+  Release the specified DH context.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+\r
+  @param[in]  DhContext  Pointer to the DH context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DhFree (\r
+  IN  VOID  *DhContext\r
+  )\r
+{\r
+  //\r
+  // Free OpenSSL DH Context\r
+  //\r
+  DH_free ((DH *)DhContext);\r
+}\r
+\r
+/**\r
+  Generates DH parameter.\r
+\r
+  Given generator g, and length of prime number p in bits, this function generates p,\r
+  and sets DH context according to value of g and p.\r
+  \r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If Prime is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.\r
+\r
+  @retval TRUE   DH pamameter generation succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateParameter (\r
+  IN OUT  VOID   *DhContext,\r
+  IN      UINTN  Generator,\r
+  IN      UINTN  PrimeLength,\r
+  OUT     UINT8  *Prime\r
+  )\r
+{\r
+  BOOLEAN RetVal;\r
+\r
+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
+    return FALSE;\r
+  }\r
+\r
+  RetVal = (BOOLEAN) DH_generate_parameters_ex (DhContext, (UINT32) PrimeLength, (UINT32) Generator, NULL);\r
+  if (!RetVal) {\r
+    return FALSE;\r
+  }\r
+\r
+  BN_bn2bin (((DH *) DhContext)->p, Prime);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Sets generator and prime parameters for DH.\r
+\r
+  Given generator g, and prime number p, this function and sets DH\r
+  context accordingly.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If Prime is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[in]       Prime        Pointer to the prime number.\r
+\r
+  @retval TRUE   DH pamameter setting succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  Value of Generator is not suitable for the Prime.\r
+  @retval FALSE  Value of Prime is not a prime number.\r
+  @retval FALSE  Value of Prime is not a safe prime number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhSetParameter (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      UINTN        Generator,\r
+  IN      UINTN        PrimeLength,\r
+  IN      CONST UINT8  *Prime\r
+  )\r
+{\r
+  DH  *Dh;\r
+\r
+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
+    return FALSE;\r
+  }\r
+\r
+  Dh = (DH *) DhContext;\r
+  Dh->p = BN_new();\r
+  Dh->g = BN_new();\r
+\r
+  BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p);\r
+  BN_set_word (Dh->g, (UINT32) Generator);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Generates DH public key.\r
+\r
+  This function generates random secret exponent, and computes the public key, which is \r
+  returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.\r
+  If the PublicKey buffer is too small to hold the public key, FALSE is returned and\r
+  PublicKeySize is set to the required buffer size to obtain the public key.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If PublicKeySize is NULL, then ASSERT().\r
+  If PublicKeySize is large enough but PublicKey is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext      Pointer to the DH context.\r
+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.\r
+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.\r
+                                  On output, the size of data returned in PublicKey buffer in bytes.\r
+\r
+  @retval TRUE   DH public key generation succeeded.\r
+  @retval FALSE  DH public key generation failed.\r
+  @retval FALSE  PublicKeySize is not large enough.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateKey (\r
+  IN OUT  VOID   *DhContext,\r
+  OUT     UINT8  *PublicKey,\r
+  IN OUT  UINTN  *PublicKeySize\r
+  )\r
+{\r
+  BOOLEAN RetVal;\r
+  DH      *Dh;\r
+\r
+  Dh = (DH *) DhContext;\r
+  *PublicKeySize = 0;\r
+\r
+  RetVal = (BOOLEAN) DH_generate_key (DhContext);\r
+  if (RetVal) {\r
+    BN_bn2bin (Dh->pub_key, PublicKey);\r
+    *PublicKeySize  = BN_num_bytes (Dh->pub_key);\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  Computes exchanged common key.\r
+\r
+  Given peer's public key, this function computes the exchanged common key, based on its own\r
+  context including value of prime modulus and random secret exponent. \r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If PeerPublicKey is NULL, then ASSERT().\r
+  If KeySize is NULL, then ASSERT().\r
+  If KeySize is large enough but Key is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext          Pointer to the DH context.\r
+  @param[in]       PeerPublicKey      Pointer to the peer's public key.\r
+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.\r
+  @param[out]      Key                Pointer to the buffer to receive generated key.\r
+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.\r
+                                      On output, the size of data returned in Key buffer in bytes.\r
+\r
+  @retval TRUE   DH exchanged key generation succeeded.\r
+  @retval FALSE  DH exchanged key generation failed.\r
+  @retval FALSE  KeySize is not large enough.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhComputeKey (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      CONST UINT8  *PeerPublicKey,\r
+  IN      UINTN        PeerPublicKeySize,\r
+  OUT     UINT8        *Key,\r
+  IN OUT  UINTN        *KeySize\r
+  )\r
+{\r
+  BIGNUM  *Bn;\r
+\r
+  Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL);\r
+\r
+  *KeySize = (BOOLEAN) DH_compute_key (Key, Bn, DhContext);\r
+\r
+  BN_free (Bn);\r
+\r
+  return TRUE;\r
+}\r
index d0a6ea5..ca0dd4f 100644 (file)
@@ -12,11 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
+#include "InternalCryptLib.h"\r
 \r
-#include <Library/BaseCryptLib.h>\r
 #include <openssl/objects.h>\r
 #include <openssl/x509.h>\r
 #include <openssl/pkcs7.h>\r
@@ -36,8 +33,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   @param[in]  InData       Pointer to the content to be verified.\r
   @param[in]  DataLength   Length of InData in bytes.\r
 \r
-  @return  TRUE  The specified PKCS#7 signed data is valid.\r
-  @return  FALSE Invalid PKCS#7 signed data.\r
+  @retval  TRUE  The specified PKCS#7 signed data is valid.\r
+  @retval  FALSE Invalid PKCS#7 signed data.\r
 \r
 **/\r
 BOOLEAN\r
index 763213a..2e84a2f 100644 (file)
@@ -12,18 +12,36 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
+#include "InternalCryptLib.h"\r
 \r
-#include <Library/BaseCryptLib.h>\r
 #include <openssl/rsa.h>\r
+#include <openssl/err.h>\r
+\r
+//\r
+// ASN.1 value for Hash Algorithm ID with the Distringuished Encoding Rules (DER)\r
+// Refer to Section 9.2 of PKCS#1 v2.1\r
+//                           \r
+CONST UINT8  Asn1IdMd5[] = {\r
+  0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,\r
+  0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10\r
+  };\r
+\r
+CONST UINT8  Asn1IdSha1[] = {\r
+  0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,\r
+  0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14\r
+  };\r
+\r
+CONST UINT8  Asn1IdSha256[] = {\r
+  0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,\r
+  0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,\r
+  0x00, 0x04, 0x20\r
+  };\r
 \r
 \r
 /**\r
-  Allocates and Initializes one RSA Context for subsequent use.\r
+  Allocates and initializes one RSA context for subsequent use.\r
 \r
-  @return  Pointer to the RSA Context that has been initialized.\r
+  @return  Pointer to the RSA context that has been initialized.\r
            If the allocations fails, RsaNew() returns NULL.\r
 \r
 **/\r
@@ -39,9 +57,10 @@ RsaNew (
   return (VOID *)RSA_new ();\r
 }\r
 \r
-\r
 /**\r
-  Release the specified RSA Context.\r
+  Release the specified RSA context.\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
 \r
   @param[in]  RsaContext  Pointer to the RSA context to be released.\r
 \r
@@ -52,36 +71,43 @@ RsaFree (
   IN  VOID  *RsaContext\r
   )\r
 {\r
+  ASSERT (RsaContext != NULL);\r
+\r
   //\r
   // Free OpenSSL RSA Context\r
   //\r
   RSA_free ((RSA *)RsaContext);\r
 }\r
 \r
-\r
 /**\r
-  Sets the tag-designated RSA key component into the established RSA context from\r
-  the user-specified nonnegative integer (octet string format represented in RSA\r
-  PKCS#1).\r
+  Sets the tag-designated key component into the established RSA context.\r
+\r
+  This function sets the tag-designated RSA key component into the established\r
+  RSA context from the user-specified non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If BigNumber is NULL, then the specified key componenet in RSA context is cleared.\r
 \r
   If RsaContext is NULL, then ASSERT().\r
 \r
   @param[in, out]  RsaContext  Pointer to RSA context being set.\r
   @param[in]       KeyTag      Tag of RSA key component being set.\r
   @param[in]       BigNumber   Pointer to octet integer buffer.\r
-  @param[in]       BnLength    Length of big number buffer in bytes.\r
+                               If NULL, then the specified key componenet in RSA\r
+                               context is cleared.\r
+  @param[in]       BnSize      Size of big number buffer in bytes.\r
+                               If BigNumber is NULL, then it is ignored.\r
 \r
-  @return  TRUE   RSA key component was set successfully.\r
-  @return  FALSE  Invalid RSA key component tag.\r
+  @retval  TRUE   RSA key component was set successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 RsaSetKey (\r
-  IN OUT VOID         *RsaContext,\r
-  IN     RSA_KEY_TAG  KeyTag,\r
-  IN     CONST UINT8  *BigNumber,\r
-  IN     UINTN        BnLength\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  IN      CONST UINT8  *BigNumber,\r
+  IN      UINTN        BnSize\r
   )\r
 {\r
   RSA  *RsaKey;\r
@@ -107,7 +133,11 @@ RsaSetKey (
     if (RsaKey->n != NULL) {\r
       BN_free (RsaKey->n);\r
     }\r
-    RsaKey->n = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->n);\r
+    RsaKey->n = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n);\r
     break;\r
 \r
   //\r
@@ -117,7 +147,11 @@ RsaSetKey (
     if (RsaKey->e != NULL) {\r
       BN_free (RsaKey->e);\r
     }\r
-    RsaKey->e = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->e);\r
+    RsaKey->e = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e);\r
     break;\r
 \r
   //\r
@@ -127,7 +161,11 @@ RsaSetKey (
     if (RsaKey->d != NULL) {\r
       BN_free (RsaKey->d);\r
     }\r
-    RsaKey->d = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->d);\r
+    RsaKey->d = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d);\r
     break;\r
 \r
   //\r
@@ -137,7 +175,11 @@ RsaSetKey (
     if (RsaKey->p != NULL) {\r
       BN_free (RsaKey->p);\r
     }\r
-    RsaKey->p = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->p);\r
+    RsaKey->p = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p);\r
     break;\r
 \r
   //\r
@@ -147,7 +189,11 @@ RsaSetKey (
     if (RsaKey->q != NULL) {\r
       BN_free (RsaKey->q);\r
     }\r
-    RsaKey->q = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->q);\r
+    RsaKey->q = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q);\r
     break;\r
 \r
   //\r
@@ -157,7 +203,11 @@ RsaSetKey (
     if (RsaKey->dmp1 != NULL) {\r
       BN_free (RsaKey->dmp1);\r
     }\r
-    RsaKey->dmp1 = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->dmp1);\r
+    RsaKey->dmp1 = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1);\r
     break;\r
 \r
   //\r
@@ -167,7 +217,11 @@ RsaSetKey (
     if (RsaKey->dmq1 != NULL) {\r
       BN_free (RsaKey->dmq1);\r
     }\r
-    RsaKey->dmq1 = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->dmq1);\r
+    RsaKey->dmq1 = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1);\r
     break;\r
 \r
   //\r
@@ -177,16 +231,382 @@ RsaSetKey (
     if (RsaKey->iqmp != NULL) {\r
       BN_free (RsaKey->iqmp);\r
     }\r
-    RsaKey->iqmp = BN_bin2bn (BigNumber, (int)BnLength, RsaKey->iqmp);\r
+    RsaKey->iqmp = NULL;\r
+    if (BigNumber == NULL) {\r
+      break;\r
+    }\r
+    RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp);\r
+    break;\r
+\r
+  default:\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Gets the tag-designated RSA key component from the established RSA context.\r
+\r
+  This function retrieves the tag-designated RSA key component from the\r
+  established RSA context as a non-negative integer (octet string format\r
+  represented in RSA PKCS#1).\r
+  If specified key component has not been set or has been cleared, then returned\r
+  BnSize is set to 0.\r
+  If the BigNumber buffer is too small to hold the contents of the key, FALSE\r
+  is returned and BnSize is set to the required buffer size to obtain the key.\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+  If BnSize is NULL, then ASSERT().\r
+  If BnSize is large enough but BigNumber is NULL, then ASSERT().\r
+\r
+  @param[in, out]  RsaContext  Pointer to RSA context being set.\r
+  @param[in]       KeyTag      Tag of RSA key component being set.\r
+  @param[out]      BigNumber   Pointer to octet integer buffer.\r
+  @param[in, out]  BnSize      On input, the size of big number buffer in bytes.\r
+                               On output, the size of data returned in big number buffer in bytes.\r
+\r
+  @retval  TRUE   RSA key component was retrieved successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+  @retval  FALSE  BnSize is too small.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGetKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      RSA_KEY_TAG  KeyTag,\r
+  OUT     UINT8        *BigNumber,\r
+  IN OUT  UINTN        *BnSize\r
+  )\r
+{\r
+  RSA    *RsaKey;\r
+  BIGNUM *BnKey;\r
+  UINTN  Size;\r
+\r
+  ASSERT (RsaContext != NULL);\r
+  ASSERT (BnSize != NULL);\r
+\r
+  RsaKey  = (RSA *) RsaContext;\r
+  Size    = *BnSize;\r
+  *BnSize = 0;\r
+\r
+  switch (KeyTag) {\r
+\r
+  //\r
+  // RSA Public Modulus (N)\r
+  //\r
+  case RsaKeyN:\r
+    if (RsaKey->n == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->n;\r
+    break;\r
+\r
+  //\r
+  // RSA Public Exponent (e)\r
+  //\r
+  case RsaKeyE:\r
+    if (RsaKey->e == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->e;\r
+    break;\r
+\r
+  //\r
+  // RSA Private Exponent (d)\r
+  //\r
+  case RsaKeyD:\r
+    if (RsaKey->d == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->d;\r
+    break;\r
+\r
+  //\r
+  // RSA Secret Prime Factor of Modulus (p)\r
+  //\r
+  case RsaKeyP:\r
+    if (RsaKey->p == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->p;\r
+    break;\r
+\r
+  //\r
+  // RSA Secret Prime Factor of Modules (q)\r
+  //\r
+  case RsaKeyQ:\r
+    if (RsaKey->q == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->q;\r
+    break;\r
+\r
+  //\r
+  // p's CRT Exponent (== d mod (p - 1))\r
+  //\r
+  case RsaKeyDp:\r
+    if (RsaKey->dmp1 == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->dmp1;\r
+    break;\r
+\r
+  //\r
+  // q's CRT Exponent (== d mod (q - 1))\r
+  //\r
+  case RsaKeyDq:\r
+    if (RsaKey->dmq1 == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->dmq1;\r
+    break;\r
+\r
+  //\r
+  // The CRT Coefficient (== 1/q mod p)\r
+  //\r
+  case RsaKeyQInv:\r
+    if (RsaKey->iqmp == NULL) {\r
+      return TRUE;\r
+    }\r
+    BnKey = RsaKey->iqmp;\r
     break;\r
 \r
   default:\r
     return FALSE;\r
   }\r
 \r
+  *BnSize = Size;\r
+  Size    = BN_num_bytes (BnKey);\r
+\r
+  if (*BnSize < Size) {\r
+    *BnSize = Size;\r
+    return FALSE;\r
+  }\r
+\r
+  ASSERT (BigNumber != NULL);\r
+  *BnSize = BN_bn2bin (BnKey, BigNumber) ;\r
+  \r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Generates RSA key components.\r
+\r
+  This function generates RSA key components. It takes RSA public exponent E and\r
+  length in bits of RSA modulus N as input, and generates all key components.\r
+  If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.\r
+\r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+\r
+  @param[in, out]  RsaContext           Pointer to RSA context being set.\r
+  @param[in]       ModulusLength        Length of RSA modulus N in bits.\r
+  @param[in]       PublicExponent       Pointer to RSA public exponent.\r
+  @param[in]       PublicExponentSize   Size of RSA public exponent buffer in bytes. \r
+\r
+  @retval  TRUE   RSA key component was generated successfully.\r
+  @retval  FALSE  Invalid RSA key component tag.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaGenerateKey (\r
+  IN OUT  VOID         *RsaContext,\r
+  IN      UINTN        ModulusLength,\r
+  IN      CONST UINT8  *PublicExponent,\r
+  IN      UINTN        PublicExponentSize\r
+  )\r
+{\r
+  BIGNUM   *KeyE;\r
+  BOOLEAN  RetVal;\r
+\r
+  ASSERT (RsaContext != NULL);\r
+\r
+  KeyE = BN_new ();\r
+  if (PublicExponent == NULL) {\r
+    BN_set_word (KeyE, 0x10001);\r
+  } else {\r
+    BN_bin2bn (PublicExponent, (UINT32) PublicExponentSize, KeyE);\r
+  }\r
+\r
+  RetVal = FALSE;\r
+  if (RSA_generate_key_ex ((RSA *) RsaContext, (UINT32) ModulusLength, KeyE, NULL) == 1) {\r
+   RetVal = TRUE;\r
+  }\r
+\r
+  BN_free (KeyE);\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  Validates key components of RSA context.\r
+\r
+  This function validates key compoents of RSA context in following aspects:\r
+  - Whether p is a prime\r
+  - Whether q is a prime\r
+  - Whether n = p * q\r
+  - Whether d*e = 1  mod lcm(p-1,q-1)\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+\r
+  @param[in]  RsaContext  Pointer to RSA context to check.\r
+\r
+  @retval  TRUE   RSA key components are valid.\r
+  @retval  FALSE  RSA key components are not valid.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaCheckKey (\r
+  IN  VOID  *RsaContext\r
+  )\r
+{\r
+  UINTN  Reason;\r
+\r
+  ASSERT (RsaContext != NULL);\r
+\r
+  if  (RSA_check_key ((RSA *) RsaContext) != 1) {\r
+    Reason = ERR_GET_REASON (ERR_peek_last_error ());\r
+    if (Reason == RSA_R_P_NOT_PRIME ||\r
+        Reason == RSA_R_Q_NOT_PRIME ||\r
+        Reason == RSA_R_N_DOES_NOT_EQUAL_P_Q ||\r
+        Reason == RSA_R_D_E_NOT_CONGRUENT_TO_1) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
   return TRUE;\r
 }\r
 \r
+/**\r
+  Performs the PKCS1-v1_5 encoding methods defined in RSA PKCS #1.\r
+\r
+  @param  Message      Message buffer to be encoded.\r
+  @param  MessageSize  Size of message buffer in bytes.\r
+  @param  DigestInfo   Pointer to buffer of digest info for output.\r
+\r
+  @return  Size of DigestInfo in bytes.\r
+\r
+**/  \r
+UINTN\r
+DigestInfoEncoding (\r
+  IN   CONST UINT8  *Message,\r
+  IN   UINTN        MessageSize,\r
+  OUT  UINT8        *DigestInfo\r
+  )\r
+{\r
+  CONST UINT8  *HashDer;\r
+  UINTN        DerSize;\r
+\r
+  ASSERT (Message != NULL);\r
+  ASSERT (DigestInfo != NULL);\r
+\r
+  //\r
+  // The original message length is used to determine the hash algorithm since\r
+  // message is digest value hashed by the specified algorithm.\r
+  //\r
+  switch (MessageSize) {\r
+  case MD5_DIGEST_SIZE:\r
+    HashDer = Asn1IdMd5;\r
+    DerSize = sizeof (Asn1IdMd5);\r
+    break;\r
+  \r
+  case SHA1_DIGEST_SIZE:\r
+    HashDer = Asn1IdSha1;\r
+    DerSize = sizeof (Asn1IdSha1);\r
+    break;\r
+   \r
+  case SHA256_DIGEST_SIZE:\r
+    HashDer = Asn1IdSha256;\r
+    DerSize = sizeof (Asn1IdSha256);\r
+    break;\r
+  \r
+  default:\r
+    return FALSE;\r
+  }\r
+\r
+  CopyMem (DigestInfo, HashDer, DerSize);\r
+  CopyMem (DigestInfo + DerSize, Message, MessageSize);\r
+\r
+  return (DerSize + MessageSize);\r
+}\r
+\r
+/**\r
+  Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.\r
+\r
+  This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in\r
+  RSA PKCS#1.\r
+  If the Signature buffer is too small to hold the contents of signature, FALSE\r
+  is returned and SigSize is set to the required buffer size to obtain the signature.\r
+\r
+  If RsaContext is NULL, then ASSERT().\r
+  If MessageHash is NULL, then ASSERT().\r
+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().\r
+  If SigSize is large enough but Signature is NULL, then ASSERT().\r
+\r
+  @param[in]       RsaContext   Pointer to RSA context for signature generation.\r
+  @param[in]       MessageHash  Pointer to octet message hash to be signed.\r
+  @param[in]       HashSize     Size of the message hash in bytes.\r
+  @param[out]      Signature    Pointer to buffer to receive RSA PKCS1-v1_5 signature.\r
+  @param[in, out]  SigSize      On input, the size of Signature buffer in bytes.\r
+                                On output, the size of data returned in Signature buffer in bytes.\r
+\r
+  @retval  TRUE   Signature successfully generated in PKCS1-v1_5.\r
+  @retval  FALSE  Signature generation failed.\r
+  @retval  FALSE  SigSize is too small.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RsaPkcs1Sign (\r
+  IN      VOID         *RsaContext,\r
+  IN      CONST UINT8  *MessageHash,\r
+  IN      UINTN        HashSize,\r
+  OUT     UINT8        *Signature,\r
+  IN OUT  UINTN        *SigSize\r
+  )\r
+{\r
+  RSA      *Rsa;\r
+  UINTN    Size;\r
+  INTN     ReturnVal;\r
+\r
+  ASSERT (RsaContext != NULL);\r
+  ASSERT (MessageHash != NULL);\r
+  ASSERT ((HashSize == MD5_DIGEST_SIZE) ||\r
+          (HashSize == SHA1_DIGEST_SIZE) ||\r
+          (HashSize == SHA256_DIGEST_SIZE));\r
+\r
+  Rsa = (RSA *) RsaContext;\r
+  Size = BN_num_bytes (Rsa->n);\r
+\r
+  if (*SigSize < Size) {\r
+    *SigSize = Size;\r
+    return FALSE;\r
+  }\r
+\r
+  ASSERT (Signature != NULL);\r
+\r
+  Size = DigestInfoEncoding (MessageHash, HashSize, Signature);\r
+\r
+  ReturnVal = RSA_private_encrypt (\r
+                (UINT32) Size,\r
+                Signature,\r
+                Signature,\r
+                Rsa,\r
+                RSA_PKCS1_PADDING\r
+                );\r
+\r
+  if (ReturnVal < (INTN) Size) {\r
+    return FALSE;\r
+  }\r
+\r
+  *SigSize = (UINTN)ReturnVal;\r
+  return TRUE;\r
+}\r
 \r
 /**\r
   Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in\r
@@ -195,16 +615,16 @@ RsaSetKey (
   If RsaContext is NULL, then ASSERT().\r
   If MessageHash is NULL, then ASSERT().\r
   If Signature is NULL, then ASSERT().\r
-  If HashLength is not equal to the size of MD5, SHA-1 or SHA-256 digest, then ASSERT().\r
+  If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-224, SHA-512 or SHA-384 digest, then ASSERT().\r
 \r
   @param[in]  RsaContext   Pointer to RSA context for signature verification.\r
   @param[in]  MessageHash  Pointer to octet message hash to be checked.\r
-  @param[in]  HashLength   Length of the message hash in bytes.\r
+  @param[in]  HashSize     Size of the message hash in bytes.\r
   @param[in]  Signature    Pointer to RSA PKCS1-v1_5 signature to be verified.\r
-  @param[in]  SigLength    Length of signature in bytes.\r
+  @param[in]  SigSize      Size of signature in bytes.\r
 \r
-  @return  TRUE   Valid signature encoded in PKCS1-v1_5.\r
-  @return  FALSE  Invalid signature or invalid RSA context.\r
+  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.\r
+  @retval  FALSE  Invalid signature or invalid RSA context.\r
 \r
 **/\r
 BOOLEAN\r
@@ -212,9 +632,9 @@ EFIAPI
 RsaPkcs1Verify (\r
   IN  VOID         *RsaContext,\r
   IN  CONST UINT8  *MessageHash,\r
-  IN  UINTN        HashLength,\r
+  IN  UINTN        HashSize,\r
   IN  UINT8        *Signature,\r
-  IN  UINTN        SigLength\r
+  IN  UINTN        SigSize\r
   )\r
 {\r
   INTN     Length;\r
@@ -227,17 +647,17 @@ RsaPkcs1Verify (
   ASSERT (Signature   != NULL);\r
 \r
   //\r
-  // ASSERT if unsupported hash length:\r
+  // ASSERT if unsupported hash size:\r
   //    Only MD5, SHA-1 or SHA-256 digest size is supported\r
   //\r
-  ASSERT ((HashLength == MD5_DIGEST_SIZE) || (HashLength == SHA1_DIGEST_SIZE) ||\r
-          (HashLength == SHA256_DIGEST_SIZE));\r
+  ASSERT ((HashSize == MD5_DIGEST_SIZE) || (HashSize == SHA1_DIGEST_SIZE) ||\r
+          (HashSize == SHA256_DIGEST_SIZE));\r
 \r
   //\r
   // RSA PKCS#1 Signature Decoding using OpenSSL RSA Decryption with Public Key\r
   //\r
   Length = RSA_public_decrypt (\r
-             (int)SigLength,\r
+             (UINT32) SigSize,\r
              Signature,\r
              Signature,\r
              RsaContext,\r
@@ -246,10 +666,10 @@ RsaPkcs1Verify (
 \r
   //\r
   // Invalid RSA Key or PKCS#1 Padding Checking Failed (if Length < 0)\r
-  // NOTE: Length should be the addition of HashLength and some DER value.\r
+  // NOTE: Length should be the addition of HashSize and some DER value.\r
   //       Ignore more strict length checking here.\r
   //\r
-  if (Length < (INTN) HashLength) {\r
+  if (Length < (INTN) HashSize) {\r
     return FALSE;\r
   }\r
 \r
@@ -263,7 +683,7 @@ RsaPkcs1Verify (
   //       Then Memory Comparing should skip the DER value of the underlying SEQUENCE\r
   //       type and AlgorithmIdentifier.\r
   //\r
-  if (CompareMem (MessageHash, Signature + Length - HashLength, HashLength) == 0) {\r
+  if (CompareMem (MessageHash, Signature + Length - HashSize, HashSize) == 0) {\r
     //\r
     // Valid RSA PKCS#1 Signature\r
     //\r
diff --git a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c
new file mode 100644 (file)
index 0000000..3ead6d1
--- /dev/null
@@ -0,0 +1,88 @@
+/** @file\r
+  Pseudorandom Number Generator Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/rand.h>\r
+\r
+//\r
+// Default seed for UEFI Crypto Library\r
+//\r
+CONST UINT8  DefaultSeed[] = "UEFI Crypto Library default seed";\r
+\r
+/**\r
+  Sets up the seed value for the pseudorandom number generator.\r
+\r
+  This function sets up the seed value for the pseudorandom number generator.\r
+  If Seed is not NULL, then the seed passed in is used.\r
+  If Seed is NULL, then default seed is used.\r
+\r
+  @param[in]  Seed      Pointer to seed value.\r
+                        If NULL, default seed is used.\r
+  @param[in]  SeedSize  Size of seed value.\r
+                        If Seed is NULL, this parameter is ignored.\r
+\r
+  @retval TRUE   Pseudorandom number generator has enough entropy for random generation.\r
+  @retval FALSE  Pseudorandom number generator does not have enough entropy for random generation.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomSeed (\r
+  IN  CONST  UINT8  *Seed  OPTIONAL,\r
+  IN  UINTN         SeedSize\r
+  )\r
+{\r
+  //\r
+  // Seed the pseudorandom number generator with user-supplied value.\r
+  // NOTE: A cryptographic PRNG must be seeded with unpredictable data.\r
+  //\r
+  if (Seed != NULL) {\r
+    RAND_seed (Seed, (UINT32) SeedSize);\r
+  } else {\r
+    RAND_seed (DefaultSeed, sizeof (DefaultSeed));\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Generates a pseudorandom byte stream of the specified size.\r
+\r
+  If Output is NULL, then ASSERT().\r
+\r
+  @param[out]  Output  Pointer to buffer to receive random value.\r
+  @param[in]   Size    Size of randome bytes to generate.\r
+\r
+  @retval TRUE   Pseudorandom byte stream generated successfully.\r
+  @retval FALSE  Pseudorandom number generator fails to generate due to lack of entropy.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RandomBytes (\r
+  OUT  UINT8  *Output,\r
+  IN   UINTN  Size\r
+  )\r
+{\r
+  ASSERT (Output != NULL);\r
+\r
+  //\r
+  // Generate random data.\r
+  //\r
+  if (RAND_bytes (Output, (UINT32) Size) != 1) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
index d31095b..4b5ffd1 100644 (file)
@@ -57,8 +57,6 @@
   SysCall/Ia32/MathLShiftS64.S      | GCC\r
   SysCall/Ia32/MathRShiftU64.S      | GCC\r
 \r
-  SysCall/Ia32/Alloca.S             | GCC\r
-\r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   CryptoPkg/CryptoPkg.dec\r
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
new file mode 100644 (file)
index 0000000..21ebd00
--- /dev/null
@@ -0,0 +1,78 @@
+## @file\r
+#  Cryptographic Library Instance for SMM driver.\r
+#\r
+#  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmmCryptLib\r
+  FILE_GUID                      = 028080a3-8958-4a62-a1a8-0fa1da162007\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = BaseCryptLib|DXE_SMM_DRIVER SMM_CORE\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources]\r
+  Hash/CryptMd5.c\r
+  Hash/CryptSha1.c\r
+  Hash/CryptSha256.c\r
+  Pk/CryptRsa.c\r
+  Pk/CryptPkcs7.c\r
+\r
+  SysCall/CrtWrapper.c\r
+  SysCall/RealTimeClock.c\r
+  SysCall/BaseMemAllocation.c\r
+\r
+[Sources.Ia32]\r
+  SysCall/HelperWrapper.c\r
+\r
+  SysCall/Ia32/MathMultS64x64.c     | MSFT\r
+  SysCall/Ia32/MathDivU64x64.c      | MSFT\r
+  SysCall/Ia32/MathReminderU64x64.c | MSFT\r
+  SysCall/Ia32/MathLShiftS64.c      | MSFT\r
+  SysCall/Ia32/MathRShiftU64.c      | MSFT\r
+\r
+  SysCall/Ia32/MathMultS64x64.c     | INTEL\r
+  SysCall/Ia32/MathDivU64x64.c      | INTEL\r
+  SysCall/Ia32/MathReminderU64x64.c | INTEL\r
+  SysCall/Ia32/MathLShiftS64.c      | INTEL\r
+  SysCall/Ia32/MathRShiftU64.c      | INTEL\r
+\r
+  SysCall/Ia32/MathMultS64x64.S     | GCC\r
+  SysCall/Ia32/MathDivU64x64.S      | GCC\r
+  SysCall/Ia32/MathReminderU64x64.S | GCC\r
+  SysCall/Ia32/MathLShiftS64.S      | GCC\r
+  SysCall/Ia32/MathRShiftU64.S      | GCC\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  CryptoPkg/CryptoPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  IoLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  OpensslLib\r
+  IntrinsicLib\r
+\r
+#\r
+# Remove these [BuildOptions] after this library is cleaned up\r
+#\r
+[BuildOptions]\r
+  GCC:*_GCC44_IA32_CC_FLAGS = "-D__cdecl=__attribute__((cdecl))" "-D__declspec(t)=__attribute__((t))"\r
+  \r
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/Alloca.S
deleted file mode 100644 (file)
index 8496833..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution.  The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-#   Alloca.S\r
-#\r
-# Abstract:\r
-#\r
-#   Implementation for allocation of automatically reclaimed memory, which is\r
-#   used to allocate space off the runtime stack.\r
-#   (NOTE: There is a assumption in this code that the page size equal to 4K)\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-\r
-    .686:\r
-    .code:\r
-\r
-ASM_GLOBAL ASM_PFX(_alloca)\r
-\r
-#------------------------------------------------------------------------------\r
-#\r
-# void __cdecl _alloca (unsigned size)\r
-#\r
-#------------------------------------------------------------------------------\r
-ASM_PFX(_alloca):\r
-\r
-    pushl   %ecx\r
-    cmpl    $0x1000, %eax\r
-    leal    8(%esp), %ecx\r
-    jb      LastPage\r
-\r
-ProbePages:\r
-    subl    $0x1000, %ecx\r
-    subl    $0x1000, %eax\r
-    testl   %eax, 0(%ecx)\r
-    cmpl    $0x1000, %eax\r
-    jae     ProbePages\r
-\r
-LastPage:\r
-    subl    %eax, %ecx\r
-    movl    %esp, %eax\r
-    testl   %eax, 0(%ecx)\r
-\r
-    movl    %ecx, %esp\r
-    movl    0(%eax), %ecx\r
-    movl    4(%eax), %eax\r
-    pushl   %eax\r
-\r
-    ret\r
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/RealTimeClock.c b/CryptoPkg/Library/BaseCryptLib/SysCall/RealTimeClock.c
new file mode 100644 (file)
index 0000000..84617b4
--- /dev/null
@@ -0,0 +1,222 @@
+/** @file\r
+  C Run-Time Libraries (CRT) Time Management Routines Wrapper Implementation\r
+  for OpenSSL-based Cryptographic Library (used in SMM).\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/IoLib.h>\r
+#include <OpenSslSupport.h>\r
+\r
+#define PCAT_RTC_ADDRESS_REGISTER 0x70\r
+#define PCAT_RTC_DATA_REGISTER    0x71\r
+\r
+#define RTC_ADDRESS_SECONDS           0   // R/W  Range 0..59\r
+#define RTC_ADDRESS_SECONDS_ALARM     1   // R/W  Range 0..59\r
+#define RTC_ADDRESS_MINUTES           2   // R/W  Range 0..59\r
+#define RTC_ADDRESS_MINUTES_ALARM     3   // R/W  Range 0..59\r
+#define RTC_ADDRESS_HOURS             4   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM\r
+#define RTC_ADDRESS_HOURS_ALARM       5   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM\r
+#define RTC_ADDRESS_DAY_OF_THE_WEEK   6   // R/W  Range 1..7\r
+#define RTC_ADDRESS_DAY_OF_THE_MONTH  7   // R/W  Range 1..31\r
+#define RTC_ADDRESS_MONTH             8   // R/W  Range 1..12\r
+#define RTC_ADDRESS_YEAR              9   // R/W  Range 0..99\r
+#define RTC_ADDRESS_REGISTER_A        10  // R/W[0..6]  R0[7]\r
+#define RTC_ADDRESS_REGISTER_B        11  // R/W\r
+#define RTC_ADDRESS_REGISTER_C        12  // RO\r
+#define RTC_ADDRESS_REGISTER_D        13  // RO\r
+#define RTC_ADDRESS_CENTURY           50  // R/W  Range 19..20 Bit 8 is R/W\r
+\r
+//\r
+// Register A\r
+//\r
+typedef struct {\r
+  UINT8 RS : 4;   // Rate Selection Bits\r
+  UINT8 DV : 3;   // Divisor\r
+  UINT8 UIP : 1;  // Update in progress\r
+} RTC_REGISTER_A_BITS;\r
+\r
+typedef union {\r
+  RTC_REGISTER_A_BITS Bits;\r
+  UINT8               Data;\r
+} RTC_REGISTER_A;\r
+\r
+//\r
+// Register B\r
+//\r
+typedef struct {\r
+  UINT8 DSE : 1;  // 0 - Daylight saving disabled  1 - Daylight savings enabled\r
+  UINT8 MIL : 1;  // 0 - 12 hour mode              1 - 24 hour mode\r
+  UINT8 DM : 1;   // 0 - BCD Format                1 - Binary Format\r
+  UINT8 SQWE : 1; // 0 - Disable SQWE output       1 - Enable SQWE output\r
+  UINT8 UIE : 1;  // 0 - Update INT disabled       1 - Update INT enabled\r
+  UINT8 AIE : 1;  // 0 - Alarm INT disabled        1 - Alarm INT Enabled\r
+  UINT8 PIE : 1;  // 0 - Periodic INT disabled     1 - Periodic INT Enabled\r
+  UINT8 SET : 1;  // 0 - Normal operation.         1 - Updates inhibited\r
+} RTC_REGISTER_B_BITS;\r
+\r
+typedef union {\r
+  RTC_REGISTER_B_BITS Bits;\r
+  UINT8               Data;\r
+} RTC_REGISTER_B;\r
+\r
+//\r
+// -- Time Management Routines --\r
+//\r
+\r
+#define IsLeap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))\r
+#define SECSPERHOUR (60 * 60)\r
+#define SECSPERDAY  (24 * SECSPERHOUR)\r
+\r
+//\r
+//  The arrays give the cumulative number of days up to the first of the\r
+//  month number used as the index (1 -> 12) for regular and leap years.\r
+//  The value at index 13 is for the whole year.\r
+//\r
+UINTN CumulativeDays[2][14] = {\r
+  {\r
+    0,\r
+    0,\r
+    31,\r
+    31 + 28,\r
+    31 + 28 + 31,\r
+    31 + 28 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,\r
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31\r
+  },\r
+  {\r
+    0,\r
+    0,\r
+    31,\r
+    31 + 29,\r
+    31 + 29 + 31,\r
+    31 + 29 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,\r
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 \r
+  }\r
+};\r
+\r
+/**\r
+  Read RTC content through its registers.\r
+\r
+  @param  Address  Address offset of RTC. It is recommended to use macros such as\r
+                   RTC_ADDRESS_SECONDS.\r
+\r
+  @return The data of UINT8 type read from RTC.\r
+**/\r
+UINT8\r
+RtcRead (\r
+  IN  UINT8 Address\r
+  )\r
+{\r
+  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & BIT7)));\r
+  return IoRead8 (PCAT_RTC_DATA_REGISTER);\r
+}\r
+\r
+/* Get the system time as seconds elapsed since midnight, January 1, 1970. */\r
+//INTN time(\r
+//  INTN *timer\r
+//  )\r
+time_t time (time_t *timer)\r
+{\r
+  UINT16          Year;\r
+  UINT8           Month;\r
+  UINT8           Day;\r
+  UINT8           Hour;\r
+  UINT8           Minute;\r
+  UINT8           Second;\r
+  UINT8           Century;\r
+  RTC_REGISTER_A  RegisterA;\r
+  RTC_REGISTER_B  RegisterB;\r
+  BOOLEAN         IsPM;\r
+  UINT16          YearIndex;\r
+\r
+  RegisterA.Data  = RtcRead (RTC_ADDRESS_REGISTER_A);\r
+  while (RegisterA.Bits.UIP == 1) {\r
+    CpuPause();\r
+    RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
+  }\r
+\r
+  Second  = RtcRead (RTC_ADDRESS_SECONDS);\r
+  Minute  = RtcRead (RTC_ADDRESS_MINUTES);\r
+  Hour    = RtcRead (RTC_ADDRESS_HOURS);\r
+  Day     = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
+  Month   = RtcRead (RTC_ADDRESS_MONTH);\r
+  Year    = RtcRead (RTC_ADDRESS_YEAR);\r
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
+\r
+  RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
+\r
+  if ((Hour & BIT7) != 0) {\r
+    IsPM = TRUE;\r
+  } else {\r
+    IsPM = FALSE;\r
+  }\r
+  Hour = (UINT8) (Hour & 0x7f);\r
+\r
+  if (RegisterB.Bits.DM == 0) {\r
+    Year    = BcdToDecimal8 ((UINT8) Year);\r
+    Month   = BcdToDecimal8 (Month);\r
+    Day     = BcdToDecimal8 (Day);\r
+    Hour    = BcdToDecimal8 (Hour);\r
+    Minute  = BcdToDecimal8 (Minute);\r
+    Second  = BcdToDecimal8 (Second);\r
+  }\r
+  Century   = BcdToDecimal8 (Century);\r
+\r
+  Year = (UINT16) (Century * 100 + Year);\r
+\r
+  //\r
+  // If time is in 12 hour format, convert it to 24 hour format\r
+  //\r
+  if (RegisterB.Bits.MIL == 0) {\r
+    if (IsPM && Hour < 12) {\r
+      Hour = (UINT8) (Hour + 12);\r
+    }\r
+    if (!IsPM && Hour == 12) {\r
+      Hour = 0;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Years Handling\r
+  // UTime should now be set to 00:00:00 on Jan 1 of the current year.\r
+  //\r
+  for (YearIndex = 1970, *timer = 0; YearIndex != Year; YearIndex++) {\r
+    *timer = *timer + (time_t)(CumulativeDays[IsLeap(YearIndex)][13] * SECSPERDAY);\r
+  }\r
+\r
+  //\r
+  // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment\r
+  //\r
+  ASSERT (Month <= 12);\r
+  *timer = *timer + \r
+           (time_t)(CumulativeDays[IsLeap(Year)][Month] * SECSPERDAY) + \r
+           (time_t)((Day - 1) * SECSPERDAY) + \r
+           (time_t)(Hour * SECSPERHOUR) + \r
+           (time_t)(Minute * 60) + \r
+           (time_t)Second;\r
+\r
+  return *timer;\r
+}\r
index 1e1a840..9c1083d 100644 (file)
@@ -21,6 +21,7 @@
   LIBRARY_CLASS                  = OpensslLib\r
   OPENSSL_PATH                   = openssl-0.9.8l\r
   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\r
+  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\r
   \r
 #\r
 # OPENSSL_FLAGS is set to define the following flags to be compatible with \r
   DebugLib\r
 \r
 [BuildOptions]\r
-   MSFT:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /WX- /GL- \r
-  INTEL:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) /WX- \r
-    GCC:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) -w\r
+   MSFT:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) $(OPENSSL_EXFLAGS) /WX- /GL- \r
+  INTEL:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) $(OPENSSL_EXFLAGS) /WX- \r
+    GCC:*_*_*_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_EXFLAGS) -w\r