]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Application/Cryptest/Cryptest.c
Add CryptoPkg (from UDK2010.UP3)
[mirror_edk2.git] / CryptoPkg / Application / Cryptest / Cryptest.c
CommitLineData
97f98500
HT
1/** @file \r
2 Application for Cryptographic Primitives Validation.\r
3\r
4Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Uefi.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiLib.h>\r
20#include <Library/UefiApplicationEntryPoint.h>\r
21#include <Library/DebugLib.h>\r
22\r
23#include <Library/BaseCryptLib.h>\r
24\r
25//\r
26// Max Known Digest Size is SHA512 Output (64 bytes) by far\r
27//\r
28#define MAX_DIGEST_SIZE 64\r
29\r
30//\r
31// Message string for digest validation\r
32//\r
33GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *HashData = "abc";\r
34\r
35//\r
36// Result for MD5("abc"). (From "A.5 Test suite" of IETF RFC1321)\r
37//\r
38GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Md5Digest[MD5_DIGEST_SIZE] = {\r
39 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72\r
40 };\r
41\r
42//\r
43// Result for SHA-1("abc"). (From "A.1 SHA-1 Example" of NIST FIPS 180-2)\r
44//\r
45GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha1Digest[SHA1_DIGEST_SIZE] = {\r
46 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,\r
47 0x9c, 0xd0, 0xd8, 0x9d\r
48 };\r
49\r
50//\r
51// Result for SHA-256("abc"). (From "B.1 SHA-256 Example" of NIST FIPS 180-2)\r
52//\r
53GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha256Digest[SHA256_DIGEST_SIZE] = {\r
54 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,\r
55 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad\r
56 };\r
57\r
58//\r
59// RSA PKCS#1 Validation Data from OpenSSL "Fips_rsa_selftest.c"\r
60//\r
61\r
62// Public Modulus of RSA Key\r
63GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaN[] = {\r
64 0xBB, 0xF8, 0x2F, 0x09, 0x06, 0x82, 0xCE, 0x9C, 0x23, 0x38, 0xAC, 0x2B, 0x9D, 0xA8, 0x71, 0xF7, \r
65 0x36, 0x8D, 0x07, 0xEE, 0xD4, 0x10, 0x43, 0xA4, 0x40, 0xD6, 0xB6, 0xF0, 0x74, 0x54, 0xF5, 0x1F,\r
66 0xB8, 0xDF, 0xBA, 0xAF, 0x03, 0x5C, 0x02, 0xAB, 0x61, 0xEA, 0x48, 0xCE, 0xEB, 0x6F, 0xCD, 0x48,\r
67 0x76, 0xED, 0x52, 0x0D, 0x60, 0xE1, 0xEC, 0x46, 0x19, 0x71, 0x9D, 0x8A, 0x5B, 0x8B, 0x80, 0x7F,\r
68 0xAF, 0xB8, 0xE0, 0xA3, 0xDF, 0xC7, 0x37, 0x72, 0x3E, 0xE6, 0xB4, 0xB7, 0xD9, 0x3A, 0x25, 0x84,\r
69 0xEE, 0x6A, 0x64, 0x9D, 0x06, 0x09, 0x53, 0x74, 0x88, 0x34, 0xB2, 0x45, 0x45, 0x98, 0x39, 0x4E,\r
70 0xE0, 0xAA, 0xB1, 0x2D, 0x7B, 0x61, 0xA5, 0x1F, 0x52, 0x7A, 0x9A, 0x41, 0xF6, 0xC1, 0x68, 0x7F,\r
71 0xE2, 0x53, 0x72, 0x98, 0xCA, 0x2A, 0x8F, 0x59, 0x46, 0xF8, 0xE5, 0xFD, 0x09, 0x1D, 0xBD, 0xCB\r
72 };\r
73\r
74// Public Exponent of RSA Key\r
75GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaE[] = { 0x11 };\r
76\r
77// Known Answer Test (KAT) Data for RSA PKCS#1 Signing\r
78GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 RsaSignData[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";\r
79\r
80// Known Signature for the above message, under SHA-1 Digest\r
81GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 RsaPkcs1Signature[] = {\r
82 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, 0x4A, 0xFD, 0x1A, 0x05,\r
83 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51,\r
84 0x55, 0x77, 0x90, 0xCF, 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,\r
85 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, 0x20, 0x22, 0xBE, 0x59,\r
86 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF,\r
87 0x4E, 0xCA, 0x2E, 0x4E, 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,\r
88 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, 0x72, 0x05, 0xDE, 0xE6,\r
89 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4\r
90 };\r
91\r
92/**\r
93 Validate MSFT Authenticode using PKCS#7 Verification Interfaces.\r
94\r
95 @return EFI_SUCCESS Validation succeeds. \r
96\r
97**/\r
98BOOLEAN\r
99AuthenticodeVerify (\r
100 VOID\r
101 );\r
102\r
103/**\r
104 Validate UEFI-OpenSSL Digest Interfaces.\r
105\r
106 @return EFI_SUCCESS Validation succeeded.\r
107\r
108**/\r
109EFI_STATUS\r
110ValidateCryptDigest (\r
111 VOID\r
112 )\r
113{\r
114 UINTN CtxSize;\r
115 VOID *HashCtx;\r
116 UINTN DataSize;\r
117 UINT8 Digest[MAX_DIGEST_SIZE];\r
118 UINTN Index;\r
119 BOOLEAN Status;\r
120\r
121 Print (L" UEFI-OpenSSL Hash Engine Testing (Hashing(\"abc\")): ");\r
122 DataSize = AsciiStrLen (HashData);\r
123\r
124 //\r
125 // MD5 Digest Validation\r
126 //\r
127 ZeroMem (Digest, MAX_DIGEST_SIZE);\r
128 CtxSize = Md5GetContextSize ();\r
129 HashCtx = AllocatePool (CtxSize);\r
130 Status = Md5Init (HashCtx);\r
131 Status = Md5Update (HashCtx, HashData, DataSize);\r
132 Status = Md5Final (HashCtx, Digest);\r
133 FreePool (HashCtx);\r
134 Print (L"\n - MD5 Digest: \n = 0x");\r
135 for (Index = 0; Index < MD5_DIGEST_SIZE; Index++) {\r
136 Print (L"%02x", Digest[Index]);\r
137 }\r
138 if (CompareMem (Digest, Md5Digest, MD5_DIGEST_SIZE) == 0) {\r
139 Print (L" [Pass]");\r
140 } else {\r
141 Print (L" [Failed]");\r
142 }\r
143\r
144 //\r
145 // SHA-1 Digest Validation\r
146 //\r
147 ZeroMem (Digest, MAX_DIGEST_SIZE);\r
148 CtxSize = Sha1GetContextSize ();\r
149 HashCtx = AllocatePool (CtxSize);\r
150 Status = Sha1Init (HashCtx);\r
151 Status = Sha1Update (HashCtx, HashData, DataSize);\r
152 Status = Sha1Final (HashCtx, Digest);\r
153 FreePool (HashCtx);\r
154 Print (L"\n - SHA-1 Digest: \n = 0x");\r
155 for (Index = 0; Index < SHA1_DIGEST_SIZE; Index++) {\r
156 Print (L"%02x", Digest[Index]);\r
157 }\r
158 if (CompareMem (Digest, Sha1Digest, SHA1_DIGEST_SIZE) == 0) {\r
159 Print (L" [Pass]");\r
160 } else {\r
161 Print (L" [Failed]");\r
162 }\r
163\r
164 //\r
165 // SHA256 Digest Validation\r
166 //\r
167 ZeroMem (Digest, MAX_DIGEST_SIZE);\r
168 CtxSize = Sha256GetContextSize ();\r
169 HashCtx = AllocatePool (CtxSize);\r
170 Status = Sha256Init (HashCtx);\r
171 Status = Sha256Update (HashCtx, HashData, DataSize);\r
172 Status = Sha256Final (HashCtx, Digest);\r
173 FreePool (HashCtx);\r
174 Print (L"\n - SHA-256 Digest: \n = 0x");\r
175 for (Index = 0; Index < SHA256_DIGEST_SIZE; Index++) {\r
176 Print (L"%02x", Digest[Index]);\r
177 }\r
178 if (CompareMem (Digest, Sha256Digest, SHA256_DIGEST_SIZE) == 0) {\r
179 Print (L" [Pass]");\r
180 } else {\r
181 Print (L" [Failed]");\r
182 } \r
183\r
184 Print (L"\n");\r
185 \r
186 return EFI_SUCCESS;\r
187}\r
188\r
189\r
190/**\r
191 Validate UEFI-OpenSSL Message Authentication Codes Interfaces.\r
192\r
193 @return EFI_SUCCESS Validation succeeded. \r
194\r
195**/\r
196EFI_STATUS\r
197ValidateCryptHmac (\r
198 VOID\r
199 )\r
200{\r
201 Print (L"\n UEFI-OpenSSL HMAC Engine Testing: ");\r
202 Print (L"\n ==> No HMAC Support in Base Crypto Library!\n");\r
203\r
204 return EFI_SUCCESS;\r
205}\r
206\r
207\r
208/**\r
209 Validate UEFI-OpenSSL Block Ciphers (Symmetric Crypto) Interfaces.\r
210\r
211 @return EFI_SUCCESS Validation succeeded.\r
212\r
213**/\r
214EFI_STATUS\r
215ValidateCryptBlockCipher (\r
216 VOID\r
217 )\r
218{\r
219 Print (L"\n UEFI-OpenSSL Block Cipher Engine Testing: ");\r
220 Print (L"\n ==> No Block Cipher Support in Base Crypto Library!\n");\r
221\r
222 return EFI_SUCCESS;\r
223}\r
224\r
225\r
226/**\r
227 Validate UEFI-OpenSSL RSA Interfaces.\r
228\r
229 @return EFI_SUCCESS Validation succeeded.\r
230\r
231**/\r
232EFI_STATUS\r
233ValidateCryptRsa (\r
234 VOID\r
235 )\r
236{\r
237 VOID *Rsa;\r
238 UINT8 mHash[SHA1_DIGEST_SIZE];\r
239 UINTN HashSize;\r
240 UINTN CtxSize;\r
241 VOID *Sha1Ctx;\r
242 UINT8 *Signature;\r
243 UINTN SigSize;\r
244 BOOLEAN Status;\r
245\r
246 Print (L"\n UEFI-OpenSSL RSA Engine Testing: ");\r
247\r
248 //\r
249 // Generate & Initialize RSA Context\r
250 //\r
251 Rsa = RsaNew ();\r
252 Print (L"\n - Generate RSA Context .............. ");\r
253 if (Rsa != NULL) {\r
254 Print (L"[Pass]");\r
255 } else {\r
256 Print (L"[Failed]");\r
257 }\r
258\r
259 //\r
260 // Set RSA Key Components\r
261 // NOTE: Only N and E are needed to be set as RSA public key for signature verification\r
262 //\r
263 Print (L"\n - Set RSA Key Components ............ ");\r
264 Status = RsaSetKey (Rsa, RsaKeyN, RsaN, sizeof (RsaN));\r
265 Status = RsaSetKey (Rsa, RsaKeyE, RsaE, sizeof (RsaE));\r
266 if (Status) {\r
267 Print (L"[Pass]");\r
268 } else {\r
269 Print (L"[Failed]");\r
270 }\r
271\r
272 //\r
273 // SHA-1 Digest Message for PKCS#1 Signature \r
274 //\r
275 Print (L"\n - Hash Original Message ............. ");\r
276 HashSize = SHA1_DIGEST_SIZE;\r
277 ZeroMem (mHash, HashSize);\r
278 CtxSize = Sha1GetContextSize ();\r
279 Sha1Ctx = AllocatePool (CtxSize);\r
280 Status = Sha1Init (Sha1Ctx);\r
281 Status = Sha1Update (Sha1Ctx, RsaSignData, AsciiStrLen (RsaSignData));\r
282 Status = Sha1Final (Sha1Ctx, mHash);\r
283 FreePool (Sha1Ctx);\r
284 if (Status) {\r
285 Print (L"[Pass]");\r
286 } else {\r
287 Print (L"[Failed]");\r
288 }\r
289\r
290 //\r
291 // Verify RSA PKCS#1-encoded Signature\r
292 //\r
293 Print (L"\n - PKCS#1 Signature Verification ..... ");\r
294 SigSize = sizeof (RsaPkcs1Signature);\r
295 Signature = (UINT8 *)AllocatePool (SigSize);\r
296 CopyMem (Signature, RsaPkcs1Signature, SigSize);\r
297 Status = RsaPkcs1Verify (Rsa, mHash, HashSize, Signature, SigSize);\r
298 if (Status) {\r
299 Print (L"[Pass]");\r
300 } else {\r
301 Print (L"[Failed]");\r
302 } \r
303\r
304 //\r
305 // Release Resources\r
306 //\r
307 RsaFree (Rsa);\r
308 Print (L"\n - Release RSA Context ............... [Pass]");\r
309\r
310 Print (L"\n");\r
311\r
312 return EFI_SUCCESS;\r
313}\r
314\r
315/**\r
316 Validate UEFI-OpenSSL PKCS#7 Verification Interfaces.\r
317\r
318 @return EFI_SUCCESS Validation succeeded.\r
319\r
320**/\r
321EFI_STATUS\r
322ValidateAuthenticode (\r
323 VOID\r
324 )\r
325{\r
326 Print (L"\n UEFI-OpenSSL PKCS#7-Signed-Data Testing: ");\r
327\r
328 Print (L"\n - Authenticode (PKCS#7 Signed Data) Verification ... ");\r
329\r
330 if (AuthenticodeVerify ()) {\r
331 Print (L"[Pass]");\r
332 } else {\r
333 Print (L"[Failed]");\r
334 } \r
335\r
336 Print (L"\n");\r
337\r
338 return EFI_SUCCESS;\r
339}\r
340\r
341\r
342/**\r
343 Entry Point of Cryptographic Validation Utility.\r
344\r
345 @param ImageHandle The image handle of the UEFI Application.\r
346 @param SystemTable A pointer to the EFI System Table.\r
347\r
348 @retval EFI_SUCCESS The entry point is executed successfully.\r
349 @retval other Some error occurs when executing this entry point.\r
350\r
351**/\r
352EFI_STATUS\r
353EFIAPI\r
354CryptestMain (\r
355 IN EFI_HANDLE ImageHandle,\r
356 IN EFI_SYSTEM_TABLE *SystemTable\r
357 )\r
358{\r
359 EFI_STATUS Status;\r
360\r
361 Print (L"\nUEFI-OpenSSL Wrapper Cryptosystem Testing: \n");\r
362 Print (L"-------------------------------------------- \n");\r
363\r
364 Status = EFI_SUCCESS;\r
365 Status = ValidateCryptDigest ();\r
366 Status = ValidateCryptHmac ();\r
367 Status = ValidateCryptBlockCipher ();\r
368 Status = ValidateCryptRsa ();\r
369 Status = ValidateAuthenticode ();\r
370\r
371 return Status;\r
372}\r