TianoCore EDK2 master
Loading...
Searching...
No Matches
FmpAuthenticationLibRsa2048Sha256.c
Go to the documentation of this file.
1
18#include <Uefi.h>
19
22#include <Guid/WinCertificate.h>
23
24#include <Library/BaseLib.h>
26#include <Library/DebugLib.h>
30#include <Library/PcdLib.h>
33
37STATIC CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
38
62RETURN_STATUS
65 IN UINTN ImageSize,
66 IN CONST UINT8 *PublicKeyData,
67 IN UINTN PublicKeyDataLength
68 )
69{
70 RETURN_STATUS Status;
71 EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlockRsa2048Sha256;
72 BOOLEAN CryptoStatus;
73 UINT8 Digest[SHA256_DIGEST_SIZE];
74 UINT8 *PublicKey;
75 UINTN PublicKeyBufferSize;
76 VOID *HashContext;
77 VOID *Rsa;
78
79 DEBUG ((DEBUG_INFO, "FmpAuthenticatedHandlerRsa2048Sha256 - Image: 0x%08x - 0x%08x\n", (UINTN)Image, (UINTN)ImageSize));
80
81 if (Image->AuthInfo.Hdr.dwLength != OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256)) {
82 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256 - dwLength: 0x%04x, dwLength - 0x%04x\n", (UINTN)Image->AuthInfo.Hdr.dwLength, (UINTN)OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256)));
84 }
85
86 CertBlockRsa2048Sha256 = (EFI_CERT_BLOCK_RSA_2048_SHA256 *)Image->AuthInfo.CertData;
87 if (!CompareGuid (&CertBlockRsa2048Sha256->HashType, &gEfiHashAlgorithmSha256Guid)) {
88 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256 - HashType: %g, expect - %g\n", &CertBlockRsa2048Sha256->HashType, &gEfiHashAlgorithmSha256Guid));
90 }
91
92 HashContext = NULL;
93 Rsa = NULL;
94
95 //
96 // Allocate hash context buffer required for SHA 256
97 //
98 HashContext = AllocatePool (Sha256GetContextSize ());
99 if (HashContext == NULL) {
100 CryptoStatus = FALSE;
101 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Can not allocate hash context\n"));
103 goto Done;
104 }
105
106 //
107 // Hash public key from data payload with SHA256.
108 //
109 ZeroMem (Digest, SHA256_DIGEST_SIZE);
110 CryptoStatus = Sha256Init (HashContext);
111 if (!CryptoStatus) {
112 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Init() failed\n"));
114 goto Done;
115 }
116
117 CryptoStatus = Sha256Update (HashContext, &CertBlockRsa2048Sha256->PublicKey, sizeof (CertBlockRsa2048Sha256->PublicKey));
118 if (!CryptoStatus) {
119 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Update() failed\n"));
121 goto Done;
122 }
123
124 CryptoStatus = Sha256Final (HashContext, Digest);
125 if (!CryptoStatus) {
126 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Final() failed\n"));
128 goto Done;
129 }
130
131 //
132 // Fail if the PublicKey is not one of the public keys in the input PublicKeyData.
133 //
134 PublicKey = (VOID *)PublicKeyData;
135 PublicKeyBufferSize = PublicKeyDataLength;
136 CryptoStatus = FALSE;
137 while (PublicKeyBufferSize != 0) {
138 if (CompareMem (Digest, PublicKey, SHA256_DIGEST_SIZE) == 0) {
139 CryptoStatus = TRUE;
140 break;
141 }
142
143 PublicKey = PublicKey + SHA256_DIGEST_SIZE;
144 PublicKeyBufferSize = PublicKeyBufferSize - SHA256_DIGEST_SIZE;
145 }
146
147 if (!CryptoStatus) {
148 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Public key in section is not supported\n"));
150 goto Done;
151 }
152
153 //
154 // Generate & Initialize RSA Context.
155 //
156 Rsa = RsaNew ();
157 if (Rsa == NULL) {
158 CryptoStatus = FALSE;
159 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: RsaNew() failed\n"));
161 goto Done;
162 }
163
164 //
165 // Set RSA Key Components.
166 // NOTE: Only N and E are needed to be set as RSA public key for signature verification.
167 //
168 CryptoStatus = RsaSetKey (Rsa, RsaKeyN, CertBlockRsa2048Sha256->PublicKey, sizeof (CertBlockRsa2048Sha256->PublicKey));
169 if (!CryptoStatus) {
170 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: RsaSetKey(RsaKeyN) failed\n"));
172 goto Done;
173 }
174
175 CryptoStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE));
176 if (!CryptoStatus) {
177 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: RsaSetKey(RsaKeyE) failed\n"));
179 goto Done;
180 }
181
182 //
183 // Hash data payload with SHA256.
184 //
185 ZeroMem (Digest, SHA256_DIGEST_SIZE);
186 CryptoStatus = Sha256Init (HashContext);
187 if (!CryptoStatus) {
188 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Init() failed\n"));
190 goto Done;
191 }
192
193 // It is a signature across the variable data and the Monotonic Count value.
194 CryptoStatus = Sha256Update (
195 HashContext,
196 (UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength,
197 ImageSize - sizeof (Image->MonotonicCount) - Image->AuthInfo.Hdr.dwLength
198 );
199 if (!CryptoStatus) {
200 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Update() failed\n"));
202 goto Done;
203 }
204
205 CryptoStatus = Sha256Update (
206 HashContext,
207 (UINT8 *)&Image->MonotonicCount,
208 sizeof (Image->MonotonicCount)
209 );
210 if (!CryptoStatus) {
211 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Update() failed\n"));
213 goto Done;
214 }
215
216 CryptoStatus = Sha256Final (HashContext, Digest);
217 if (!CryptoStatus) {
218 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: Sha256Final() failed\n"));
220 goto Done;
221 }
222
223 //
224 // Verify the RSA 2048 SHA 256 signature.
225 //
226 CryptoStatus = RsaPkcs1Verify (
227 Rsa,
228 Digest,
230 CertBlockRsa2048Sha256->Signature,
231 sizeof (CertBlockRsa2048Sha256->Signature)
232 );
233 if (!CryptoStatus) {
234 //
235 // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set.
236 //
237 DEBUG ((DEBUG_ERROR, "FmpAuthenticatedHandlerRsa2048Sha256: RsaPkcs1Verify() failed\n"));
239 goto Done;
240 }
241
242 DEBUG ((DEBUG_INFO, "FmpAuthenticatedHandlerRsa2048Sha256: PASS verification\n"));
243
244 Status = RETURN_SUCCESS;
245
246Done:
247 //
248 // Free allocated resources used to perform RSA 2048 SHA 256 signature verification
249 //
250 if (Rsa != NULL) {
251 RsaFree (Rsa);
252 }
253
254 if (HashContext != NULL) {
255 FreePool (HashContext);
256 }
257
258 return Status;
259}
260
296RETURN_STATUS
297EFIAPI
300 IN UINTN ImageSize,
301 IN CONST UINT8 *PublicKeyData,
302 IN UINTN PublicKeyDataLength
303 )
304{
305 GUID *CertType;
306 EFI_STATUS Status;
307
308 if ((Image == NULL) || (ImageSize == 0)) {
309 return RETURN_UNSUPPORTED;
310 }
311
312 if ((PublicKeyDataLength % SHA256_DIGEST_SIZE) != 0) {
313 DEBUG ((DEBUG_ERROR, "PublicKeyDataLength is not multiple SHA256 size\n"));
314 return RETURN_UNSUPPORTED;
315 }
316
317 if (ImageSize < sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION)) {
318 DEBUG ((DEBUG_ERROR, "AuthenticateFmpImage - ImageSize too small\n"));
320 }
321
322 if (Image->AuthInfo.Hdr.dwLength <= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) {
323 DEBUG ((DEBUG_ERROR, "AuthenticateFmpImage - dwLength too small\n"));
325 }
326
327 if ((UINTN)Image->AuthInfo.Hdr.dwLength > MAX_UINTN - sizeof (UINT64)) {
328 DEBUG ((DEBUG_ERROR, "AuthenticateFmpImage - dwLength too big\n"));
330 }
331
332 if (ImageSize <= sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) {
333 DEBUG ((DEBUG_ERROR, "AuthenticateFmpImage - ImageSize too small\n"));
335 }
336
337 if (Image->AuthInfo.Hdr.wRevision != 0x0200) {
338 DEBUG ((DEBUG_ERROR, "AuthenticateFmpImage - wRevision: 0x%02x, expect - 0x%02x\n", (UINTN)Image->AuthInfo.Hdr.wRevision, (UINTN)0x0200));
340 }
341
342 if (Image->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) {
343 DEBUG ((DEBUG_ERROR, "AuthenticateFmpImage - wCertificateType: 0x%02x, expect - 0x%02x\n", (UINTN)Image->AuthInfo.Hdr.wCertificateType, (UINTN)WIN_CERT_TYPE_EFI_GUID));
345 }
346
347 CertType = &Image->AuthInfo.CertType;
348 DEBUG ((DEBUG_INFO, "AuthenticateFmpImage - CertType: %g\n", CertType));
349
350 if (CompareGuid (&gEfiCertTypeRsa2048Sha256Guid, CertType)) {
351 //
352 // Call the match handler to extract raw data for the input section data.
353 //
355 Image,
356 ImageSize,
357 PublicKeyData,
358 PublicKeyDataLength
359 );
360 return Status;
361 }
362
363 //
364 // Not found, the input guided section is not supported.
365 //
366 return RETURN_UNSUPPORTED;
367}
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)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
RETURN_STATUS EFIAPI AuthenticateFmpImage(IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, IN UINTN ImageSize, IN CONST UINT8 *PublicKeyData, IN UINTN PublicKeyDataLength)
RETURN_STATUS FmpAuthenticatedHandlerRsa2048Sha256(IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image, IN UINTN ImageSize, IN CONST UINT8 *PublicKeyData, IN UINTN PublicKeyDataLength)
STATIC CONST UINT8 mRsaE[]
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define RETURN_OUT_OF_RESOURCES
Definition: Base.h:1114
#define RETURN_SECURITY_VIOLATION
Definition: Base.h:1203
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
Definition: Base.h:213