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