]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/RuntimeDxeIpfCryptLib.c
1. Correct the counter-based hash algorithm according to UEFI spec.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLibRuntimeCryptProtocol / RuntimeDxeIpfCryptLib.c
CommitLineData
97f98500
HT
1/** @file\r
2 Implementation of The runtime cryptographic library instance (for IPF).\r
3\r
16d2c32c 4Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
97f98500
HT
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\r
17#include <Library/BaseLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Library/UefiRuntimeLib.h>\r
21\r
22#include <Protocol/RuntimeCrypt.h>\r
23\r
24#include <Guid/EventGroup.h>\r
25\r
26EFI_RUNTIME_CRYPT_PROTOCOL *mCryptProtocol = NULL;\r
27EFI_EVENT mIpfCryptLibVirtualNotifyEvent;\r
28\r
29/**\r
30 Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which converts\r
31 pointer to new virtual address.\r
32\r
33 @param Event Event whose notification function is being invoked.\r
34 @param Context Pointer to the notification function's context\r
35\r
36**/\r
37VOID\r
38EFIAPI\r
39IpfCryptLibAddressChangeEvent (\r
40 IN EFI_EVENT Event,\r
41 IN VOID *Context\r
42 )\r
43{\r
44 //\r
45 // Convert Address of Runtime Crypto Protocol.\r
46 //\r
47 EfiConvertPointer (0x0, (VOID **) &mCryptProtocol);\r
48}\r
49\r
50/**\r
51 Constructor of IPF Crypto Library Instance.\r
52 This function locates the Runtime Crypt Protocol and register notification\r
53 function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
54\r
55 @param ImageHandle The firmware allocated handle for the EFI image.\r
56 @param SystemTable A pointer to the EFI System Table.\r
57\r
58 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
59\r
60**/\r
61EFI_STATUS\r
62EFIAPI\r
63RuntimeDxeIpfCryptLibConstructor (\r
64 IN EFI_HANDLE ImageHandle,\r
65 IN EFI_SYSTEM_TABLE *SystemTable\r
66 )\r
67{\r
68 EFI_STATUS Status;\r
69\r
70 //\r
71 // Locate Runtime Crypt Protocol Instance\r
72 //\r
73 Status = gBS->LocateProtocol (\r
74 &gEfiRuntimeCryptProtocolGuid,\r
75 NULL,\r
76 (VOID**) &mCryptProtocol\r
77 );\r
78 ASSERT_EFI_ERROR (Status);\r
79 ASSERT (mCryptProtocol != NULL);\r
80\r
81 //\r
82 // Register SetVirtualAddressMap () notify function\r
83 //\r
84 Status = gBS->CreateEventEx (\r
85 EVT_NOTIFY_SIGNAL,\r
86 TPL_NOTIFY,\r
87 IpfCryptLibAddressChangeEvent,\r
88 NULL,\r
89 &gEfiEventVirtualAddressChangeGuid,\r
90 &mIpfCryptLibVirtualNotifyEvent\r
91 );\r
92 ASSERT_EFI_ERROR (Status);\r
93\r
94 return Status;\r
95}\r
96\r
97/**\r
98 Destructor of IPF Crypto Library Instance.\r
99\r
100 @param ImageHandle The firmware allocated handle for the EFI image.\r
101 @param SystemTable A pointer to the EFI System Table.\r
102\r
103 @retval EFI_SUCCESS The destructor completed successfully.\r
104 @retval Other value The destructor did not complete successfully.\r
105\r
106**/\r
107EFI_STATUS\r
108EFIAPI\r
109RuntimeDxeIpfCryptLibDestructor (\r
110 IN EFI_HANDLE ImageHandle,\r
111 IN EFI_SYSTEM_TABLE *SystemTable\r
112 )\r
113{\r
114 EFI_STATUS Status;\r
115\r
116 //\r
117 // Close the Set Virtual Address Map event\r
118 //\r
119 Status = gBS->CloseEvent (mIpfCryptLibVirtualNotifyEvent);\r
120 ASSERT_EFI_ERROR (Status);\r
121\r
122 return Status;\r
123}\r
124\r
125/**\r
126 Check whether crypto service provided by Runtime Crypt protocol is ready to use.\r
127\r
128 Crypto service is available if the call is in physical mode prior to\r
129 SetVirtualAddressMap() or virtual mode after SetVirtualAddressMap(). If either\r
130 of these two conditions are met, this routine will return TRUE; if neither of\r
131 these conditions are met, this routine will return FALSE.\r
132\r
133 @retval TRUE The Crypto service is ready to use.\r
134 @retval FALSE The Crypto service is not available.\r
135\r
136**/\r
137BOOLEAN\r
138EFIAPI\r
139InternalIsCryptServiveAvailable (\r
140 VOID\r
141 )\r
142{\r
143 INT64 CpuMode;\r
144 BOOLEAN GoneVirtual;\r
145\r
146 CpuMode = AsmCpuVirtual();\r
147 if (CpuMode < 0) {\r
148 //\r
149 // CPU is in mixed mode, return failing the operation gracefully.\r
150 //\r
151 return FALSE;\r
152 }\r
153\r
154 GoneVirtual = EfiGoneVirtual();\r
155\r
156 if ((CpuMode > 0) && !GoneVirtual) {\r
157 //\r
158 // CPU is in virtual mode, but SetVirtualAddressMap() has not been called,\r
159 // so return failing the operation gracefully.\r
160 //\r
161 return FALSE;\r
162 }\r
163\r
164 if ((CpuMode == 0) && GoneVirtual) {\r
165 //\r
166 // CPU is in physical mode, but SetVirtualAddressMap() has been called,\r
167 // so return failing the operation gracefully.\r
168 //\r
169 return FALSE;\r
170 }\r
171\r
172 return TRUE;\r
173}\r
174\r
175/**\r
176 Retrieves the size, in bytes, of the context buffer required for SHA-256 operations.\r
177\r
178 @return The size, in bytes, of the context buffer required for SHA-256 operations.\r
179\r
180**/\r
181UINTN\r
182EFIAPI\r
183Sha256GetContextSize (\r
184 VOID\r
185 )\r
186{\r
187 if (!InternalIsCryptServiveAvailable ()) {\r
188 return 0;\r
189 }\r
190\r
191 return mCryptProtocol->Sha256GetContextSize ();\r
192}\r
193\r
194/**\r
195 Initializes user-supplied memory pointed by Sha256Context as SHA-256 hash context for\r
196 subsequent use.\r
197\r
16d2c32c 198 If Sha256Context is NULL, then return FALSE.\r
97f98500
HT
199\r
200 @param[in, out] Sha256Context Pointer to SHA-256 Context being initialized.\r
201\r
202 @retval TRUE SHA-256 context initialization succeeded.\r
203 @retval FALSE SHA-256 context initialization failed.\r
204\r
205**/\r
206BOOLEAN\r
207EFIAPI\r
208Sha256Init (\r
209 IN OUT VOID *Sha256Context\r
210 )\r
211{\r
212 if (!InternalIsCryptServiveAvailable ()) {\r
213 return FALSE;\r
214 }\r
215\r
216 return mCryptProtocol->Sha256Init (Sha256Context);\r
217}\r
218\r
219\r
532616bb 220/**\r
221 Makes a copy of an existing SHA-256 context.\r
222\r
223 Return FALSE to indicate this interface is not supported.\r
224\r
225 @param[in] Sha256Context Pointer to SHA-256 context being copied.\r
226 @param[out] NewSha256Context Pointer to new SHA-256 context.\r
227\r
228 @retval FALSE This interface is not supported.\r
229\r
230**/\r
231BOOLEAN\r
232EFIAPI\r
233Sha256Duplicate (\r
234 IN CONST VOID *Sha256Context,\r
235 OUT VOID *NewSha256Context\r
236 )\r
237{\r
238 ASSERT (FALSE);\r
239 return FALSE;\r
240}\r
241\r
242\r
97f98500
HT
243/**\r
244 Performs SHA-256 digest on a data buffer of the specified length. This function can\r
245 be called multiple times to compute the digest of long or discontinuous data streams.\r
246\r
16d2c32c 247 If Sha256Context is NULL, then return FALSE.\r
97f98500
HT
248\r
249 @param[in, out] Sha256Context Pointer to the SHA-256 context.\r
250 @param[in] Data Pointer to the buffer containing the data to be hashed.\r
251 @param[in] DataLength Length of Data buffer in bytes.\r
252\r
253 @retval TRUE SHA-256 data digest succeeded.\r
254 @retval FALSE Invalid SHA-256 context. After Sha256Final function has been called, the\r
255 SHA-256 context cannot be reused.\r
256\r
257**/\r
258BOOLEAN\r
259EFIAPI\r
260Sha256Update (\r
261 IN OUT VOID *Sha256Context,\r
262 IN CONST VOID *Data,\r
263 IN UINTN DataLength\r
264 )\r
265{\r
266 if (!InternalIsCryptServiveAvailable ()) {\r
267 return FALSE;\r
268 }\r
269\r
270 return mCryptProtocol->Sha256Update (Sha256Context, Data, DataLength);\r
271}\r
272\r
273/**\r
274 Completes SHA-256 hash computation and retrieves the digest value into the specified\r
275 memory. After this function has been called, the SHA-256 context cannot be used again.\r
276\r
16d2c32c 277 If Sha256Context is NULL, then return FALSE.\r
278 If HashValue is NULL, then return FALSE.\r
97f98500
HT
279\r
280 @param[in, out] Sha256Context Pointer to SHA-256 context\r
281 @param[out] HashValue Pointer to a buffer that receives the SHA-256 digest\r
282 value (32 bytes).\r
283\r
284 @retval TRUE SHA-256 digest computation succeeded.\r
285 @retval FALSE SHA-256 digest computation failed.\r
286\r
287**/\r
288BOOLEAN\r
289EFIAPI\r
290Sha256Final (\r
291 IN OUT VOID *Sha256Context,\r
292 OUT UINT8 *HashValue\r
293 )\r
294{\r
295 if (!InternalIsCryptServiveAvailable ()) {\r
296 return FALSE;\r
297 }\r
298\r
299 return mCryptProtocol->Sha256Final (Sha256Context, HashValue);\r
300}\r
301\r
302/**\r
532616bb 303 Allocates and initializes one RSA context for subsequent use.\r
97f98500 304\r
532616bb 305 @return Pointer to the RSA context that has been initialized.\r
97f98500
HT
306 If the allocations fails, RsaNew() returns NULL.\r
307\r
308**/\r
309VOID *\r
310EFIAPI\r
311RsaNew (\r
312 VOID\r
313 )\r
314{\r
315 if (!InternalIsCryptServiveAvailable ()) {\r
316 return FALSE;\r
317 }\r
318\r
319 return mCryptProtocol->RsaNew ();\r
320}\r
321\r
322/**\r
532616bb 323 Release the specified RSA context.\r
97f98500
HT
324\r
325 @param[in] RsaContext Pointer to the RSA context to be released.\r
326\r
327**/\r
328VOID\r
329EFIAPI\r
330RsaFree (\r
331 IN VOID *RsaContext\r
332 )\r
333{\r
334 if (!InternalIsCryptServiveAvailable ()) {\r
335 return;\r
336 }\r
337\r
338 mCryptProtocol->RsaFree (RsaContext);\r
339}\r
340\r
341/**\r
532616bb 342 Sets the tag-designated key component into the established RSA context.\r
343\r
344 This function sets the tag-designated RSA key component into the established\r
345 RSA context from the user-specified non-negative integer (octet string format\r
346 represented in RSA PKCS#1).\r
347 If BigNumber is NULL, then the specified key componenet in RSA context is cleared.\r
97f98500 348\r
16d2c32c 349 If RsaContext is NULL, then return FALSE.\r
97f98500
HT
350\r
351 @param[in, out] RsaContext Pointer to RSA context being set.\r
352 @param[in] KeyTag Tag of RSA key component being set.\r
353 @param[in] BigNumber Pointer to octet integer buffer.\r
532616bb 354 If NULL, then the specified key componenet in RSA\r
355 context is cleared.\r
356 @param[in] BnSize Size of big number buffer in bytes.\r
357 If BigNumber is NULL, then it is ignored.\r
97f98500 358\r
532616bb 359 @retval TRUE RSA key component was set successfully.\r
360 @retval FALSE Invalid RSA key component tag.\r
97f98500
HT
361\r
362**/\r
363BOOLEAN\r
364EFIAPI\r
365RsaSetKey (\r
532616bb 366 IN OUT VOID *RsaContext,\r
367 IN RSA_KEY_TAG KeyTag,\r
368 IN CONST UINT8 *BigNumber,\r
369 IN UINTN BnSize\r
97f98500
HT
370 )\r
371{\r
372 if (!InternalIsCryptServiveAvailable ()) {\r
373 return FALSE;\r
374 }\r
375\r
532616bb 376 return mCryptProtocol->RsaSetKey (RsaContext, KeyTag, BigNumber, BnSize);\r
97f98500
HT
377}\r
378\r
379/**\r
380 Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in\r
381 RSA PKCS#1.\r
382\r
16d2c32c 383 If RsaContext is NULL, then return FALSE.\r
384 If MessageHash is NULL, then return FALSE.\r
385 If Signature is NULL, then return FALSE.\r
532616bb 386 If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE.\r
97f98500
HT
387\r
388 @param[in] RsaContext Pointer to RSA context for signature verification.\r
389 @param[in] MessageHash Pointer to octet message hash to be checked.\r
532616bb 390 @param[in] HashSize Size of the message hash in bytes.\r
97f98500 391 @param[in] Signature Pointer to RSA PKCS1-v1_5 signature to be verified.\r
532616bb 392 @param[in] SigSize Size of signature in bytes.\r
97f98500 393\r
532616bb 394 @retval TRUE Valid signature encoded in PKCS1-v1_5.\r
395 @retval FALSE Invalid signature or invalid RSA context.\r
97f98500
HT
396\r
397**/\r
398BOOLEAN\r
399EFIAPI\r
400RsaPkcs1Verify (\r
401 IN VOID *RsaContext,\r
402 IN CONST UINT8 *MessageHash,\r
532616bb 403 IN UINTN HashSize,\r
97f98500 404 IN UINT8 *Signature,\r
532616bb 405 IN UINTN SigSize\r
97f98500
HT
406 )\r
407{\r
408 if (!InternalIsCryptServiveAvailable ()) {\r
409 return FALSE;\r
410 }\r
411\r
412 return mCryptProtocol->RsaPkcs1Verify (\r
413 RsaContext,\r
414 MessageHash,\r
532616bb 415 HashSize,\r
97f98500 416 Signature,\r
532616bb 417 SigSize\r
97f98500
HT
418 );\r
419}\r