TianoCore EDK2 master
Loading...
Searching...
No Matches
DxeRsa2048Sha256GuidedSectionExtractLib.c
Go to the documentation of this file.
1
12#include <PiDxe.h>
13#include <Protocol/Hash.h>
16#include <Library/DebugLib.h>
20#include <Library/PcdLib.h>
21#include <Guid/WinCertificate.h>
25
29typedef struct {
33
34typedef struct {
38
42CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
43
61EFIAPI
63 IN CONST VOID *InputSection,
64 OUT UINT32 *OutputBufferSize,
65 OUT UINT32 *ScratchBufferSize,
66 OUT UINT16 *SectionAttribute
67 )
68{
69 if (IS_SECTION2 (InputSection)) {
70 //
71 // Check whether the input guid section is recognized.
72 //
73 if (!CompareGuid (
74 &gEfiCertTypeRsa2048Sha256Guid,
75 &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid)
76 ))
77 {
78 return EFI_INVALID_PARAMETER;
79 }
80
81 //
82 // Retrieve the size and attribute of the input section data.
83 //
84 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes;
85 *ScratchBufferSize = 0;
86 *OutputBufferSize = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
87 } else {
88 //
89 // Check whether the input guid section is recognized.
90 //
91 if (!CompareGuid (
92 &gEfiCertTypeRsa2048Sha256Guid,
93 &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid)
94 ))
95 {
96 return EFI_INVALID_PARAMETER;
97 }
98
99 //
100 // Retrieve the size and attribute of the input section data.
101 //
102 *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes;
103 *ScratchBufferSize = 0;
104 *OutputBufferSize = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER);
105 }
106
107 return EFI_SUCCESS;
108}
109
128EFIAPI
130 IN CONST VOID *InputSection,
131 OUT VOID **OutputBuffer,
132 IN VOID *ScratchBuffer OPTIONAL,
133 OUT UINT32 *AuthenticationStatus
134 )
135{
136 EFI_STATUS Status;
137 UINT32 OutputBufferSize;
138 VOID *DummyInterface;
139 EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlockRsa2048Sha256;
140 BOOLEAN CryptoStatus;
141 UINT8 Digest[SHA256_DIGEST_SIZE];
142 UINT8 *PublicKey;
143 UINTN PublicKeyBufferSize;
144 VOID *HashContext;
145 VOID *Rsa;
146
147 HashContext = NULL;
148 Rsa = NULL;
149
150 if (IS_SECTION2 (InputSection)) {
151 //
152 // Check whether the input guid section is recognized.
153 //
154 if (!CompareGuid (
155 &gEfiCertTypeRsa2048Sha256Guid,
156 &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid)
157 ))
158 {
159 return EFI_INVALID_PARAMETER;
160 }
161
162 //
163 // Get the RSA 2048 SHA 256 information.
164 //
165 CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *)InputSection)->CertBlockRsa2048Sha256;
166 OutputBufferSize = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
167 if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
168 PERF_INMODULE_BEGIN ("DxeRsaCopy");
169 CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize);
170 PERF_INMODULE_END ("DxeRsaCopy");
171 } else {
172 *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
173 }
174
175 //
176 // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set
177 //
178 ASSERT ((((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0);
179 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
180 } else {
181 //
182 // Check whether the input guid section is recognized.
183 //
184 if (!CompareGuid (
185 &gEfiCertTypeRsa2048Sha256Guid,
186 &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid)
187 ))
188 {
189 return EFI_INVALID_PARAMETER;
190 }
191
192 //
193 // Get the RSA 2048 SHA 256 information.
194 //
195 CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256;
196 OutputBufferSize = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER);
197 if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
198 PERF_INMODULE_BEGIN ("DxeRsaCopy");
199 CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize);
200 PERF_INMODULE_END ("DxeRsaCopy");
201 } else {
202 *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER);
203 }
204
205 //
206 // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set
207 //
208 ASSERT ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0);
209 *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED;
210 }
211
212 //
213 // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID.
214 //
215 Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface);
216 if (!EFI_ERROR (Status)) {
217 //
218 // If SecurityPolicy Protocol exist, AUTH platform override bit is set.
219 //
220 *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE;
221
222 return EFI_SUCCESS;
223 }
224
225 //
226 // All paths from here return EFI_SUCCESS and result is returned in AuthenticationStatus
227 //
228 Status = EFI_SUCCESS;
229
230 //
231 // Fail if the HashType is not SHA 256
232 //
233 if (!CompareGuid (&gEfiHashAlgorithmSha256Guid, &CertBlockRsa2048Sha256->HashType)) {
234 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: HASH type of section is not supported\n"));
235 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
236 goto Done;
237 }
238
239 //
240 // Allocate hash context buffer required for SHA 256
241 //
242 HashContext = AllocatePool (Sha256GetContextSize ());
243 if (HashContext == NULL) {
244 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Can not allocate hash context\n"));
245 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
246 goto Done;
247 }
248
249 //
250 // Hash public key from data payload with SHA256.
251 //
252 ZeroMem (Digest, SHA256_DIGEST_SIZE);
253 CryptoStatus = Sha256Init (HashContext);
254 if (!CryptoStatus) {
255 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n"));
256 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
257 goto Done;
258 }
259
260 CryptoStatus = Sha256Update (HashContext, &CertBlockRsa2048Sha256->PublicKey, sizeof (CertBlockRsa2048Sha256->PublicKey));
261 if (!CryptoStatus) {
262 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n"));
263 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
264 goto Done;
265 }
266
267 CryptoStatus = Sha256Final (HashContext, Digest);
268 if (!CryptoStatus) {
269 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n"));
270 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
271 goto Done;
272 }
273
274 //
275 // Fail if the PublicKey is not one of the public keys in PcdRsa2048Sha256PublicKeyBuffer
276 //
277 PublicKey = (UINT8 *)PcdGetPtr (PcdRsa2048Sha256PublicKeyBuffer);
278 DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer = %p\n", PublicKey));
279 ASSERT (PublicKey != NULL);
280 DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Token = %08x\n", PcdToken (PcdRsa2048Sha256PublicKeyBuffer)));
281 PublicKeyBufferSize = PcdGetSize (PcdRsa2048Sha256PublicKeyBuffer);
282 DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Size = %08x\n", PublicKeyBufferSize));
283 ASSERT ((PublicKeyBufferSize % SHA256_DIGEST_SIZE) == 0);
284 CryptoStatus = FALSE;
285 while (PublicKeyBufferSize != 0) {
286 if (CompareMem (Digest, PublicKey, SHA256_DIGEST_SIZE) == 0) {
287 CryptoStatus = TRUE;
288 break;
289 }
290
291 PublicKey = PublicKey + SHA256_DIGEST_SIZE;
292 PublicKeyBufferSize = PublicKeyBufferSize - SHA256_DIGEST_SIZE;
293 }
294
295 if (!CryptoStatus) {
296 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Public key in section is not supported\n"));
297 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
298 goto Done;
299 }
300
301 //
302 // Generate & Initialize RSA Context.
303 //
304 Rsa = RsaNew ();
305 if (Rsa == NULL) {
306 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaNew() failed\n"));
307 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
308 goto Done;
309 }
310
311 //
312 // Set RSA Key Components.
313 // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
314 //
315 CryptoStatus = RsaSetKey (Rsa, RsaKeyN, CertBlockRsa2048Sha256->PublicKey, sizeof (CertBlockRsa2048Sha256->PublicKey));
316 if (!CryptoStatus) {
317 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyN) failed\n"));
318 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
319 goto Done;
320 }
321
322 CryptoStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
323 if (!CryptoStatus) {
324 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyE) failed\n"));
325 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
326 goto Done;
327 }
328
329 //
330 // Hash data payload with SHA256.
331 //
332 ZeroMem (Digest, SHA256_DIGEST_SIZE);
333 CryptoStatus = Sha256Init (HashContext);
334 if (!CryptoStatus) {
335 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n"));
336 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
337 goto Done;
338 }
339
340 PERF_INMODULE_BEGIN ("DxeRsaShaData");
341 CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize);
342 PERF_INMODULE_END ("DxeRsaShaData");
343 if (!CryptoStatus) {
344 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n"));
345 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
346 goto Done;
347 }
348
349 CryptoStatus = Sha256Final (HashContext, Digest);
350 if (!CryptoStatus) {
351 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n"));
352 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
353 goto Done;
354 }
355
356 //
357 // Verify the RSA 2048 SHA 256 signature.
358 //
359 PERF_INMODULE_BEGIN ("DxeRsaVerify");
360 CryptoStatus = RsaPkcs1Verify (
361 Rsa,
362 Digest,
364 CertBlockRsa2048Sha256->Signature,
365 sizeof (CertBlockRsa2048Sha256->Signature)
366 );
367 PERF_INMODULE_END ("DxeRsaVerify");
368 if (!CryptoStatus) {
369 //
370 // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set.
371 //
372 DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaPkcs1Verify() failed\n"));
373 *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
374 }
375
376Done:
377 //
378 // Free allocated resources used to perform RSA 2048 SHA 256 signature verification
379 //
380 if (Rsa != NULL) {
381 RsaFree (Rsa);
382 }
383
384 if (HashContext != NULL) {
385 FreePool (HashContext);
386 }
387
388 DEBUG ((DEBUG_VERBOSE, "DxeRsa2048Sha256: Status = %r AuthenticationStatus = %08x\n", Status, *AuthenticationStatus));
389
390 return Status;
391}
392
403EFIAPI
405 IN EFI_HANDLE ImageHandle,
406 IN EFI_SYSTEM_TABLE *SystemTable
407 )
408{
410 &gEfiCertTypeRsa2048Sha256Guid,
413 );
414}
UINT64 UINTN
@ RsaKeyN
RSA public Modulus (N)
Definition: BaseCryptLib.h:75
@ RsaKeyE
RSA Public exponent (e)
Definition: BaseCryptLib.h:76
UINTN EFIAPI Sha256GetContextSize(VOID)
Definition: CryptSha256.c:20
VOID *EFIAPI RsaNew(VOID)
Definition: CryptRsaBasic.c:30
BOOLEAN EFIAPI Sha256Init(OUT VOID *Sha256Context)
Definition: CryptSha256.c:44
BOOLEAN EFIAPI Sha256Final(IN OUT VOID *Sha256Context, OUT UINT8 *HashValue)
Definition: CryptSha256.c:161
#define SHA256_DIGEST_SIZE
Definition: BaseCryptLib.h:44
BOOLEAN EFIAPI RsaSetKey(IN OUT VOID *RsaContext, IN RSA_KEY_TAG KeyTag, IN CONST UINT8 *BigNumber, IN UINTN BnSize)
Definition: CryptRsaBasic.c:82
BOOLEAN EFIAPI Sha256Update(IN OUT VOID *Sha256Context, IN CONST VOID *Data, IN UINTN DataSize)
Definition: CryptSha256.c:113
VOID EFIAPI RsaFree(IN VOID *RsaContext)
Definition: CryptRsaBasic.c:48
BOOLEAN EFIAPI RsaPkcs1Verify(IN VOID *RsaContext, IN CONST UINT8 *MessageHash, IN UINTN HashSize, IN CONST UINT8 *Signature, IN UINTN SigSize)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI DxeRsa2048Sha256GuidedSectionExtractLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI Rsa2048Sha256GuidedSectionGetInfo(IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute)
EFI_STATUS EFIAPI Rsa2048Sha256GuidedSectionHandler(IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer OPTIONAL, OUT UINT32 *AuthenticationStatus)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGetSize(TokenName)
Definition: PcdLib.h:440
#define PcdToken(TokenName)
Definition: PcdLib.h:36
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
#define PERF_INMODULE_BEGIN(MeasurementString)
#define PERF_INMODULE_END(MeasurementString)
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED
#define SECTION_SIZE(SectionHeaderPtr)
#define EFI_AUTH_STATUS_PLATFORM_OVERRIDE
Definition: PiMultiPhase.h:91
RETURN_STATUS EFIAPI ExtractGuidedSectionRegisterHandlers(IN CONST GUID *SectionGuid, IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER GetInfoHandler, IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER DecodeHandler)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_CERT_BLOCK_RSA_2048_SHA256 CertBlockRsa2048Sha256
RSA 2048-bit Signature.
EFI_GUID_DEFINED_SECTION2 GuidedSectionHeader
EFI guided section header.
EFI_GUID_DEFINED_SECTION GuidedSectionHeader
EFI guided section header.
EFI_CERT_BLOCK_RSA_2048_SHA256 CertBlockRsa2048Sha256
RSA 2048-bit Signature.