Changeset 58459 in vbox for trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated
- Timestamp:
- Oct 28, 2015 8:17:18 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/Firmware
- Files:
-
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/Firmware
-
Property svn:mergeinfo
set to (toggle deleted branches)
/vendor/edk2/current 103735-103757
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/AuthService.c
r48674 r58459 3 3 service in UEFI2.2. 4 4 5 Copyright (c) 2009 - 201 1, Intel Corporation. All rights reserved.<BR>5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 6 This program and the accompanying materials 7 7 are licensed and made available under the terms and conditions of the BSD License … … 48 48 VARIABLE_HEADER VariableHeader; 49 49 BOOLEAN Valid; 50 51 ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER)); 50 52 51 53 mVariableModuleGlobal->AuthenticatedVariableGuid[Physical] = &gEfiAuthenticatedVariableGuid; … … 485 487 486 488 OldPkList = NULL; 489 ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER)); 487 490 488 491 if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { … … 624 627 625 628 KekList = NULL; 629 ZeroMem (&VariableHeader, sizeof (VARIABLE_HEADER)); 626 630 627 631 if (mPlatformMode == USER_MODE) { -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/EsalVariableDxeSal.inf
r48674 r58459 1 1 ## @file 2 # Component description file for Extended SAL authentication variable 3 # service module. 2 # Provides authenticated variable service for IPF platform 4 3 # 5 # Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> 4 # This module installs variable arch protocol and variable write arch protocol to provide 5 # four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo. 6 # 7 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 8 # This program and the accompanying materials 7 9 # are licensed and made available under the terms and conditions of the BSD License … … 16 18 INF_VERSION = 0x00010005 17 19 BASE_NAME = EsalVariableDxeSal 20 MODULE_UNI_FILE = EsalVariableDxeSal.uni 18 21 FILE_GUID = 14610837-4E97-4427-96E0-21D9B2956996 19 22 MODULE_TYPE = DXE_SAL_DRIVER … … 61 64 62 65 [Protocols] 63 gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_CONSUMED64 gEfiFaultTolerantWriteProtocolGuid # PROTOCOL SOMETIMES_CONSUMED66 gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES 67 gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES 65 68 66 69 [Guids] 70 ## SOMETIMES_CONSUMES ## Variable:L"PK" 71 ## CONSUMES ## Variable:L"SetupMode" 72 ## PRODUCES ## Variable:L"SetupMode" 73 ## CONSUMES ## Variable:L"SignatureSupport" 74 ## PRODUCES ## Variable:L"SignatureSupport" 67 75 gEfiGlobalVariableGuid 76 77 ## PRODUCES ## GUID # Variable store header 78 ## CONSUMES ## GUID # Variable store header 79 ## SOMETIMES_CONSUMES ## HOB 80 ## SOMETIMES_PRODUCES ## SystemTable 68 81 gEfiAuthenticatedVariableGuid 69 gEfiEventVirtualAddressChangeGuid 70 gEfiCertRsa2048Sha256Guid 82 83 gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event 84 gEfiCertRsa2048Sha256Guid ## CONSUMES ## GUID # Unique ID for the format of the CertType. 85 86 ## SOMETIMES_CONSUMES ## Variable:L"DB" 87 ## SOMETIMES_CONSUMES ## Variable:L"DBX" 71 88 gEfiImageSecurityDatabaseGuid 72 89 73 90 [Pcd.common] 74 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize 75 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase 76 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize 77 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize 78 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize 79 gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize 80 91 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES 92 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES 93 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES 94 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES 95 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES 96 gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES 97 81 98 [FeaturePcd.common] 82 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics 99 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. 83 100 84 101 [Depex] 85 gEfiExtendedSalFvBlockServicesProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid 86 102 gEfiExtendedSalFvBlockServicesProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid 103 104 [UserExtensions.TianoCore."ExtraFiles"] 105 EsalVariableDxeSalExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/Variable.c
r48674 r58459 2 2 The implementation of Extended SAL variable services. 3 3 4 Copyright (c) 2009 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 2592 2592 } 2593 2593 2594 2595 if ((UINTN)(~0) - PayloadSize < StrSize(VariableName)){ 2596 // 2597 // Prevent whole variable size overflow 2598 // 2599 return EFI_INVALID_PARAMETER; 2600 } 2601 2594 2602 VariableGlobal = &Global->VariableGlobal[VirtualMode]; 2595 2603 Instance = Global->FvbInstance; … … 2600 2608 // in bytes plus the DataSize is limited to maximum size of PcdGet32(PcdMaxHardwareErrorVariableSize) bytes. 2601 2609 // 2602 if ((PayloadSize > PcdGet32(PcdMaxHardwareErrorVariableSize)) || 2603 (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxHardwareErrorVariableSize))) { 2610 if (StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) { 2604 2611 return EFI_INVALID_PARAMETER; 2605 2612 } … … 2617 2624 // Unicode Null in bytes plus the DataSize is limited to maximum size of PcdGet32(PcdMaxVariableSize) bytes. 2618 2625 // 2619 if ((PayloadSize > PcdGet32(PcdMaxVariableSize)) || 2620 (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxVariableSize))) { 2626 if (StrSize (VariableName) + PayloadSize > PcdGet32(PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) { 2621 2627 return EFI_INVALID_PARAMETER; 2622 2628 } … … 3239 3245 } else { 3240 3246 Status = EFI_VOLUME_CORRUPTED; 3241 DEBUG((EFI_D_ INFO, "Variable Store header is corrupted\n"));3247 DEBUG((EFI_D_ERROR, "Variable Store header is corrupted\n")); 3242 3248 } 3243 3249 -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/Pei/Variable.c
r48674 r58459 4 4 storage space. 5 5 6 Copyright (c) 2009 - 201 1, Intel Corporation. All rights reserved.<BR>6 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 7 7 This program and the accompanying materials 8 8 are licensed and made available under the terms and conditions of the BSD License … … 173 173 ) 174 174 { 175 176 175 return (CHAR16 *) (Variable + 1); 177 176 } … … 181 180 This code gets the pointer to the variable data. 182 181 183 @param Variable Pointer to the Variable Header. 182 @param Variable Pointer to the Variable Header. 183 @param VariableHeader Pointer to the Variable Header that has consecutive content. 184 184 185 185 @return A UINT8* pointer to Variable Data. … … 188 188 UINT8 * 189 189 GetVariableDataPtr ( 190 IN VARIABLE_HEADER *Variable 190 IN VARIABLE_HEADER *Variable, 191 IN VARIABLE_HEADER *VariableHeader 191 192 ) 192 193 { … … 197 198 // 198 199 Value = (UINTN) GetVariableNamePtr (Variable); 199 Value += NameSizeOfVariable (Variable );200 Value += GET_PAD_SIZE (NameSizeOfVariable (Variable ));200 Value += NameSizeOfVariable (VariableHeader); 201 Value += GET_PAD_SIZE (NameSizeOfVariable (VariableHeader)); 201 202 202 203 return (UINT8 *) Value; … … 207 208 This code gets the pointer to the next variable header. 208 209 209 @param Variable Pointer to the Variable Header. 210 @param StoreInfo Pointer to variable store info structure. 211 @param Variable Pointer to the Variable Header. 212 @param VariableHeader Pointer to the Variable Header that has consecutive content. 210 213 211 214 @return A VARIABLE_HEADER* pointer to next variable header. … … 214 217 VARIABLE_HEADER * 215 218 GetNextVariablePtr ( 216 IN VARIABLE_HEADER *Variable 217 ) 218 { 219 UINTN Value; 220 221 if (!IsValidVariableHeader (Variable)) { 222 return NULL; 223 } 224 225 Value = (UINTN) GetVariableDataPtr (Variable); 226 Value += DataSizeOfVariable (Variable); 227 Value += GET_PAD_SIZE (DataSizeOfVariable (Variable)); 228 219 IN VARIABLE_STORE_INFO *StoreInfo, 220 IN VARIABLE_HEADER *Variable, 221 IN VARIABLE_HEADER *VariableHeader 222 ) 223 { 224 EFI_PHYSICAL_ADDRESS TargetAddress; 225 EFI_PHYSICAL_ADDRESS SpareAddress; 226 UINTN Value; 227 228 Value = (UINTN) GetVariableDataPtr (Variable, VariableHeader); 229 Value += DataSizeOfVariable (VariableHeader); 230 Value += GET_PAD_SIZE (DataSizeOfVariable (VariableHeader)); 229 231 // 230 232 // Be careful about pad size for alignment 231 233 // 232 return (VARIABLE_HEADER *) HEADER_ALIGN (Value); 233 } 234 235 /** 236 This code gets the pointer to the variable name. 234 Value = HEADER_ALIGN (Value); 235 236 if (StoreInfo->FtwLastWriteData != NULL) { 237 TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; 238 SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; 239 if (((UINTN) Variable < (UINTN) TargetAddress) && (Value >= (UINTN) TargetAddress)) { 240 // 241 // Next variable is in spare block. 242 // 243 Value = (UINTN) SpareAddress + (Value - (UINTN) TargetAddress); 244 } 245 } 246 247 return (VARIABLE_HEADER *) Value; 248 } 249 250 /** 251 Get variable store status. 237 252 238 253 @param VarStoreHeader Pointer to the Variable Store Header. … … 248 263 ) 249 264 { 250 251 265 if (CompareGuid (&VarStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) && 252 266 VarStoreHeader->Format == VARIABLE_STORE_FORMATTED && … … 272 286 } 273 287 288 /** 289 Compare two variable names, one of them may be inconsecutive. 290 291 @param StoreInfo Pointer to variable store info structure. 292 @param Name1 Pointer to one variable name. 293 @param Name2 Pointer to another variable name. 294 @param NameSize Variable name size. 295 296 @retval TRUE Name1 and Name2 are identical. 297 @retval FALSE Name1 and Name2 are not identical. 298 299 **/ 300 BOOLEAN 301 CompareVariableName ( 302 IN VARIABLE_STORE_INFO *StoreInfo, 303 IN CONST CHAR16 *Name1, 304 IN CONST CHAR16 *Name2, 305 IN UINTN NameSize 306 ) 307 { 308 EFI_PHYSICAL_ADDRESS TargetAddress; 309 EFI_PHYSICAL_ADDRESS SpareAddress; 310 UINTN PartialNameSize; 311 312 if (StoreInfo->FtwLastWriteData != NULL) { 313 TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; 314 SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; 315 if (((UINTN) Name1 < (UINTN) TargetAddress) && (((UINTN) Name1 + NameSize) > (UINTN) TargetAddress)) { 316 // 317 // Name1 is inconsecutive. 318 // 319 PartialNameSize = (UINTN) TargetAddress - (UINTN) Name1; 320 // 321 // Partial content is in NV storage. 322 // 323 if (CompareMem ((UINT8 *) Name1, (UINT8 *) Name2, PartialNameSize) == 0) { 324 // 325 // Another partial content is in spare block. 326 // 327 if (CompareMem ((UINT8 *) (UINTN) SpareAddress, (UINT8 *) Name2 + PartialNameSize, NameSize - PartialNameSize) == 0) { 328 return TRUE; 329 } 330 } 331 return FALSE; 332 } else if (((UINTN) Name2 < (UINTN) TargetAddress) && (((UINTN) Name2 + NameSize) > (UINTN) TargetAddress)) { 333 // 334 // Name2 is inconsecutive. 335 // 336 PartialNameSize = (UINTN) TargetAddress - (UINTN) Name2; 337 // 338 // Partial content is in NV storage. 339 // 340 if (CompareMem ((UINT8 *) Name2, (UINT8 *) Name1, PartialNameSize) == 0) { 341 // 342 // Another partial content is in spare block. 343 // 344 if (CompareMem ((UINT8 *) (UINTN) SpareAddress, (UINT8 *) Name1 + PartialNameSize, NameSize - PartialNameSize) == 0) { 345 return TRUE; 346 } 347 } 348 return FALSE; 349 } 350 } 351 352 // 353 // Both Name1 and Name2 are consecutive. 354 // 355 if (CompareMem ((UINT8 *) Name1, (UINT8 *) Name2, NameSize) == 0) { 356 return TRUE; 357 } 358 return FALSE; 359 } 274 360 275 361 /** 276 362 This function compares a variable with variable entries in database. 277 363 364 @param StoreInfo Pointer to variable store info structure. 278 365 @param Variable Pointer to the variable in our database 366 @param VariableHeader Pointer to the Variable Header that has consecutive content. 279 367 @param VariableName Name of the variable to compare to 'Variable' 280 368 @param VendorGuid GUID of the variable to compare to 'Variable' … … 287 375 EFI_STATUS 288 376 CompareWithValidVariable ( 377 IN VARIABLE_STORE_INFO *StoreInfo, 289 378 IN VARIABLE_HEADER *Variable, 379 IN VARIABLE_HEADER *VariableHeader, 290 380 IN CONST CHAR16 *VariableName, 291 381 IN CONST EFI_GUID *VendorGuid, … … 304 394 // on the first failed comparison. 305 395 // 306 if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable ->VendorGuid)[0]) &&307 (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable ->VendorGuid)[1]) &&308 (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable ->VendorGuid)[2]) &&309 (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable ->VendorGuid)[3])396 if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &VariableHeader->VendorGuid)[0]) && 397 (((INT32 *) VendorGuid)[1] == ((INT32 *) &VariableHeader->VendorGuid)[1]) && 398 (((INT32 *) VendorGuid)[2] == ((INT32 *) &VariableHeader->VendorGuid)[2]) && 399 (((INT32 *) VendorGuid)[3] == ((INT32 *) &VariableHeader->VendorGuid)[3]) 310 400 ) { 311 ASSERT (NameSizeOfVariable (Variable ) != 0);401 ASSERT (NameSizeOfVariable (VariableHeader) != 0); 312 402 Point = (VOID *) GetVariableNamePtr (Variable); 313 if (Compare Mem (VariableName, Point, NameSizeOfVariable (Variable)) == 0) {403 if (CompareVariableName (StoreInfo, VariableName, Point, NameSizeOfVariable (VariableHeader))) { 314 404 PtrTrack->CurrPtr = Variable; 315 405 return EFI_SUCCESS; … … 322 412 323 413 /** 324 Return the variable store header and the index tablebased on the Index.325 326 @param Type The type of the variable store.327 @param IndexTable Return the index table.414 Return the variable store header and the store info based on the Index. 415 416 @param Type The type of the variable store. 417 @param StoreInfo Return the store info. 328 418 329 419 @return Pointer to the variable store header. … … 332 422 GetVariableStore ( 333 423 IN VARIABLE_STORE_TYPE Type, 334 OUT VARIABLE_INDEX_TABLE **IndexTable OPTIONAL 335 ) 336 { 337 EFI_HOB_GUID_TYPE *GuidHob; 338 EFI_FIRMWARE_VOLUME_HEADER *FvHeader; 339 VARIABLE_STORE_HEADER *VariableStoreHeader; 340 341 if (IndexTable != NULL) { 342 *IndexTable = NULL; 343 } 424 OUT VARIABLE_STORE_INFO *StoreInfo 425 ) 426 { 427 EFI_HOB_GUID_TYPE *GuidHob; 428 EFI_FIRMWARE_VOLUME_HEADER *FvHeader; 429 VARIABLE_STORE_HEADER *VariableStoreHeader; 430 EFI_PHYSICAL_ADDRESS NvStorageBase; 431 UINT32 NvStorageSize; 432 FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; 433 UINT32 BackUpOffset; 434 435 StoreInfo->IndexTable = NULL; 436 StoreInfo->FtwLastWriteData = NULL; 344 437 VariableStoreHeader = NULL; 345 438 switch (Type) { … … 356 449 // The content of NV storage for variable is not reliable in recovery boot mode. 357 450 // 358 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ? 359 PcdGet64 (PcdFlashNvStorageVariableBase64) : 360 PcdGet32 (PcdFlashNvStorageVariableBase) 361 ); 451 452 NvStorageSize = PcdGet32 (PcdFlashNvStorageVariableSize); 453 NvStorageBase = (EFI_PHYSICAL_ADDRESS) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ? 454 PcdGet64 (PcdFlashNvStorageVariableBase64) : 455 PcdGet32 (PcdFlashNvStorageVariableBase) 456 ); 457 // 458 // First let FvHeader point to NV storage base. 459 // 460 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) NvStorageBase; 461 462 // 463 // Check the FTW last write data hob. 464 // 465 BackUpOffset = 0; 466 GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); 467 if (GuidHob != NULL) { 468 FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob); 469 if (FtwLastWriteData->TargetAddress == NvStorageBase) { 470 // 471 // Let FvHeader point to spare block. 472 // 473 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FtwLastWriteData->SpareAddress; 474 DEBUG ((EFI_D_INFO, "PeiVariable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress)); 475 } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) && (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) { 476 StoreInfo->FtwLastWriteData = FtwLastWriteData; 477 // 478 // Flash NV storage from the offset is backed up in spare block. 479 // 480 BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase); 481 DEBUG ((EFI_D_INFO, "PeiVariable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress)); 482 // 483 // At least one block data in flash NV storage is still valid, so still leave FvHeader point to NV storage base. 484 // 485 } 486 } 362 487 363 488 // … … 371 496 VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) FvHeader + FvHeader->HeaderLength); 372 497 373 if (IndexTable != NULL) { 374 GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid); 375 if (GuidHob != NULL) { 376 *IndexTable = GET_GUID_HOB_DATA (GuidHob); 377 } else { 378 // 379 // If it's the first time to access variable region in flash, create a guid hob to record 380 // VAR_ADDED type variable info. 381 // Note that as the resource of PEI phase is limited, only store the limited number of 382 // VAR_ADDED type variables to reduce access time. 383 // 384 *IndexTable = BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE)); 385 (*IndexTable)->Length = 0; 386 (*IndexTable)->StartPtr = GetStartPointer (VariableStoreHeader); 387 (*IndexTable)->EndPtr = GetEndPointer (VariableStoreHeader); 388 (*IndexTable)->GoneThrough = 0; 389 } 498 GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid); 499 if (GuidHob != NULL) { 500 StoreInfo->IndexTable = GET_GUID_HOB_DATA (GuidHob); 501 } else { 502 // 503 // If it's the first time to access variable region in flash, create a guid hob to record 504 // VAR_ADDED type variable info. 505 // Note that as the resource of PEI phase is limited, only store the limited number of 506 // VAR_ADDED type variables to reduce access time. 507 // 508 StoreInfo->IndexTable = (VARIABLE_INDEX_TABLE *) BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE)); 509 StoreInfo->IndexTable->Length = 0; 510 StoreInfo->IndexTable->StartPtr = GetStartPointer (VariableStoreHeader); 511 StoreInfo->IndexTable->EndPtr = GetEndPointer (VariableStoreHeader); 512 StoreInfo->IndexTable->GoneThrough = 0; 390 513 } 391 514 } … … 397 520 } 398 521 522 StoreInfo->VariableStoreHeader = VariableStoreHeader; 399 523 return VariableStoreHeader; 400 524 } 401 525 402 526 /** 527 Get variable header that has consecutive content. 528 529 @param StoreInfo Pointer to variable store info structure. 530 @param Variable Pointer to the Variable Header. 531 @param VariableHeader Pointer to Pointer to the Variable Header that has consecutive content. 532 533 @retval TRUE Variable header is valid. 534 @retval FALSE Variable header is not valid. 535 536 **/ 537 BOOLEAN 538 GetVariableHeader ( 539 IN VARIABLE_STORE_INFO *StoreInfo, 540 IN VARIABLE_HEADER *Variable, 541 OUT VARIABLE_HEADER **VariableHeader 542 ) 543 { 544 EFI_PHYSICAL_ADDRESS TargetAddress; 545 EFI_PHYSICAL_ADDRESS SpareAddress; 546 EFI_HOB_GUID_TYPE *GuidHob; 547 UINTN PartialHeaderSize; 548 549 if (Variable == NULL) { 550 return FALSE; 551 } 552 553 // 554 // First assume variable header pointed by Variable is consecutive. 555 // 556 *VariableHeader = Variable; 557 558 if (StoreInfo->FtwLastWriteData != NULL) { 559 TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; 560 SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; 561 if (((UINTN) Variable > (UINTN) SpareAddress) && 562 (((UINTN) Variable - (UINTN) SpareAddress + (UINTN) TargetAddress) >= (UINTN) GetEndPointer (StoreInfo->VariableStoreHeader))) { 563 // 564 // Reach the end of variable store. 565 // 566 return FALSE; 567 } 568 if (((UINTN) Variable < (UINTN) TargetAddress) && (((UINTN) Variable + sizeof (VARIABLE_HEADER)) > (UINTN) TargetAddress)) { 569 // 570 // Variable header pointed by Variable is inconsecutive, 571 // create a guid hob to combine the two partial variable header content together. 572 // 573 GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); 574 if (GuidHob != NULL) { 575 *VariableHeader = (VARIABLE_HEADER *) GET_GUID_HOB_DATA (GuidHob); 576 } else { 577 *VariableHeader = (VARIABLE_HEADER *) BuildGuidHob (&gEfiCallerIdGuid, sizeof (VARIABLE_HEADER)); 578 PartialHeaderSize = (UINTN) TargetAddress - (UINTN) Variable; 579 // 580 // Partial content is in NV storage. 581 // 582 CopyMem ((UINT8 *) *VariableHeader, (UINT8 *) Variable, PartialHeaderSize); 583 // 584 // Another partial content is in spare block. 585 // 586 CopyMem ((UINT8 *) *VariableHeader + PartialHeaderSize, (UINT8 *) (UINTN) SpareAddress, sizeof (VARIABLE_HEADER) - PartialHeaderSize); 587 } 588 } 589 } else { 590 if (Variable >= GetEndPointer (StoreInfo->VariableStoreHeader)) { 591 // 592 // Reach the end of variable store. 593 // 594 return FALSE; 595 } 596 } 597 598 return IsValidVariableHeader (*VariableHeader); 599 } 600 601 /** 602 Get variable name or data to output buffer. 603 604 @param StoreInfo Pointer to variable store info structure. 605 @param NameOrData Pointer to the variable name/data that may be inconsecutive. 606 @param Size Variable name/data size. 607 @param Buffer Pointer to output buffer to hold the variable name/data. 608 609 **/ 610 VOID 611 GetVariableNameOrData ( 612 IN VARIABLE_STORE_INFO *StoreInfo, 613 IN UINT8 *NameOrData, 614 IN UINTN Size, 615 OUT UINT8 *Buffer 616 ) 617 { 618 EFI_PHYSICAL_ADDRESS TargetAddress; 619 EFI_PHYSICAL_ADDRESS SpareAddress; 620 UINTN PartialSize; 621 622 if (StoreInfo->FtwLastWriteData != NULL) { 623 TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; 624 SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; 625 if (((UINTN) NameOrData < (UINTN) TargetAddress) && (((UINTN) NameOrData + Size) > (UINTN) TargetAddress)) { 626 // 627 // Variable name/data is inconsecutive. 628 // 629 PartialSize = (UINTN) TargetAddress - (UINTN) NameOrData; 630 // 631 // Partial content is in NV storage. 632 // 633 CopyMem (Buffer, NameOrData, PartialSize); 634 // 635 // Another partial content is in spare block. 636 // 637 CopyMem (Buffer + PartialSize, (UINT8 *) (UINTN) SpareAddress, Size - PartialSize); 638 return; 639 } 640 } 641 642 // 643 // Variable name/data is consecutive. 644 // 645 CopyMem (Buffer, NameOrData, Size); 646 } 647 648 /** 403 649 Find the variable in the specified variable store. 404 650 405 @param VariableStoreHeader Pointer to the variable store header. 406 @param IndexTable Pointer to the index table. 651 @param StoreInfo Pointer to the store info structure. 407 652 @param VariableName Name of the variable to be found 408 653 @param VendorGuid Vendor GUID to be found. … … 416 661 EFI_STATUS 417 662 FindVariableEx ( 418 IN VARIABLE_STORE_HEADER *VariableStoreHeader, 419 IN VARIABLE_INDEX_TABLE *IndexTable, 663 IN VARIABLE_STORE_INFO *StoreInfo, 420 664 IN CONST CHAR16 *VariableName, 421 665 IN CONST EFI_GUID *VendorGuid, … … 429 673 UINTN Offset; 430 674 BOOLEAN StopRecord; 675 VARIABLE_HEADER *InDeletedVariable; 676 VARIABLE_STORE_HEADER *VariableStoreHeader; 677 VARIABLE_INDEX_TABLE *IndexTable; 678 VARIABLE_HEADER *VariableHeader; 679 680 VariableStoreHeader = StoreInfo->VariableStoreHeader; 431 681 432 682 if (VariableStoreHeader == NULL) { … … 442 692 } 443 693 694 IndexTable = StoreInfo->IndexTable; 444 695 PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader); 445 696 PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader); 446 697 698 InDeletedVariable = NULL; 699 447 700 // 448 701 // No Variable Address equals zero, so 0 as initial value is safe. 449 702 // 450 703 MaxIndex = NULL; 704 VariableHeader = NULL; 451 705 452 706 if (IndexTable != NULL) { … … 459 713 Offset += IndexTable->Index[Index]; 460 714 MaxIndex = (VARIABLE_HEADER *) ((UINT8 *) IndexTable->StartPtr + Offset); 461 if (CompareWithValidVariable (MaxIndex, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { 462 return EFI_SUCCESS; 715 GetVariableHeader (StoreInfo, MaxIndex, &VariableHeader); 716 if (CompareWithValidVariable (StoreInfo, MaxIndex, VariableHeader, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { 717 if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 718 InDeletedVariable = PtrTrack->CurrPtr; 719 } else { 720 return EFI_SUCCESS; 721 } 463 722 } 464 723 } … … 466 725 if (IndexTable->GoneThrough != 0) { 467 726 // 468 // If the table has all the existing variables indexed and we still cannot find it. 469 // 470 return EFI_NOT_FOUND; 727 // If the table has all the existing variables indexed, return. 728 // 729 PtrTrack->CurrPtr = InDeletedVariable; 730 return (PtrTrack->CurrPtr == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS; 471 731 } 472 732 } … … 477 737 // If not found in HOB, then let's start from the MaxIndex we've found. 478 738 // 479 Variable = GetNextVariablePtr ( MaxIndex);739 Variable = GetNextVariablePtr (StoreInfo, MaxIndex, VariableHeader); 480 740 LastVariable = MaxIndex; 481 741 } else { … … 489 749 490 750 // 491 // Find the variable by walk through non-volatilevariable store751 // Find the variable by walk through variable store 492 752 // 493 753 StopRecord = FALSE; 494 while ( (Variable < PtrTrack->EndPtr) && IsValidVariableHeader (Variable)) {495 if (Variable ->State == VAR_ADDED) {754 while (GetVariableHeader (StoreInfo, Variable, &VariableHeader)) { 755 if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 496 756 // 497 757 // Record Variable in VariableIndex HOB … … 511 771 } 512 772 513 if (CompareWithValidVariable (Variable, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { 514 return EFI_SUCCESS; 515 } 516 } 517 518 Variable = GetNextVariablePtr (Variable); 773 if (CompareWithValidVariable (StoreInfo, Variable, VariableHeader, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { 774 if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 775 InDeletedVariable = PtrTrack->CurrPtr; 776 } else { 777 return EFI_SUCCESS; 778 } 779 } 780 } 781 782 Variable = GetNextVariablePtr (StoreInfo, Variable, VariableHeader); 519 783 } 520 784 // … … 525 789 } 526 790 527 PtrTrack->CurrPtr = NULL;528 529 return EFI_NOT_FOUND;791 PtrTrack->CurrPtr = InDeletedVariable; 792 793 return (PtrTrack->CurrPtr == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS; 530 794 } 531 795 … … 536 800 @param VendorGuid Vendor GUID to be found. 537 801 @param PtrTrack Variable Track Pointer structure that contains Variable Information. 802 @param StoreInfo Return the store info. 538 803 539 804 @retval EFI_SUCCESS Variable found successfully … … 545 810 IN CONST CHAR16 *VariableName, 546 811 IN CONST EFI_GUID *VendorGuid, 547 OUT VARIABLE_POINTER_TRACK *PtrTrack 812 OUT VARIABLE_POINTER_TRACK *PtrTrack, 813 OUT VARIABLE_STORE_INFO *StoreInfo 548 814 ) 549 815 { 550 816 EFI_STATUS Status; 551 VARIABLE_STORE_HEADER *VariableStoreHeader;552 VARIABLE_INDEX_TABLE *IndexTable;553 817 VARIABLE_STORE_TYPE Type; 554 818 … … 558 822 559 823 for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) { 560 VariableStoreHeader = GetVariableStore (Type, &IndexTable);824 GetVariableStore (Type, StoreInfo); 561 825 Status = FindVariableEx ( 562 VariableStoreHeader, 563 IndexTable, 826 StoreInfo, 564 827 VariableName, 565 828 VendorGuid, … … 614 877 UINTN VarDataSize; 615 878 EFI_STATUS Status; 879 VARIABLE_STORE_INFO StoreInfo; 880 VARIABLE_HEADER *VariableHeader; 616 881 617 882 if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) { … … 619 884 } 620 885 886 VariableHeader = NULL; 887 621 888 // 622 889 // Find existing variable 623 890 // 624 Status = FindVariable (VariableName, VariableGuid, &Variable );891 Status = FindVariable (VariableName, VariableGuid, &Variable, &StoreInfo); 625 892 if (EFI_ERROR (Status)) { 626 893 return Status; 627 894 } 895 GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader); 896 628 897 // 629 898 // Get data size 630 899 // 631 VarDataSize = DataSizeOfVariable (Variable .CurrPtr);900 VarDataSize = DataSizeOfVariable (VariableHeader); 632 901 if (*DataSize >= VarDataSize) { 633 902 if (Data == NULL) { … … 635 904 } 636 905 637 CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr), VarDataSize);906 GetVariableNameOrData (&StoreInfo, GetVariableDataPtr (Variable.CurrPtr, VariableHeader), VarDataSize, Data); 638 907 639 908 if (Attributes != NULL) { 640 *Attributes = Variable .CurrPtr->Attributes;909 *Attributes = VariableHeader->Attributes; 641 910 } 642 911 … … 690 959 VARIABLE_POINTER_TRACK Variable; 691 960 VARIABLE_POINTER_TRACK VariableInHob; 961 VARIABLE_POINTER_TRACK VariablePtrTrack; 692 962 UINTN VarNameSize; 693 963 EFI_STATUS Status; 694 964 VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax]; 965 VARIABLE_HEADER *VariableHeader; 966 VARIABLE_STORE_INFO StoreInfo; 967 VARIABLE_STORE_INFO StoreInfoForNv; 968 VARIABLE_STORE_INFO StoreInfoForHob; 695 969 696 970 if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) { … … 698 972 } 699 973 700 Status = FindVariable (VariableName, VariableGuid, &Variable); 974 VariableHeader = NULL; 975 976 Status = FindVariable (VariableName, VariableGuid, &Variable, &StoreInfo); 701 977 if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) { 702 978 return Status; … … 707 983 // If variable name is not NULL, get next variable 708 984 // 709 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); 710 } 711 712 VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, NULL); 713 VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, NULL); 985 GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader); 986 Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); 987 } 988 989 VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, &StoreInfoForHob); 990 VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, &StoreInfoForNv); 714 991 715 992 while (TRUE) { … … 717 994 // Switch from HOB to Non-Volatile. 718 995 // 719 while ((Variable.CurrPtr >= Variable.EndPtr) || 720 (Variable.CurrPtr == NULL) || 721 !IsValidVariableHeader (Variable.CurrPtr) 722 ) { 996 while (!GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader)) { 723 997 // 724 998 // Find current storage index … … 749 1023 Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]); 750 1024 Variable.CurrPtr = Variable.StartPtr; 751 } 752 753 if (Variable.CurrPtr->State == VAR_ADDED) { 1025 GetVariableStore (Type, &StoreInfo); 1026 } 1027 1028 if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 1029 if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 1030 // 1031 // If it is a IN_DELETED_TRANSITION variable, 1032 // and there is also a same ADDED one at the same time, 1033 // don't return it. 1034 // 1035 Status = FindVariableEx ( 1036 &StoreInfo, 1037 GetVariableNamePtr (Variable.CurrPtr), 1038 &VariableHeader->VendorGuid, 1039 &VariablePtrTrack 1040 ); 1041 if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr != Variable.CurrPtr) { 1042 Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); 1043 continue; 1044 } 1045 } 754 1046 755 1047 // … … 760 1052 ) { 761 1053 Status = FindVariableEx ( 762 VariableStoreHeader[VariableStoreTypeHob], 763 NULL, 1054 &StoreInfoForHob, 764 1055 GetVariableNamePtr (Variable.CurrPtr), 765 &Variable .CurrPtr->VendorGuid,1056 &VariableHeader->VendorGuid, 766 1057 &VariableInHob 767 1058 ); 768 1059 if (!EFI_ERROR (Status)) { 769 Variable.CurrPtr = GetNextVariablePtr ( Variable.CurrPtr);1060 Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); 770 1061 continue; 771 1062 } 772 1063 } 773 1064 774 VarNameSize = NameSizeOfVariable (Variable .CurrPtr);1065 VarNameSize = NameSizeOfVariable (VariableHeader); 775 1066 ASSERT (VarNameSize != 0); 776 1067 777 1068 if (VarNameSize <= *VariableNameSize) { 778 CopyMem (VariableName, GetVariableNamePtr (Variable.CurrPtr), VarNameSize);779 780 CopyMem (VariableGuid, &Variable .CurrPtr->VendorGuid, sizeof (EFI_GUID));1069 GetVariableNameOrData (&StoreInfo, (UINT8 *) GetVariableNamePtr (Variable.CurrPtr), VarNameSize, (UINT8 *) VariableName); 1070 1071 CopyMem (VariableGuid, &VariableHeader->VendorGuid, sizeof (EFI_GUID)); 781 1072 782 1073 Status = EFI_SUCCESS; … … 791 1082 return Status; 792 1083 } else { 793 Variable.CurrPtr = GetNextVariablePtr ( Variable.CurrPtr);794 } 795 } 796 } 1084 Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); 1085 } 1086 } 1087 } -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/Pei/Variable.h
r48674 r58459 3 3 internal structure and functions used by PeiVariable module. 4 4 5 Copyright (c) 2009 - 201 1, Intel Corporation. All rights reserved.<BR>5 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR> 6 6 This program and the accompanying materials 7 7 are licensed and made available under the terms and conditions of the BSD License … … 31 31 #include <Guid/VariableIndexTable.h> 32 32 #include <Guid/SystemNvDataGuid.h> 33 #include <Guid/FaultTolerantWrite.h> 33 34 34 35 typedef enum { … … 37 38 VariableStoreTypeMax 38 39 } VARIABLE_STORE_TYPE; 40 41 typedef struct { 42 VARIABLE_STORE_HEADER *VariableStoreHeader; 43 VARIABLE_INDEX_TABLE *IndexTable; 44 // 45 // If it is not NULL, it means there may be an inconsecutive variable whose 46 // partial content is still in NV storage, but another partial content is backed up 47 // in spare block. 48 // 49 FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; 50 } VARIABLE_STORE_INFO; 39 51 40 52 // -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf
r48674 r58459 1 1 ## @file 2 # The component description for PEI variable driver. 2 # Implements ReadOnly Variable Services required by PEIM and installs PEI ReadOnly Varaiable2 PPI 3 # This module implements ReadOnly Variable Services required by PEIM and installs PEI ReadOnly Varaiable2 PPI. 3 4 # 4 # Copyright (c) 2009 - 201 1, Intel Corporation. All rights reserved.<BR>5 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 5 6 # This program and the accompanying materials 6 7 # are licensed and made available under the terms and conditions of the BSD License … … 14 15 [Defines] 15 16 INF_VERSION = 0x00010005 16 BASE_NAME = PeiVariable 17 BASE_NAME = PeiVariableAuth 18 MODULE_UNI_FILE = PeiVariableAuth.uni 17 19 FILE_GUID = B1F7AF2F-2807-478c-A893-2BF4DDD1F62B 18 20 MODULE_TYPE = PEIM … … 45 47 46 48 [Guids] 49 ## CONSUMES ## GUID # Variable store header 50 ## SOMETIMES_CONSUMES ## HOB 47 51 gEfiAuthenticatedVariableGuid 52 ## SOMETIMES_PRODUCES ## HOB 53 ## SOMETIMES_CONSUMES ## HOB 48 54 gEfiVariableIndexTableGuid 49 gEfiSystemNvDataFvGuid 55 gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID 56 gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB 50 57 51 58 [Ppis] 52 gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_PRODUCES (Not for boot mode RECOVERY)59 gEfiPeiReadOnlyVariable2PpiGuid ## PRODUCES 53 60 54 61 [Pcd] 55 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES 56 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES 62 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES 63 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES 64 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES 57 65 58 66 [Depex] 59 TRUE67 gEdkiiFaultTolerantWriteGuid 60 68 61 # 62 # [BootMode] 63 # RECOVERY ## CONSUMES 64 # 69 # [BootMode] 70 # RECOVERY_FULL ## SOMETIMES_CONSUMES 65 71 72 [UserExtensions.TianoCore."ExtraFiles"] 73 PeiVariableExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
r48674 r58459 3 3 service in UEFI2.2. 4 4 5 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5 Caution: This module requires additional review when modified. 6 This driver will have external input - variable data. It may be input in SMM mode. 7 This external input must be validated carefully to avoid security issue like 8 buffer overflow, integer overflow. 9 Variable attribute should also be checked to avoid authentication bypass. 10 The whole SMM authentication variable design relies on the integrity of flash part and SMM. 11 which is assumed to be protected by platform. All variable code and metadata in flash/SMM Memory 12 may not be modified without authorization. If platform fails to protect these resources, 13 the authentication service provided in this driver will be broken, and the behavior is undefined. 14 15 ProcessVarWithPk(), ProcessVarWithKek() and ProcessVariable() are the function to do 16 variable authentication. 17 18 VerifyTimeBasedPayload() and VerifyCounterBasedPayload() are sub function to do verification. 19 They will do basic validation for authentication data structure, then call crypto library 20 to verify the signature. 21 22 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 23 This program and the accompanying materials 7 24 are licensed and made available under the terms and conditions of the BSD License … … 20 37 /// Global database array for scratch 21 38 /// 22 UINT8 mPubKeyStore[MAX_KEYDB_SIZE];39 UINT8 *mPubKeyStore; 23 40 UINT32 mPubKeyNumber; 41 UINT32 mMaxKeyNumber; 42 UINT32 mMaxKeyDbSize; 43 UINT8 *mCertDbStore; 44 UINT32 mMaxCertDbSize; 24 45 UINT32 mPlatformMode; 46 UINT8 mVendorKeyState; 47 25 48 EFI_GUID mSignatureSupport[] = {EFI_CERT_SHA1_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_RSA2048_GUID, EFI_CERT_X509_GUID}; 26 49 // … … 32 55 // 33 56 VOID *mHashCtx = NULL; 34 35 //36 // Pointer to runtime buffer.37 // For "Append" operation to an existing variable, a read/modify/write operation38 // is supported by firmware internally. Reserve runtime buffer to cache previous39 // variable data in runtime phase because memory allocation is forbidden in virtual mode.40 //41 VOID *mStorageArea = NULL;42 57 43 58 // … … 177 192 178 193 // 179 // Reserved runtime buffer for "Append" operation in virtual mode. 180 // 181 mStorageArea = AllocateRuntimePool (PcdGet32 (PcdMaxVariableSize)); 182 if (mStorageArea == NULL) { 194 // Reserve runtime buffer for public key database. The size excludes variable header and name size. 195 // 196 mMaxKeyDbSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - sizeof (AUTHVAR_KEYDB_NAME); 197 mMaxKeyNumber = mMaxKeyDbSize / EFI_CERT_TYPE_RSA2048_SIZE; 198 mPubKeyStore = AllocateRuntimePool (mMaxKeyDbSize); 199 if (mPubKeyStore == NULL) { 200 return EFI_OUT_OF_RESOURCES; 201 } 202 203 // 204 // Reserve runtime buffer for certificate database. The size excludes variable header and name size. 205 // 206 mMaxCertDbSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - sizeof (EFI_CERT_DB_NAME); 207 mCertDbStore = AllocateRuntimePool (mMaxCertDbSize); 208 if (mCertDbStore == NULL) { 183 209 return EFI_OUT_OF_RESOURCES; 184 210 } … … 230 256 Data = GetVariableDataPtr (Variable.CurrPtr); 231 257 ASSERT ((DataSize != 0) && (Data != NULL)); 258 // 259 // "AuthVarKeyDatabase" is an internal variable. Its DataSize is always ensured not to exceed mPubKeyStore buffer size(See definition before) 260 // Therefore, there is no memory overflow in underlying CopyMem. 261 // 232 262 CopyMem (mPubKeyStore, (UINT8 *) Data, DataSize); 233 263 mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE); … … 242 272 243 273 // 244 // Check "SetupMode" variable's existence. 245 // If it doesn't exist, check PK database's existence to determine the value. 246 // Then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set. 247 // 248 Status = FindVariable ( 274 // Create "SetupMode" variable with BS+RT attribute set. 275 // 276 FindVariable (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 277 if (PkVariable.CurrPtr == NULL) { 278 mPlatformMode = SETUP_MODE; 279 } else { 280 mPlatformMode = USER_MODE; 281 } 282 Status = UpdateVariable ( 249 283 EFI_SETUP_MODE_NAME, 250 284 &gEfiGlobalVariableGuid, 285 &mPlatformMode, 286 sizeof(UINT8), 287 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 288 0, 289 0, 251 290 &Variable, 252 &mVariableModuleGlobal->VariableGlobal, 253 FALSE 291 NULL 254 292 ); 255 256 if (Variable.CurrPtr == NULL) { 257 if (PkVariable.CurrPtr == NULL) { 258 mPlatformMode = SETUP_MODE; 259 } else { 260 mPlatformMode = USER_MODE; 261 } 262 263 VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; 264 Status = UpdateVariable ( 265 EFI_SETUP_MODE_NAME, 266 &gEfiGlobalVariableGuid, 267 &mPlatformMode, 268 sizeof(UINT8), 269 VarAttr, 270 0, 271 0, 272 &Variable, 273 NULL 274 ); 275 if (EFI_ERROR (Status)) { 276 return Status; 277 } 278 } else { 279 mPlatformMode = *(GetVariableDataPtr (Variable.CurrPtr)); 280 } 281 // 282 // Check "SignatureSupport" variable's existence. 283 // If it doesn't exist, then create a new one with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set. 284 // 285 Status = FindVariable ( 286 EFI_SIGNATURE_SUPPORT_NAME, 287 &gEfiGlobalVariableGuid, 288 &Variable, 289 &mVariableModuleGlobal->VariableGlobal, 290 FALSE 291 ); 292 293 if (Variable.CurrPtr == NULL) { 294 VarAttr = EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; 295 Status = UpdateVariable ( 296 EFI_SIGNATURE_SUPPORT_NAME, 297 &gEfiGlobalVariableGuid, 298 mSignatureSupport, 299 sizeof(mSignatureSupport), 300 VarAttr, 301 0, 302 0, 303 &Variable, 304 NULL 305 ); 293 if (EFI_ERROR (Status)) { 294 return Status; 295 } 296 297 // 298 // Create "SignatureSupport" variable with BS+RT attribute set. 299 // 300 FindVariable (EFI_SIGNATURE_SUPPORT_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 301 Status = UpdateVariable ( 302 EFI_SIGNATURE_SUPPORT_NAME, 303 &gEfiGlobalVariableGuid, 304 mSignatureSupport, 305 sizeof(mSignatureSupport), 306 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 307 0, 308 0, 309 &Variable, 310 NULL 311 ); 312 if (EFI_ERROR (Status)) { 313 return Status; 306 314 } 307 315 … … 311 319 // If "SecureBootEnable" variable is SECURE_BOOT_DISABLE, Set "SecureBoot" variable to SECURE_BOOT_MODE_DISABLE. 312 320 // 313 SecureBootEnable = SECURE_BOOT_ MODE_DISABLE;321 SecureBootEnable = SECURE_BOOT_DISABLE; 314 322 FindVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 315 323 if (Variable.CurrPtr != NULL) { … … 319 327 // "SecureBootEnable" not exist, initialize it in USER_MODE. 320 328 // 321 SecureBootEnable = SECURE_BOOT_ MODE_ENABLE;329 SecureBootEnable = SECURE_BOOT_ENABLE; 322 330 Status = UpdateVariable ( 323 331 EFI_SECURE_BOOT_ENABLE_NAME, … … 336 344 } 337 345 346 // 347 // Create "SecureBoot" variable with BS+RT attribute set. 348 // 338 349 if (SecureBootEnable == SECURE_BOOT_ENABLE && mPlatformMode == USER_MODE) { 339 350 SecureBootMode = SECURE_BOOT_MODE_ENABLE; … … 347 358 &SecureBootMode, 348 359 sizeof (UINT8), 349 EFI_VARIABLE_ NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,360 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 350 361 0, 351 362 0, … … 362 373 363 374 // 364 // Check "CustomMode" variable's existence.375 // Initialize "CustomMode" in STANDARD_SECURE_BOOT_MODE state. 365 376 // 366 377 FindVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 367 if (Variable.CurrPtr != NULL) { 368 CustomMode = *(GetVariableDataPtr (Variable.CurrPtr)); 369 } else { 370 // 371 // "CustomMode" not exist, initialize it in STANDARD_SECURE_BOOT_MODE. 372 // 373 CustomMode = STANDARD_SECURE_BOOT_MODE; 374 Status = UpdateVariable ( 375 EFI_CUSTOM_MODE_NAME, 376 &gEfiCustomModeEnableGuid, 377 &CustomMode, 378 sizeof (UINT8), 379 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 380 0, 381 0, 382 &Variable, 383 NULL 384 ); 385 if (EFI_ERROR (Status)) { 386 return Status; 387 } 378 CustomMode = STANDARD_SECURE_BOOT_MODE; 379 Status = UpdateVariable ( 380 EFI_CUSTOM_MODE_NAME, 381 &gEfiCustomModeEnableGuid, 382 &CustomMode, 383 sizeof (UINT8), 384 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 385 0, 386 0, 387 &Variable, 388 NULL 389 ); 390 if (EFI_ERROR (Status)) { 391 return Status; 388 392 } 389 393 … … 405 409 if (Variable.CurrPtr == NULL) { 406 410 VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; 407 ListSize = 0;411 ListSize = sizeof (UINT32); 408 412 Status = UpdateVariable ( 409 413 EFI_CERT_DB_NAME, … … 417 421 NULL 418 422 ); 419 423 if (EFI_ERROR (Status)) { 424 return Status; 425 } 420 426 } 427 428 // 429 // Check "VendorKeysNv" variable's existence and create "VendorKeys" variable accordingly. 430 // 431 FindVariable (EFI_VENDOR_KEYS_NV_VARIABLE_NAME, &gEfiVendorKeysNvGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 432 if (Variable.CurrPtr != NULL) { 433 mVendorKeyState = *(GetVariableDataPtr (Variable.CurrPtr)); 434 } else { 435 // 436 // "VendorKeysNv" not exist, initialize it in VENDOR_KEYS_VALID state. 437 // 438 mVendorKeyState = VENDOR_KEYS_VALID; 439 Status = UpdateVariable ( 440 EFI_VENDOR_KEYS_NV_VARIABLE_NAME, 441 &gEfiVendorKeysNvGuid, 442 &mVendorKeyState, 443 sizeof (UINT8), 444 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 445 0, 446 0, 447 &Variable, 448 NULL 449 ); 450 if (EFI_ERROR (Status)) { 451 return Status; 452 } 453 } 454 455 // 456 // Create "VendorKeys" variable with BS+RT attribute set. 457 // 458 FindVariable (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 459 Status = UpdateVariable ( 460 EFI_VENDOR_KEYS_VARIABLE_NAME, 461 &gEfiGlobalVariableGuid, 462 &mVendorKeyState, 463 sizeof (UINT8), 464 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 465 0, 466 0, 467 &Variable, 468 NULL 469 ); 470 if (EFI_ERROR (Status)) { 471 return Status; 472 } 473 474 DEBUG ((EFI_D_INFO, "Variable %s is %x\n", EFI_VENDOR_KEYS_VARIABLE_NAME, mVendorKeyState)); 421 475 422 476 return Status; … … 427 481 428 482 @param[in] PubKey Input pointer to Public Key data 483 @param[in] VariableDataEntry The variable data entry 429 484 430 485 @return Index of new added item … … 433 488 UINT32 434 489 AddPubKeyInStore ( 435 IN UINT8 *PubKey 490 IN UINT8 *PubKey, 491 IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry 436 492 ) 437 493 { 438 EFI_STATUS Status; 439 BOOLEAN IsFound; 440 UINT32 Index; 441 VARIABLE_POINTER_TRACK Variable; 442 UINT8 *Ptr; 494 EFI_STATUS Status; 495 BOOLEAN IsFound; 496 UINT32 Index; 497 VARIABLE_POINTER_TRACK Variable; 498 UINT8 *Ptr; 499 UINT8 *Data; 500 UINTN DataSize; 501 VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry; 502 UINT32 Attributes; 443 503 444 504 if (PubKey == NULL) { … … 453 513 FALSE 454 514 ); 455 ASSERT_EFI_ERROR (Status); 515 if (EFI_ERROR (Status)) { 516 DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status)); 517 return 0; 518 } 519 456 520 // 457 521 // Check whether the public key entry does exist. … … 470 534 // Add public key in database. 471 535 // 472 if (mPubKeyNumber == MAX_KEY_NUM) {536 if (mPubKeyNumber == mMaxKeyNumber) { 473 537 // 474 // Notes: Database is full, need enhancement here, currently just return 0. 538 // Public key dadatase is full, try to reclaim invalid key. 539 // 540 if (AtRuntime ()) { 541 // 542 // NV storage can't reclaim at runtime. 543 // 544 return 0; 545 } 546 547 Status = Reclaim ( 548 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, 549 &mVariableModuleGlobal->NonVolatileLastVariableOffset, 550 FALSE, 551 NULL, 552 NULL, 553 0, 554 TRUE 555 ); 556 if (EFI_ERROR (Status)) { 557 return 0; 558 } 559 560 Status = FindVariable ( 561 AUTHVAR_KEYDB_NAME, 562 &gEfiAuthenticatedVariableGuid, 563 &Variable, 564 &mVariableModuleGlobal->VariableGlobal, 565 FALSE 566 ); 567 if (EFI_ERROR (Status)) { 568 DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status)); 569 return 0; 570 } 571 572 DataSize = DataSizeOfVariable (Variable.CurrPtr); 573 Data = GetVariableDataPtr (Variable.CurrPtr); 574 ASSERT ((DataSize != 0) && (Data != NULL)); 575 // 576 // "AuthVarKeyDatabase" is an internal used variable. Its DataSize is always ensured not to exceed mPubKeyStore buffer size(See definition before) 577 // Therefore, there is no memory overflow in underlying CopyMem. 578 // 579 CopyMem (mPubKeyStore, (UINT8 *) Data, DataSize); 580 mPubKeyNumber = (UINT32) (DataSize / EFI_CERT_TYPE_RSA2048_SIZE); 581 582 if (mPubKeyNumber == mMaxKeyNumber) { 583 return 0; 584 } 585 } 586 587 // 588 // Check the variable space for both public key and variable data. 589 // 590 PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * EFI_CERT_TYPE_RSA2048_SIZE; 591 PublicKeyEntry.Guid = &gEfiAuthenticatedVariableGuid; 592 PublicKeyEntry.Name = AUTHVAR_KEYDB_NAME; 593 Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; 594 595 if (!CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) { 596 // 597 // No enough variable space. 475 598 // 476 599 return 0; … … 487 610 mPubKeyStore, 488 611 mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, 489 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,612 Attributes, 490 613 0, 491 614 0, … … 493 616 NULL 494 617 ); 495 ASSERT_EFI_ERROR (Status); 618 if (EFI_ERROR (Status)) { 619 DEBUG ((EFI_D_ERROR, "Update public key database variable failure, Status = %r\n", Status)); 620 return 0; 621 } 496 622 } 497 623 … … 502 628 Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256_GUID type. 503 629 Follow the steps in UEFI2.2. 630 631 Caution: This function may receive untrusted input. 632 This function may be invoked in SMM mode, and datasize and data are external input. 633 This function will do basic validation, before parse the data. 634 This function will parse the authentication carefully to avoid security issues, like 635 buffer overflow, integer overflow. 504 636 505 637 @param[in] Data Pointer to data with AuthInfo. … … 524 656 UINT8 Digest[SHA256_DIGEST_SIZE]; 525 657 VOID *Rsa; 526 658 UINTN PayloadSize; 659 660 PayloadSize = DataSize - AUTHINFO_SIZE; 527 661 Rsa = NULL; 528 662 CertData = NULL; … … 556 690 goto Done; 557 691 } 558 Status = Sha256Update (mHashCtx, Data + AUTHINFO_SIZE, (UINTN) (DataSize - AUTHINFO_SIZE)); 692 Status = Sha256Update (mHashCtx, Data + AUTHINFO_SIZE, PayloadSize); 693 if (!Status) { 694 goto Done; 695 } 696 // 697 // Hash Size. 698 // 699 Status = Sha256Update (mHashCtx, &PayloadSize, sizeof (UINTN)); 559 700 if (!Status) { 560 701 goto Done; … … 626 767 EFI_STATUS Status; 627 768 VARIABLE_POINTER_TRACK Variable; 628 UINT32 VarAttr;629 769 UINT8 SecureBootMode; 630 770 UINT8 SecureBootEnable; … … 642 782 } 643 783 644 mPlatformMode = Mode; 645 VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; 646 Status = UpdateVariable ( 647 EFI_SETUP_MODE_NAME, 648 &gEfiGlobalVariableGuid, 649 &mPlatformMode, 650 sizeof(UINT8), 651 VarAttr, 652 0, 653 0, 654 &Variable, 655 NULL 656 ); 657 if (EFI_ERROR (Status)) { 658 return Status; 659 } 784 // 785 // Update the value of SetupMode variable by a simple mem copy, this could avoid possible 786 // variable storage reclaim at runtime. 787 // 788 mPlatformMode = (UINT8) Mode; 789 CopyMem (GetVariableDataPtr (Variable.CurrPtr), &mPlatformMode, sizeof(UINT8)); 660 790 661 791 if (AtRuntime ()) { … … 697 827 } 698 828 699 VarAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;700 829 Status = UpdateVariable ( 701 830 EFI_SECURE_BOOT_MODE_NAME, … … 703 832 &SecureBootMode, 704 833 sizeof(UINT8), 705 VarAttr,834 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 706 835 0, 707 836 0, … … 757 886 758 887 /** 759 Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK variable.888 Check input data form to make sure it is a valid EFI_SIGNATURE_LIST for PK/KEK/db/dbx variable. 760 889 761 890 @param[in] VariableName Name of Variable to be check. … … 781 910 UINT32 SigCount; 782 911 BOOLEAN IsPk; 912 VOID *RsaContext; 913 EFI_SIGNATURE_DATA *CertData; 914 UINTN CertLen; 783 915 784 916 if (DataSize == 0) { … … 790 922 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_PLATFORM_KEY_NAME) == 0)){ 791 923 IsPk = TRUE; 792 } else if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0)) { 924 } else if ((CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0) || 925 (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) && 926 (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0 || StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))){ 793 927 IsPk = FALSE; 794 928 } else { … … 799 933 SigList = (EFI_SIGNATURE_LIST *) Data; 800 934 SigDataSize = DataSize; 935 RsaContext = NULL; 801 936 802 937 // … … 830 965 } 831 966 967 if (CompareGuid (&SigList->SignatureType, &gEfiCertX509Guid)) { 968 // 969 // Try to retrieve the RSA public key from the X.509 certificate. 970 // If this operation fails, it's not a valid certificate. 971 // 972 RsaContext = RsaNew (); 973 if (RsaContext == NULL) { 974 return EFI_INVALID_PARAMETER; 975 } 976 CertData = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize); 977 CertLen = SigList->SignatureSize - sizeof (EFI_GUID); 978 if (!RsaGetPublicKeyFromX509 (CertData->SignatureData, CertLen, &RsaContext)) { 979 RsaFree (RsaContext); 980 return EFI_INVALID_PARAMETER; 981 } 982 RsaFree (RsaContext); 983 } 984 832 985 if ((SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) % SigList->SignatureSize != 0) { 833 986 return EFI_INVALID_PARAMETER; … … 851 1004 852 1005 /** 1006 Update "VendorKeys" variable to record the out of band secure boot key modification. 1007 1008 @return EFI_SUCCESS Variable is updated successfully. 1009 @return Others Failed to update variable. 1010 1011 **/ 1012 EFI_STATUS 1013 VendorKeyIsModified ( 1014 VOID 1015 ) 1016 { 1017 EFI_STATUS Status; 1018 VARIABLE_POINTER_TRACK Variable; 1019 1020 if (mVendorKeyState == VENDOR_KEYS_MODIFIED) { 1021 return EFI_SUCCESS; 1022 } 1023 mVendorKeyState = VENDOR_KEYS_MODIFIED; 1024 1025 FindVariable (EFI_VENDOR_KEYS_NV_VARIABLE_NAME, &gEfiVendorKeysNvGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1026 Status = UpdateVariable ( 1027 EFI_VENDOR_KEYS_NV_VARIABLE_NAME, 1028 &gEfiVendorKeysNvGuid, 1029 &mVendorKeyState, 1030 sizeof (UINT8), 1031 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 1032 0, 1033 0, 1034 &Variable, 1035 NULL 1036 ); 1037 if (EFI_ERROR (Status)) { 1038 return Status; 1039 } 1040 1041 FindVariable (EFI_VENDOR_KEYS_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1042 return UpdateVariable ( 1043 EFI_VENDOR_KEYS_VARIABLE_NAME, 1044 &gEfiGlobalVariableGuid, 1045 &mVendorKeyState, 1046 sizeof (UINT8), 1047 EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1048 0, 1049 0, 1050 &Variable, 1051 NULL 1052 ); 1053 } 1054 1055 /** 853 1056 Process variable with platform key for verification. 1057 1058 Caution: This function may receive untrusted input. 1059 This function may be invoked in SMM mode, and datasize and data are external input. 1060 This function will do basic validation, before parse the data. 1061 This function will parse the authentication carefully to avoid security issues, like 1062 buffer overflow, integer overflow. 1063 This function will check attribute carefully to avoid authentication bypass. 854 1064 855 1065 @param[in] VariableName Name of Variable to be found. … … 887 1097 (Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) == 0) { 888 1098 // 889 // PK and KEKshould set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based1099 // PK, KEK and db/dbx should set EFI_VARIABLE_NON_VOLATILE attribute and should be a time-based 890 1100 // authenticated variable. 891 1101 // … … 893 1103 } 894 1104 895 if (mPlatformMode == USER_MODE && !(InCustomMode() && UserPhysicalPresent())) { 896 // 897 // Verify against X509 Cert PK. 898 // 899 Del = FALSE; 900 Status = VerifyTimeBasedPayload ( 901 VariableName, 902 VendorGuid, 903 Data, 904 DataSize, 905 Variable, 906 Attributes, 907 AuthVarTypePk, 908 &Del 909 ); 910 if (!EFI_ERROR (Status)) { 911 // 912 // If delete PK in user mode, need change to setup mode. 913 // 914 if (Del && IsPk) { 915 Status = UpdatePlatformMode (SETUP_MODE); 916 } 917 } 918 return Status; 919 } else { 920 // 921 // Process PK or KEK in Setup mode or Custom Secure Boot mode. 922 // 1105 Del = FALSE; 1106 if ((InCustomMode() && UserPhysicalPresent()) || (mPlatformMode == SETUP_MODE && !IsPk)) { 923 1107 Payload = (UINT8 *) Data + AUTHINFO2_SIZE (Data); 924 1108 PayloadSize = DataSize - AUTHINFO2_SIZE (Data); 1109 if (PayloadSize == 0) { 1110 Del = TRUE; 1111 } 925 1112 926 1113 Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize); … … 940 1127 &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp 941 1128 ); 942 943 if (IsPk) { 944 if (PayloadSize != 0) { 945 // 946 // If enroll PK in setup mode, need change to user mode. 947 // 948 Status = UpdatePlatformMode (USER_MODE); 949 } else { 950 // 951 // If delete PK in custom mode, need change to setup mode. 952 // 953 UpdatePlatformMode (SETUP_MODE); 954 } 955 } 1129 if (EFI_ERROR(Status)) { 1130 return Status; 1131 } 1132 1133 if ((mPlatformMode != SETUP_MODE) || IsPk) { 1134 Status = VendorKeyIsModified (); 1135 } 1136 } else if (mPlatformMode == USER_MODE) { 1137 // 1138 // Verify against X509 Cert in PK database. 1139 // 1140 Status = VerifyTimeBasedPayload ( 1141 VariableName, 1142 VendorGuid, 1143 Data, 1144 DataSize, 1145 Variable, 1146 Attributes, 1147 AuthVarTypePk, 1148 &Del 1149 ); 1150 } else { 1151 // 1152 // Verify against the certificate in data payload. 1153 // 1154 Status = VerifyTimeBasedPayload ( 1155 VariableName, 1156 VendorGuid, 1157 Data, 1158 DataSize, 1159 Variable, 1160 Attributes, 1161 AuthVarTypePayload, 1162 &Del 1163 ); 1164 } 1165 1166 if (!EFI_ERROR(Status) && IsPk) { 1167 if (mPlatformMode == SETUP_MODE && !Del) { 1168 // 1169 // If enroll PK in setup mode, need change to user mode. 1170 // 1171 Status = UpdatePlatformMode (USER_MODE); 1172 } else if (mPlatformMode == USER_MODE && Del){ 1173 // 1174 // If delete PK in user mode, need change to setup mode. 1175 // 1176 Status = UpdatePlatformMode (SETUP_MODE); 1177 } 956 1178 } 957 1179 … … 961 1183 /** 962 1184 Process variable with key exchange key for verification. 1185 1186 Caution: This function may receive untrusted input. 1187 This function may be invoked in SMM mode, and datasize and data are external input. 1188 This function will do basic validation, before parse the data. 1189 This function will parse the authentication carefully to avoid security issues, like 1190 buffer overflow, integer overflow. 1191 This function will check attribute carefully to avoid authentication bypass. 963 1192 964 1193 @param[in] VariableName Name of Variable to be found. … … 1021 1250 PayloadSize = DataSize - AUTHINFO2_SIZE (Data); 1022 1251 1252 Status = CheckSignatureListFormat(VariableName, VendorGuid, Payload, PayloadSize); 1253 if (EFI_ERROR (Status)) { 1254 return Status; 1255 } 1256 1023 1257 Status = UpdateVariable ( 1024 1258 VariableName, … … 1032 1266 &((EFI_VARIABLE_AUTHENTICATION_2 *) Data)->TimeStamp 1033 1267 ); 1268 if (EFI_ERROR (Status)) { 1269 return Status; 1270 } 1271 1272 if (mPlatformMode != SETUP_MODE) { 1273 Status = VendorKeyIsModified (); 1274 } 1034 1275 } 1035 1276 … … 1039 1280 /** 1040 1281 Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set 1282 1283 Caution: This function may receive untrusted input. 1284 This function may be invoked in SMM mode, and datasize and data are external input. 1285 This function will do basic validation, before parse the data. 1286 This function will parse the authentication carefully to avoid security issues, like 1287 buffer overflow, integer overflow. 1288 This function will check attribute carefully to avoid authentication bypass. 1041 1289 1042 1290 @param[in] VariableName Name of Variable to be found. … … 1052 1300 @return EFI_WRITE_PROTECTED Variable is write-protected and needs authentication with 1053 1301 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set. 1302 @return EFI_OUT_OF_RESOURCES The Database to save the public key is full. 1054 1303 @return EFI_SECURITY_VIOLATION The variable is with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 1055 1304 set, but the AuthInfo does NOT pass the validation … … 1076 1325 UINT32 KeyIndex; 1077 1326 UINT64 MonotonicCount; 1327 VARIABLE_ENTRY_CONSISTENCY VariableDataEntry; 1078 1328 1079 1329 KeyIndex = 0; … … 1090 1340 } 1091 1341 1342 // 1343 // A time-based authenticated variable and a count-based authenticated variable 1344 // can't be updated by each other. 1345 // 1346 if (Variable->CurrPtr != NULL) { 1347 if (((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) && 1348 ((Variable->CurrPtr->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) { 1349 return EFI_SECURITY_VIOLATION; 1350 } 1351 1352 if (((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) && 1353 ((Variable->CurrPtr->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0)) { 1354 return EFI_SECURITY_VIOLATION; 1355 } 1356 } 1357 1092 1358 // 1093 1359 // Process Time-based Authenticated variable. … … 1157 1423 if (!IsFirstTime) { 1158 1424 // 1159 // Check input PubKey. 1160 // 1161 if (CompareMem (PubKey, mPubKeyStore + (KeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, EFI_CERT_TYPE_RSA2048_SIZE) != 0) { 1425 // 2 cases need to check here 1426 // 1. Internal PubKey variable. PubKeyIndex is always 0 1427 // 2. Other counter-based AuthVariable. Check input PubKey. 1428 // 1429 if (KeyIndex == 0 || CompareMem (PubKey, mPubKeyStore + (KeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, EFI_CERT_TYPE_RSA2048_SIZE) != 0) { 1162 1430 return EFI_SECURITY_VIOLATION; 1163 1431 } … … 1185 1453 // 1186 1454 if (IsFirstTime && !IsDeletion) { 1455 VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE; 1456 VariableDataEntry.Guid = VendorGuid; 1457 VariableDataEntry.Name = VariableName; 1458 1187 1459 // 1188 1460 // Update public key database variable if need. 1189 1461 // 1190 KeyIndex = AddPubKeyInStore (PubKey );1462 KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry); 1191 1463 if (KeyIndex == 0) { 1192 return EFI_ SECURITY_VIOLATION;1464 return EFI_OUT_OF_RESOURCES; 1193 1465 } 1194 1466 } … … 1205 1477 will be ignored. 1206 1478 1207 @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST. 1208 @param[in] DataSize Size of Data buffer. 1209 @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended. 1210 @param[in] NewDataSize Size of NewData buffer. 1211 1212 @return Size of the merged buffer. 1479 @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST. 1480 @param[in] DataSize Size of Data buffer. 1481 @param[in] FreeBufSize Size of free data buffer 1482 @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended. 1483 @param[in] NewDataSize Size of NewData buffer. 1484 @param[out] MergedBufSize Size of the merged buffer 1485 1486 @return EFI_BUFFER_TOO_SMALL if input Data buffer overflowed 1213 1487 1214 1488 **/ 1215 UINTN 1489 EFI_STATUS 1216 1490 AppendSignatureList ( 1217 1491 IN OUT VOID *Data, 1218 1492 IN UINTN DataSize, 1493 IN UINTN FreeBufSize, 1219 1494 IN VOID *NewData, 1220 IN UINTN NewDataSize 1495 IN UINTN NewDataSize, 1496 OUT UINTN *MergedBufSize 1221 1497 ) 1222 1498 { … … 1277 1553 // 1278 1554 if (CopiedCount == 0) { 1555 if (FreeBufSize < sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize) { 1556 return EFI_BUFFER_TOO_SMALL; 1557 } 1558 1279 1559 // 1280 1560 // Copy EFI_SIGNATURE_LIST header for only once. 1281 1561 // 1562 1282 1563 CopyMem (Tail, NewCertList, sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize); 1283 1564 Tail = Tail + sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize; 1565 FreeBufSize -= sizeof (EFI_SIGNATURE_LIST) + NewCertList->SignatureHeaderSize; 1284 1566 } 1285 1567 1568 if (FreeBufSize < NewCertList->SignatureSize) { 1569 return EFI_BUFFER_TOO_SMALL; 1570 } 1286 1571 CopyMem (Tail, NewCert, NewCertList->SignatureSize); 1287 1572 Tail += NewCertList->SignatureSize; 1573 FreeBufSize -= NewCertList->SignatureSize; 1288 1574 CopiedCount++; 1289 1575 } … … 1305 1591 } 1306 1592 1307 return (Tail - (UINT8 *) Data); 1593 *MergedBufSize = (Tail - (UINT8 *) Data); 1594 return EFI_SUCCESS; 1308 1595 } 1309 1596 … … 1334 1621 return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour); 1335 1622 } else if (FirstTime->Minute != SecondTime->Minute) { 1336 return (BOOLEAN) (FirstTime->Minute < FirstTime->Minute);1623 return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute); 1337 1624 } 1338 1625 … … 1620 1907 // 1621 1908 NewCertDbSize = (UINT32) DataSize - CertNodeSize; 1622 NewCertDb = AllocateZeroPool (NewCertDbSize); 1623 if (NewCertDb == NULL) { 1624 return EFI_OUT_OF_RESOURCES; 1625 } 1909 NewCertDb = (UINT8*) mCertDbStore; 1626 1910 1627 1911 // … … 1660 1944 ); 1661 1945 1662 FreePool (NewCertDb);1663 1946 return Status; 1664 1947 } … … 1749 2032 NameSize = (UINT32) StrLen (VariableName); 1750 2033 CertNodeSize = sizeof (AUTH_CERT_DB_DATA) + (UINT32) CertDataSize + NameSize * sizeof (CHAR16); 1751 NewCertDbSize = (UINT32) DataSize + CertNodeSize; 1752 NewCertDb = AllocateZeroPool (NewCertDbSize); 1753 if (NewCertDb == NULL) { 2034 NewCertDbSize = (UINT32) DataSize + CertNodeSize; 2035 if (NewCertDbSize > mMaxCertDbSize) { 1754 2036 return EFI_OUT_OF_RESOURCES; 1755 2037 } 2038 NewCertDb = (UINT8*) mCertDbStore; 1756 2039 1757 2040 // … … 1800 2083 ); 1801 2084 1802 FreePool (NewCertDb);1803 2085 return Status; 1804 2086 } … … 1806 2088 /** 1807 2089 Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set 2090 2091 Caution: This function may receive untrusted input. 2092 This function may be invoked in SMM mode, and datasize and data are external input. 2093 This function will do basic validation, before parse the data. 2094 This function will parse the authentication carefully to avoid security issues, like 2095 buffer overflow, integer overflow. 1808 2096 1809 2097 @param[in] VariableName Name of Variable to be found. … … 1814 2102 @param[in] Variable The variable information which is used to keep track of variable usage. 1815 2103 @param[in] Attributes Attribute value of the variable. 1816 @param[in] AuthVarType Verify against PK or KEK database or private database.2104 @param[in] AuthVarType Verify against PK, KEK database, private database or certificate in data payload. 1817 2105 @param[out] VarDel Delete the variable or not. 1818 2106 … … 1871 2159 SignerCerts = NULL; 1872 2160 RootCert = NULL; 2161 CertsInCertDb = NULL; 1873 2162 1874 2163 // … … 1956 2245 if (AuthVarType == AuthVarTypePk) { 1957 2246 // 1958 // Get platform key from variable. 2247 // Verify that the signature has been made with the current Platform Key (no chaining for PK). 2248 // First, get signer's certificates from SignedData. 2249 // 2250 VerifyStatus = Pkcs7GetSigners ( 2251 SigData, 2252 SigDataSize, 2253 &SignerCerts, 2254 &CertStackSize, 2255 &RootCert, 2256 &RootCertSize 2257 ); 2258 if (!VerifyStatus) { 2259 goto Exit; 2260 } 2261 2262 // 2263 // Second, get the current platform key from variable. Check whether it's identical with signer's certificates 2264 // in SignedData. If not, return error immediately. 1959 2265 // 1960 2266 Status = FindVariable ( … … 1966 2272 ); 1967 2273 if (EFI_ERROR (Status)) { 1968 return Status;1969 }1970 2274 VerifyStatus = FALSE; 2275 goto Exit; 2276 } 1971 2277 CertList = (EFI_SIGNATURE_LIST *) GetVariableDataPtr (PkVariable.CurrPtr); 1972 2278 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); 1973 RootCert = Cert->SignatureData; 1974 RootCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1); 1975 2279 if ((RootCertSize != (CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1))) || 2280 (CompareMem (Cert->SignatureData, RootCert, RootCertSize) != 0)) { 2281 VerifyStatus = FALSE; 2282 goto Exit; 2283 } 1976 2284 1977 2285 // … … 2091 2399 // Delete signer's certificates when delete the common authenticated variable. 2092 2400 // 2093 if ((PayloadSize == 0) && (Variable->CurrPtr != NULL) ) {2401 if ((PayloadSize == 0) && (Variable->CurrPtr != NULL) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) { 2094 2402 Status = DeleteCertsFromDb (VariableName, VendorGuid); 2095 2403 if (EFI_ERROR (Status)) { … … 2097 2405 goto Exit; 2098 2406 } 2099 } else if (Variable->CurrPtr == NULL ) {2407 } else if (Variable->CurrPtr == NULL && PayloadSize != 0) { 2100 2408 // 2101 2409 // Insert signer's certificates when adding a new common authenticated variable. … … 2107 2415 } 2108 2416 } 2417 } else if (AuthVarType == AuthVarTypePayload) { 2418 CertList = (EFI_SIGNATURE_LIST *) PayloadPtr; 2419 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); 2420 RootCert = Cert->SignatureData; 2421 RootCertSize = CertList->SignatureSize - (sizeof (EFI_SIGNATURE_DATA) - 1); 2422 2423 // Verify Pkcs7 SignedData via Pkcs7Verify library. 2424 // 2425 VerifyStatus = Pkcs7Verify ( 2426 SigData, 2427 SigDataSize, 2428 RootCert, 2429 RootCertSize, 2430 NewData, 2431 NewDataSize 2432 ); 2109 2433 } else { 2110 2434 return EFI_SECURITY_VIOLATION; … … 2113 2437 Exit: 2114 2438 2115 if (AuthVarType == AuthVarTypeP riv) {2439 if (AuthVarType == AuthVarTypePk || AuthVarType == AuthVarTypePriv) { 2116 2440 Pkcs7FreeSigners (RootCert); 2117 2441 Pkcs7FreeSigners (SignerCerts); -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
r48674 r58459 3 3 internal structure and functions used by AuthService module. 4 4 5 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5 Caution: This module requires additional review when modified. 6 This driver will have external input - variable data. It may be input in SMM mode. 7 This external input must be validated carefully to avoid security issue like 8 buffer overflow, integer overflow. 9 Variable attribute should also be checked to avoid authentication bypass. 10 The whole SMM authentication variable design relies on the integrity of flash part and SMM. 11 which is assumed to be protected by platform. All variable code and metadata in flash/SMM Memory 12 may not be modified without authorization. If platform fails to protect these resources, 13 the authentication service provided in this driver will be broken, and the behavior is undefined. 14 15 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 16 This program and the accompanying materials 7 17 are licensed and made available under the terms and conditions of the BSD License … … 37 47 /// 38 48 #define AUTHVAR_KEYDB_NAME L"AuthVarKeyDatabase" 39 #define AUTHVAR_KEYDB_NAME_SIZE 38 40 41 /// 42 /// Max size of public key database, restricted by max individal EFI varible size, exclude variable header and name size.43 /// 44 #define MAX_KEYDB_SIZE (FixedPcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - AUTHVAR_KEYDB_NAME_SIZE) 45 #define MAX_KEY_NUM (MAX_KEYDB_SIZE / EFI_CERT_TYPE_RSA2048_SIZE)49 50 /// 51 /// "certdb" variable stores the signer's certificates for non PK/KEK/DB/DBX 52 /// variables with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set. 53 /// 54 /// 55 #define EFI_CERT_DB_NAME L"certdb" 46 56 47 57 /// … … 60 70 AuthVarTypePk, 61 71 AuthVarTypeKek, 62 AuthVarTypePriv 72 AuthVarTypePriv, 73 AuthVarTypePayload 63 74 } AUTHVAR_TYPE; 64 75 … … 77 88 Process variable with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS/EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set. 78 89 90 Caution: This function may receive untrusted input. 91 This function may be invoked in SMM mode, and datasize and data are external input. 92 This function will do basic validation, before parse the data. 93 This function will parse the authentication carefully to avoid security issues, like 94 buffer overflow, integer overflow. 95 This function will check attribute carefully to avoid authentication bypass. 96 79 97 @param[in] VariableName Name of Variable to be found. 80 98 @param[in] VendorGuid Variable vendor GUID. … … 162 180 /** 163 181 Process variable with platform key for verification. 182 183 Caution: This function may receive untrusted input. 184 This function may be invoked in SMM mode, and datasize and data are external input. 185 This function will do basic validation, before parse the data. 186 This function will parse the authentication carefully to avoid security issues, like 187 buffer overflow, integer overflow. 188 This function will check attribute carefully to avoid authentication bypass. 164 189 165 190 @param[in] VariableName Name of Variable to be found. … … 192 217 Process variable with key exchange key for verification. 193 218 219 Caution: This function may receive untrusted input. 220 This function may be invoked in SMM mode, and datasize and data are external input. 221 This function will do basic validation, before parse the data. 222 This function will parse the authentication carefully to avoid security issues, like 223 buffer overflow, integer overflow. 224 This function will check attribute carefully to avoid authentication bypass. 225 194 226 @param[in] VariableName Name of Variable to be found. 195 227 @param[in] VendorGuid Variable vendor GUID. … … 221 253 will be ignored. 222 254 223 @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST. 224 @param[in] DataSize Size of Data buffer. 225 @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended. 226 @param[in] NewDataSize Size of NewData buffer. 227 228 @return Size of the merged buffer. 229 230 **/ 231 UINTN 255 @param[in, out] Data Pointer to original EFI_SIGNATURE_LIST. 256 @param[in] DataSize Size of Data buffer. 257 @param[in] FreeBufSize Size of free data buffer 258 @param[in] NewData Pointer to new EFI_SIGNATURE_LIST to be appended. 259 @param[in] NewDataSize Size of NewData buffer. 260 @param[out] MergedBufSize Size of the merged buffer 261 262 @return EFI_BUFFER_TOO_SMALL if input Data buffer overflowed 263 264 **/ 265 EFI_STATUS 232 266 AppendSignatureList ( 233 267 IN OUT VOID *Data, 234 268 IN UINTN DataSize, 269 IN UINTN FreeBufSize, 235 270 IN VOID *NewData, 236 IN UINTN NewDataSize 271 IN UINTN NewDataSize, 272 OUT UINTN *MergedBufSize 237 273 ); 238 274 … … 257 293 /** 258 294 Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set 295 296 Caution: This function may receive untrusted input. 297 This function may be invoked in SMM mode, and datasize and data are external input. 298 This function will do basic validation, before parse the data. 299 This function will parse the authentication carefully to avoid security issues, like 300 buffer overflow, integer overflow. 259 301 260 302 @param[in] VariableName Name of Variable to be found. … … 288 330 ); 289 331 290 extern UINT8 mPubKeyStore[MAX_KEYDB_SIZE]; 332 extern UINT8 *mPubKeyStore; 333 extern UINT8 *mCertDbStore; 291 334 extern UINT32 mPubKeyNumber; 292 335 extern VOID *mHashCtx; 293 extern VOID *mStorageArea;294 336 extern UINT8 *mSerializationRuntimeBuffer; 295 337 -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c
r48674 r58459 3 3 (Fault Tolerant Write) protocol. 4 4 5 Copyright (c) 2009 - 201 0, Intel Corporation. All rights reserved.<BR>5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 6 This program and the accompanying materials 7 7 are licensed and made available under the terms and conditions of the BSD License … … 49 49 *Lba = (EFI_LBA) (-1); 50 50 *Offset = 0; 51 51 Fvb = NULL; 52 52 53 // 53 54 // Get the proper FVB protocol. … … 99 100 100 101 @param VariableBase Base address of variable to write 101 @param Buffer Point to the data buffer. 102 @param BufferSize The number of bytes of the data Buffer. 102 @param VariableBuffer Point to the variable data buffer. 103 103 104 104 @retval EFI_SUCCESS The function completed successfully. … … 110 110 FtwVariableSpace ( 111 111 IN EFI_PHYSICAL_ADDRESS VariableBase, 112 IN UINT8 *Buffer, 113 IN UINTN BufferSize 112 IN VARIABLE_STORE_HEADER *VariableBuffer 114 113 ) 115 114 { … … 118 117 EFI_LBA VarLba; 119 118 UINTN VarOffset; 120 UINT8 *FtwBuffer;121 119 UINTN FtwBufferSize; 122 120 EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; … … 143 141 return EFI_ABORTED; 144 142 } 145 // 146 // Prepare for the variable data. 147 // 143 148 144 FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size; 149 FtwBuffer = AllocatePool (FtwBufferSize); 150 if (FtwBuffer == NULL) { 151 return EFI_OUT_OF_RESOURCES; 152 } 153 154 SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff); 155 CopyMem (FtwBuffer, Buffer, BufferSize); 145 ASSERT (FtwBufferSize == VariableBuffer->Size); 156 146 157 147 // … … 165 155 NULL, // PrivateData NULL 166 156 FvbHandle, // Fvb Handle 167 FtwBuffer// write buffer157 (VOID *) VariableBuffer // write buffer 168 158 ); 169 159 170 FreePool (FtwBuffer);171 160 return Status; 172 161 } -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
r48674 r58459 1 1 /** @file 2 The common variable operation routines shared by DXE_R INTIME variable2 The common variable operation routines shared by DXE_RUNTIME variable 3 3 module and DXE_SMM variable module. 4 4 5 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 5 Caution: This module requires additional review when modified. 6 This driver will have external input - variable data. They may be input in SMM mode. 7 This external input must be validated carefully to avoid security issue like 8 buffer overflow, integer overflow. 9 10 VariableServiceGetNextVariableName () and VariableServiceQueryVariableInfo() are external API. 11 They need check input parameter. 12 13 VariableServiceGetVariable() and VariableServiceSetVariable() are external API 14 to receive datasize and data buffer. The size should be checked carefully. 15 16 VariableServiceSetVariable() should also check authenticate data to avoid buffer overflow, 17 integer overflow. It should also check attribute to avoid authentication bypass. 18 19 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 20 This program and the accompanying materials 7 21 are licensed and made available under the terms and conditions of the BSD License … … 22 36 /// Define a memory cache that improves the search performance for a variable. 23 37 /// 24 VARIABLE_STORE_HEADER *mNvVariableCache = NULL;38 VARIABLE_STORE_HEADER *mNvVariableCache = NULL; 25 39 26 40 /// 27 41 /// The memory entry used for variable statistics data. 28 42 /// 29 VARIABLE_INFO_ENTRY *gVariableInfo = NULL; 30 43 VARIABLE_INFO_ENTRY *gVariableInfo = NULL; 44 45 /// 46 /// The list to store the variables which cannot be set after the EFI_END_OF_DXE_EVENT_GROUP_GUID 47 /// or EVT_GROUP_READY_TO_BOOT event. 48 /// 49 LIST_ENTRY mLockedVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mLockedVariableList); 50 51 /// 52 /// The flag to indicate whether the platform has left the DXE phase of execution. 53 /// 54 BOOLEAN mEndOfDxe = FALSE; 55 56 /// 57 /// The flag to indicate whether the variable storage locking is enabled. 58 /// 59 BOOLEAN mEnableLocking = TRUE; 60 61 // 62 // To prevent name collisions with possible future globally defined variables, 63 // other internal firmware data variables that are not defined here must be 64 // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or 65 // any other GUID defined by the UEFI Specification. Implementations must 66 // only permit the creation of variables with a UEFI Specification-defined 67 // VendorGuid when these variables are documented in the UEFI Specification. 68 // 69 GLOBAL_VARIABLE_ENTRY mGlobalVariableList[] = { 70 {EFI_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 71 {EFI_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 72 {EFI_TIME_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 73 {EFI_PLATFORM_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 74 {EFI_PLATFORM_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 75 {EFI_CON_IN_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 76 {EFI_CON_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 77 {EFI_ERR_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 78 {EFI_CON_IN_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 79 {EFI_CON_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 80 {EFI_ERR_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 81 {EFI_BOOT_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 82 {EFI_BOOT_NEXT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 83 {EFI_BOOT_CURRENT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 84 {EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 85 {EFI_DRIVER_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 86 {EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 87 {EFI_SETUP_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 88 {EFI_KEY_EXCHANGE_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT}, 89 {EFI_PLATFORM_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT}, 90 {EFI_SIGNATURE_SUPPORT_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 91 {EFI_SECURE_BOOT_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 92 {EFI_KEK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 93 {EFI_PK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 94 {EFI_DB_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 95 {EFI_DBX_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 96 {EFI_DBT_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 97 {EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 98 {EFI_OS_INDICATIONS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, 99 {EFI_VENDOR_KEYS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, 100 }; 101 GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = { 102 {L"Boot####", VARIABLE_ATTRIBUTE_NV_BS_RT}, 103 {L"Driver####", VARIABLE_ATTRIBUTE_NV_BS_RT}, 104 {L"Key####", VARIABLE_ATTRIBUTE_NV_BS_RT}, 105 }; 106 107 /** 108 109 SecureBoot Hook for auth variable update. 110 111 @param[in] VariableName Name of Variable to be found. 112 @param[in] VendorGuid Variable vendor GUID. 113 **/ 114 VOID 115 EFIAPI 116 SecureBootHook ( 117 IN CHAR16 *VariableName, 118 IN EFI_GUID *VendorGuid 119 ); 31 120 32 121 /** … … 130 219 This code checks if variable header is valid or not. 131 220 132 @param Variable Pointer to the Variable Header. 133 134 @retval TRUE Variable header is valid. 135 @retval FALSE Variable header is not valid. 221 @param Variable Pointer to the Variable Header. 222 @param VariableStoreEnd Pointer to the Variable Store End. 223 224 @retval TRUE Variable header is valid. 225 @retval FALSE Variable header is not valid. 136 226 137 227 **/ 138 228 BOOLEAN 139 229 IsValidVariableHeader ( 140 IN VARIABLE_HEADER *Variable 230 IN VARIABLE_HEADER *Variable, 231 IN VARIABLE_HEADER *VariableStoreEnd 141 232 ) 142 233 { 143 if (Variable == NULL || Variable->StartId != VARIABLE_DATA) { 234 if ((Variable == NULL) || (Variable >= VariableStoreEnd) || (Variable->StartId != VARIABLE_DATA)) { 235 // 236 // Variable is NULL or has reached the end of variable store, 237 // or the StartId is not correct. 238 // 144 239 return FALSE; 145 240 } … … 441 536 UINTN Value; 442 537 443 if (!IsValidVariableHeader (Variable)) {444 return NULL;445 }446 447 538 Value = (UINTN) GetVariableDataPtr (Variable); 448 539 Value += DataSizeOfVariable (Variable); … … 498 589 } 499 590 500 501 591 /** 502 592 593 Check the PubKeyIndex is a valid key or not. 594 595 This function will iterate the NV storage to see if this PubKeyIndex is still referenced 596 by any valid count-based auth variabe. 597 598 @param[in] PubKeyIndex Index of the public key in public key store. 599 600 @retval TRUE The PubKeyIndex is still in use. 601 @retval FALSE The PubKeyIndex is not referenced by any count-based auth variabe. 602 603 **/ 604 BOOLEAN 605 IsValidPubKeyIndex ( 606 IN UINT32 PubKeyIndex 607 ) 608 { 609 VARIABLE_HEADER *Variable; 610 VARIABLE_HEADER *VariableStoreEnd; 611 612 if (PubKeyIndex > mPubKeyNumber) { 613 return FALSE; 614 } 615 616 Variable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase); 617 VariableStoreEnd = GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase); 618 619 while (IsValidVariableHeader (Variable, VariableStoreEnd)) { 620 if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && 621 Variable->PubKeyIndex == PubKeyIndex) { 622 return TRUE; 623 } 624 Variable = GetNextVariablePtr (Variable); 625 } 626 627 return FALSE; 628 } 629 630 /** 631 632 Get the number of valid public key in PubKeyStore. 633 634 @param[in] PubKeyNumber Number of the public key in public key store. 635 636 @return Number of valid public key in PubKeyStore. 637 638 **/ 639 UINT32 640 GetValidPubKeyNumber ( 641 IN UINT32 PubKeyNumber 642 ) 643 { 644 UINT32 PubKeyIndex; 645 UINT32 Counter; 646 647 Counter = 0; 648 649 for (PubKeyIndex = 1; PubKeyIndex <= PubKeyNumber; PubKeyIndex++) { 650 if (IsValidPubKeyIndex (PubKeyIndex)) { 651 Counter++; 652 } 653 } 654 655 return Counter; 656 } 657 658 /** 659 660 Filter the useless key in public key store. 661 662 This function will find out all valid public keys in public key database, save them in new allocated 663 buffer NewPubKeyStore, and give the new PubKeyIndex. The caller is responsible for freeing buffer 664 NewPubKeyIndex and NewPubKeyStore with FreePool(). 665 666 @param[in] PubKeyStore Point to the public key database. 667 @param[in] PubKeyNumber Number of the public key in PubKeyStore. 668 @param[out] NewPubKeyIndex Point to an array of new PubKeyIndex corresponds to NewPubKeyStore. 669 @param[out] NewPubKeyStore Saved all valid public keys in PubKeyStore. 670 @param[out] NewPubKeySize Buffer size of the NewPubKeyStore. 671 672 @retval EFI_SUCCESS Trim operation is complete successfully. 673 @retval EFI_OUT_OF_RESOURCES No enough memory resources, or no useless key in PubKeyStore. 674 675 **/ 676 EFI_STATUS 677 PubKeyStoreFilter ( 678 IN UINT8 *PubKeyStore, 679 IN UINT32 PubKeyNumber, 680 OUT UINT32 **NewPubKeyIndex, 681 OUT UINT8 **NewPubKeyStore, 682 OUT UINT32 *NewPubKeySize 683 ) 684 { 685 UINT32 PubKeyIndex; 686 UINT32 CopiedKey; 687 UINT32 NewPubKeyNumber; 688 689 NewPubKeyNumber = GetValidPubKeyNumber (PubKeyNumber); 690 if (NewPubKeyNumber == PubKeyNumber) { 691 return EFI_OUT_OF_RESOURCES; 692 } 693 694 if (NewPubKeyNumber != 0) { 695 *NewPubKeySize = NewPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE; 696 } else { 697 *NewPubKeySize = sizeof (UINT8); 698 } 699 700 *NewPubKeyStore = AllocatePool (*NewPubKeySize); 701 if (*NewPubKeyStore == NULL) { 702 return EFI_OUT_OF_RESOURCES; 703 } 704 705 *NewPubKeyIndex = AllocateZeroPool ((PubKeyNumber + 1) * sizeof (UINT32)); 706 if (*NewPubKeyIndex == NULL) { 707 FreePool (*NewPubKeyStore); 708 *NewPubKeyStore = NULL; 709 return EFI_OUT_OF_RESOURCES; 710 } 711 712 CopiedKey = 0; 713 for (PubKeyIndex = 1; PubKeyIndex <= PubKeyNumber; PubKeyIndex++) { 714 if (IsValidPubKeyIndex (PubKeyIndex)) { 715 CopyMem ( 716 *NewPubKeyStore + CopiedKey * EFI_CERT_TYPE_RSA2048_SIZE, 717 PubKeyStore + (PubKeyIndex - 1) * EFI_CERT_TYPE_RSA2048_SIZE, 718 EFI_CERT_TYPE_RSA2048_SIZE 719 ); 720 (*NewPubKeyIndex)[PubKeyIndex] = ++CopiedKey; 721 } 722 } 723 return EFI_SUCCESS; 724 } 725 726 /** 727 503 728 Variable store garbage collection and reclaim operation. 504 729 505 @param VariableBase Base address of variable store. 506 @param LastVariableOffset Offset of last variable. 507 @param IsVolatile The variable store is volatile or not; 508 if it is non-volatile, need FTW. 509 @param UpdatingVariable Pointer to updating variable. 510 511 @return EFI_OUT_OF_RESOURCES 512 @return EFI_SUCCESS 513 @return Others 730 If ReclaimPubKeyStore is FALSE, reclaim variable space by deleting the obsoleted varaibles. 731 If ReclaimPubKeyStore is TRUE, reclaim invalid key in public key database and update the PubKeyIndex 732 for all the count-based authenticate variable in NV storage. 733 734 @param[in] VariableBase Base address of variable store. 735 @param[out] LastVariableOffset Offset of last variable. 736 @param[in] IsVolatile The variable store is volatile or not; 737 if it is non-volatile, need FTW. 738 @param[in, out] UpdatingPtrTrack Pointer to updating variable pointer track structure. 739 @param[in] NewVariable Pointer to new variable. 740 @param[in] NewVariableSize New variable size. 741 @param[in] ReclaimPubKeyStore Reclaim for public key database or not. 742 743 @return EFI_SUCCESS Reclaim operation has finished successfully. 744 @return EFI_OUT_OF_RESOURCES No enough memory resources or variable space. 745 @return EFI_DEVICE_ERROR The public key database doesn't exist. 746 @return Others Unexpect error happened during reclaim operation. 514 747 515 748 **/ 516 749 EFI_STATUS 517 750 Reclaim ( 518 IN EFI_PHYSICAL_ADDRESS VariableBase, 519 OUT UINTN *LastVariableOffset, 520 IN BOOLEAN IsVolatile, 521 IN VARIABLE_HEADER *UpdatingVariable 751 IN EFI_PHYSICAL_ADDRESS VariableBase, 752 OUT UINTN *LastVariableOffset, 753 IN BOOLEAN IsVolatile, 754 IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack, 755 IN VARIABLE_HEADER *NewVariable, 756 IN UINTN NewVariableSize, 757 IN BOOLEAN ReclaimPubKeyStore 522 758 ) 523 759 { … … 530 766 UINTN MaximumBufferSize; 531 767 UINTN VariableSize; 532 UINTN VariableNameSize;533 UINTN UpdatingVariableNameSize;534 768 UINTN NameSize; 535 769 UINT8 *CurrPtr; … … 538 772 BOOLEAN FoundAdded; 539 773 EFI_STATUS Status; 540 CHAR16 *VariableNamePtr; 541 CHAR16 *UpdatingVariableNamePtr; 774 UINTN CommonVariableTotalSize; 775 UINTN HwErrVariableTotalSize; 776 UINT32 *NewPubKeyIndex; 777 UINT8 *NewPubKeyStore; 778 UINT32 NewPubKeySize; 779 VARIABLE_HEADER *PubKeyHeader; 780 VARIABLE_HEADER *UpdatingVariable; 781 VARIABLE_HEADER *UpdatingInDeletedTransition; 782 783 UpdatingVariable = NULL; 784 UpdatingInDeletedTransition = NULL; 785 if (UpdatingPtrTrack != NULL) { 786 UpdatingVariable = UpdatingPtrTrack->CurrPtr; 787 UpdatingInDeletedTransition = UpdatingPtrTrack->InDeletedTransitionPtr; 788 } 542 789 543 790 VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase); 544 // 545 // Recalculate the total size of Common/HwErr type variables in non-volatile area. 546 // 547 if (!IsVolatile) { 548 mVariableModuleGlobal->CommonVariableTotalSize = 0; 549 mVariableModuleGlobal->HwErrVariableTotalSize = 0; 550 } 551 552 // 553 // Start Pointers for the variable. 554 // 555 Variable = GetStartPointer (VariableStoreHeader); 556 MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER); 557 558 while (IsValidVariableHeader (Variable)) { 559 NextVariable = GetNextVariablePtr (Variable); 560 if (Variable->State == VAR_ADDED || 561 Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED) 562 ) { 563 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 564 MaximumBufferSize += VariableSize; 565 } 566 567 Variable = NextVariable; 568 } 569 570 // 571 // Reserve the 1 Bytes with Oxff to identify the 572 // end of the variable buffer. 573 // 574 MaximumBufferSize += 1; 575 ValidBuffer = AllocatePool (MaximumBufferSize); 576 if (ValidBuffer == NULL) { 577 return EFI_OUT_OF_RESOURCES; 791 792 CommonVariableTotalSize = 0; 793 HwErrVariableTotalSize = 0; 794 NewPubKeyIndex = NULL; 795 NewPubKeyStore = NULL; 796 NewPubKeySize = 0; 797 PubKeyHeader = NULL; 798 799 if (IsVolatile) { 800 // 801 // Start Pointers for the variable. 802 // 803 Variable = GetStartPointer (VariableStoreHeader); 804 MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER); 805 806 while (IsValidVariableHeader (Variable, GetEndPointer (VariableStoreHeader))) { 807 NextVariable = GetNextVariablePtr (Variable); 808 if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && 809 Variable != UpdatingVariable && 810 Variable != UpdatingInDeletedTransition 811 ) { 812 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 813 MaximumBufferSize += VariableSize; 814 } 815 816 Variable = NextVariable; 817 } 818 819 if (NewVariable != NULL) { 820 // 821 // Add the new variable size. 822 // 823 MaximumBufferSize += NewVariableSize; 824 } 825 826 // 827 // Reserve the 1 Bytes with Oxff to identify the 828 // end of the variable buffer. 829 // 830 MaximumBufferSize += 1; 831 ValidBuffer = AllocatePool (MaximumBufferSize); 832 if (ValidBuffer == NULL) { 833 return EFI_OUT_OF_RESOURCES; 834 } 835 } else { 836 // 837 // For NV variable reclaim, don't allocate pool here and just use mNvVariableCache 838 // as the buffer to reduce SMRAM consumption for SMM variable driver. 839 // 840 MaximumBufferSize = mNvVariableCache->Size; 841 ValidBuffer = (UINT8 *) mNvVariableCache; 578 842 } 579 843 … … 586 850 CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer); 587 851 588 // 589 // Reinstall all ADDED variables as long as they are not identical to Updating Variable. 590 // 591 Variable = GetStartPointer (VariableStoreHeader); 592 while (IsValidVariableHeader (Variable)) { 593 NextVariable = GetNextVariablePtr (Variable); 594 if (Variable->State == VAR_ADDED) { 595 if (UpdatingVariable != NULL) { 596 if (UpdatingVariable == Variable) { 852 if (ReclaimPubKeyStore) { 853 ASSERT (IsVolatile == FALSE); 854 // 855 // Trim the PubKeyStore and get new PubKeyIndex. 856 // 857 Status = PubKeyStoreFilter ( 858 mPubKeyStore, 859 mPubKeyNumber, 860 &NewPubKeyIndex, 861 &NewPubKeyStore, 862 &NewPubKeySize 863 ); 864 if (EFI_ERROR (Status)) { 865 goto Done; 866 } 867 ASSERT ((NewPubKeyIndex != NULL) && (NewPubKeyStore != NULL)); 868 869 // 870 // Refresh the PubKeyIndex for all valid variables (ADDED and IN_DELETED_TRANSITION). 871 // 872 Variable = GetStartPointer (VariableStoreHeader); 873 while (IsValidVariableHeader (Variable, GetEndPointer (VariableStoreHeader))) { 874 NextVariable = GetNextVariablePtr (Variable); 875 if (Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 876 if ((StrCmp (GetVariableNamePtr (Variable), AUTHVAR_KEYDB_NAME) == 0) && 877 (CompareGuid (&Variable->VendorGuid, &gEfiAuthenticatedVariableGuid))) { 878 // 879 // Skip the public key database, it will be reinstalled later. 880 // 881 PubKeyHeader = Variable; 597 882 Variable = NextVariable; 598 883 continue; 599 884 } 600 601 VariableNameSize = NameSizeOfVariable(Variable); 602 UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable); 603 604 VariableNamePtr = GetVariableNamePtr (Variable); 605 UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable); 606 if (CompareGuid (&Variable->VendorGuid, &UpdatingVariable->VendorGuid) && 607 VariableNameSize == UpdatingVariableNameSize && 608 CompareMem (VariableNamePtr, UpdatingVariableNamePtr, VariableNameSize) == 0 ) { 609 Variable = NextVariable; 610 continue; 885 886 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 887 CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); 888 ((VARIABLE_HEADER*) CurrPtr)->PubKeyIndex = NewPubKeyIndex[Variable->PubKeyIndex]; 889 CurrPtr += VariableSize; 890 if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 891 HwErrVariableTotalSize += VariableSize; 892 } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 893 CommonVariableTotalSize += VariableSize; 611 894 } 612 895 } 613 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 614 CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); 615 CurrPtr += VariableSize; 616 if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 617 mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; 618 } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 619 mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; 620 } 621 } 622 Variable = NextVariable; 623 } 624 625 // 626 // Reinstall the variable being updated if it is not NULL. 627 // 628 if (UpdatingVariable != NULL) { 629 VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable; 630 CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize); 631 CurrPtr += VariableSize; 632 if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 633 mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; 634 } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 635 mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; 636 } 637 } 638 639 // 640 // Reinstall all in delete transition variables. 641 // 642 Variable = GetStartPointer (VariableStoreHeader); 643 while (IsValidVariableHeader (Variable)) { 644 NextVariable = GetNextVariablePtr (Variable); 645 if (Variable != UpdatingVariable && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 646 647 // 648 // Buffer has cached all ADDED variable. 649 // Per IN_DELETED variable, we have to guarantee that 650 // no ADDED one in previous buffer. 651 // 652 653 FoundAdded = FALSE; 654 AddedVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer); 655 while (IsValidVariableHeader (AddedVariable)) { 656 NextAddedVariable = GetNextVariablePtr (AddedVariable); 657 NameSize = NameSizeOfVariable (AddedVariable); 658 if (CompareGuid (&AddedVariable->VendorGuid, &Variable->VendorGuid) && 659 NameSize == NameSizeOfVariable (Variable) 660 ) { 661 Point0 = (VOID *) GetVariableNamePtr (AddedVariable); 662 Point1 = (VOID *) GetVariableNamePtr (Variable); 663 if (CompareMem (Point0, Point1, NameSizeOfVariable (AddedVariable)) == 0) { 664 FoundAdded = TRUE; 665 break; 896 Variable = NextVariable; 897 } 898 899 // 900 // Reinstall the new public key database. 901 // 902 ASSERT (PubKeyHeader != NULL); 903 if (PubKeyHeader == NULL) { 904 Status = EFI_DEVICE_ERROR; 905 goto Done; 906 } 907 CopyMem (CurrPtr, (UINT8*) PubKeyHeader, sizeof (VARIABLE_HEADER)); 908 Variable = (VARIABLE_HEADER*) CurrPtr; 909 Variable->DataSize = NewPubKeySize; 910 StrCpy (GetVariableNamePtr (Variable), GetVariableNamePtr (PubKeyHeader)); 911 CopyMem (GetVariableDataPtr (Variable), NewPubKeyStore, NewPubKeySize); 912 CurrPtr = (UINT8*) GetNextVariablePtr (Variable); 913 CommonVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable; 914 } else { 915 // 916 // Reinstall all ADDED variables as long as they are not identical to Updating Variable. 917 // 918 Variable = GetStartPointer (VariableStoreHeader); 919 while (IsValidVariableHeader (Variable, GetEndPointer (VariableStoreHeader))) { 920 NextVariable = GetNextVariablePtr (Variable); 921 if (Variable != UpdatingVariable && Variable->State == VAR_ADDED) { 922 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 923 CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); 924 CurrPtr += VariableSize; 925 if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 926 HwErrVariableTotalSize += VariableSize; 927 } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 928 CommonVariableTotalSize += VariableSize; 929 } 930 } 931 Variable = NextVariable; 932 } 933 934 // 935 // Reinstall all in delete transition variables. 936 // 937 Variable = GetStartPointer (VariableStoreHeader); 938 while (IsValidVariableHeader (Variable, GetEndPointer (VariableStoreHeader))) { 939 NextVariable = GetNextVariablePtr (Variable); 940 if (Variable != UpdatingVariable && Variable != UpdatingInDeletedTransition && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 941 942 // 943 // Buffer has cached all ADDED variable. 944 // Per IN_DELETED variable, we have to guarantee that 945 // no ADDED one in previous buffer. 946 // 947 948 FoundAdded = FALSE; 949 AddedVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer); 950 while (IsValidVariableHeader (AddedVariable, GetEndPointer ((VARIABLE_STORE_HEADER *) ValidBuffer))) { 951 NextAddedVariable = GetNextVariablePtr (AddedVariable); 952 NameSize = NameSizeOfVariable (AddedVariable); 953 if (CompareGuid (&AddedVariable->VendorGuid, &Variable->VendorGuid) && 954 NameSize == NameSizeOfVariable (Variable) 955 ) { 956 Point0 = (VOID *) GetVariableNamePtr (AddedVariable); 957 Point1 = (VOID *) GetVariableNamePtr (Variable); 958 if (CompareMem (Point0, Point1, NameSize) == 0) { 959 FoundAdded = TRUE; 960 break; 961 } 962 } 963 AddedVariable = NextAddedVariable; 964 } 965 if (!FoundAdded) { 966 // 967 // Promote VAR_IN_DELETED_TRANSITION to VAR_ADDED. 968 // 969 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 970 CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); 971 ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED; 972 CurrPtr += VariableSize; 973 if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 974 HwErrVariableTotalSize += VariableSize; 975 } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 976 CommonVariableTotalSize += VariableSize; 666 977 } 667 978 } 668 AddedVariable = NextAddedVariable; 669 } 670 if (!FoundAdded) { 671 // 672 // Promote VAR_IN_DELETED_TRANSITION to VAR_ADDED. 673 // 674 VariableSize = (UINTN) NextVariable - (UINTN) Variable; 675 CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize); 676 ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED; 677 CurrPtr += VariableSize; 678 if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 679 mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; 680 } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 681 mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; 979 } 980 981 Variable = NextVariable; 982 } 983 984 // 985 // Install the new variable if it is not NULL. 986 // 987 if (NewVariable != NULL) { 988 if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > VariableStoreHeader->Size) { 989 // 990 // No enough space to store the new variable. 991 // 992 Status = EFI_OUT_OF_RESOURCES; 993 goto Done; 994 } 995 if (!IsVolatile) { 996 if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 997 HwErrVariableTotalSize += NewVariableSize; 998 } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 999 CommonVariableTotalSize += NewVariableSize; 682 1000 } 683 } 684 } 685 686 Variable = NextVariable; 1001 if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) || 1002 (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) { 1003 // 1004 // No enough space to store the new variable by NV or NV+HR attribute. 1005 // 1006 Status = EFI_OUT_OF_RESOURCES; 1007 goto Done; 1008 } 1009 } 1010 1011 CopyMem (CurrPtr, (UINT8 *) NewVariable, NewVariableSize); 1012 ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED; 1013 if (UpdatingVariable != NULL) { 1014 UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer))); 1015 UpdatingPtrTrack->InDeletedTransitionPtr = NULL; 1016 } 1017 CurrPtr += NewVariableSize; 1018 } 687 1019 } 688 1020 … … 692 1024 // 693 1025 SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); 694 CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)); 1026 CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer)); 1027 *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); 695 1028 Status = EFI_SUCCESS; 696 1029 } else { … … 700 1033 Status = FtwVariableSpace ( 701 1034 VariableBase, 702 ValidBuffer, 703 (UINTN) (CurrPtr - (UINT8 *) ValidBuffer) 1035 (VARIABLE_STORE_HEADER *) ValidBuffer 704 1036 ); 705 CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size); 706 } 707 if (!EFI_ERROR (Status)) { 708 *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer); 1037 if (!EFI_ERROR (Status)) { 1038 *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); 1039 mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; 1040 mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; 1041 } else { 1042 NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); 1043 while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) { 1044 VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); 1045 if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 1046 mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); 1047 } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 1048 mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); 1049 } 1050 1051 NextVariable = GetNextVariablePtr (NextVariable); 1052 } 1053 *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; 1054 } 1055 } 1056 1057 Done: 1058 if (IsVolatile) { 1059 FreePool (ValidBuffer); 709 1060 } else { 710 *LastVariableOffset = 0; 711 } 712 713 FreePool (ValidBuffer); 1061 // 1062 // For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back. 1063 // 1064 CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size); 1065 1066 if (NewPubKeyStore != NULL) { 1067 FreePool (NewPubKeyStore); 1068 } 1069 1070 if (NewPubKeyIndex != NULL) { 1071 FreePool (NewPubKeyIndex); 1072 } 1073 } 714 1074 715 1075 return Status; … … 739 1099 VOID *Point; 740 1100 1101 PtrTrack->InDeletedTransitionPtr = NULL; 1102 741 1103 // 742 1104 // Find the variable by walk through HOB, volatile and non-volatile variable store. … … 745 1107 746 1108 for ( PtrTrack->CurrPtr = PtrTrack->StartPtr 747 ; (PtrTrack->CurrPtr < PtrTrack->EndPtr) && IsValidVariableHeader (PtrTrack->CurrPtr)1109 ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr) 748 1110 ; PtrTrack->CurrPtr = GetNextVariablePtr (PtrTrack->CurrPtr) 749 1111 ) { … … 756 1118 InDeletedVariable = PtrTrack->CurrPtr; 757 1119 } else { 1120 PtrTrack->InDeletedTransitionPtr = InDeletedVariable; 758 1121 return EFI_SUCCESS; 759 1122 } … … 767 1130 InDeletedVariable = PtrTrack->CurrPtr; 768 1131 } else { 1132 PtrTrack->InDeletedTransitionPtr = InDeletedVariable; 769 1133 return EFI_SUCCESS; 770 1134 } … … 1151 1515 1152 1516 /** 1517 This function is to check if the remaining variable space is enough to set 1518 all Variables from argument list successfully. The purpose of the check 1519 is to keep the consistency of the Variables to be in variable storage. 1520 1521 Note: Variables are assumed to be in same storage. 1522 The set sequence of Variables will be same with the sequence of VariableEntry from argument list, 1523 so follow the argument sequence to check the Variables. 1524 1525 @param[in] Attributes Variable attributes for Variable entries. 1526 @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. 1527 A NULL terminates the list. The VariableSize of 1528 VARIABLE_ENTRY_CONSISTENCY is the variable data size as input. 1529 It will be changed to variable total size as output. 1530 1531 @retval TRUE Have enough variable space to set the Variables successfully. 1532 @retval FALSE No enough variable space to set the Variables successfully. 1533 1534 **/ 1535 BOOLEAN 1536 EFIAPI 1537 CheckRemainingSpaceForConsistency ( 1538 IN UINT32 Attributes, 1539 ... 1540 ) 1541 { 1542 EFI_STATUS Status; 1543 VA_LIST Args; 1544 VARIABLE_ENTRY_CONSISTENCY *VariableEntry; 1545 UINT64 MaximumVariableStorageSize; 1546 UINT64 RemainingVariableStorageSize; 1547 UINT64 MaximumVariableSize; 1548 UINTN TotalNeededSize; 1549 UINTN OriginalVarSize; 1550 VARIABLE_STORE_HEADER *VariableStoreHeader; 1551 VARIABLE_POINTER_TRACK VariablePtrTrack; 1552 VARIABLE_HEADER *NextVariable; 1553 UINTN VarNameSize; 1554 UINTN VarDataSize; 1555 1556 // 1557 // Non-Volatile related. 1558 // 1559 VariableStoreHeader = mNvVariableCache; 1560 1561 Status = VariableServiceQueryVariableInfoInternal ( 1562 Attributes, 1563 &MaximumVariableStorageSize, 1564 &RemainingVariableStorageSize, 1565 &MaximumVariableSize 1566 ); 1567 ASSERT_EFI_ERROR (Status); 1568 1569 TotalNeededSize = 0; 1570 VA_START (Args, Attributes); 1571 VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); 1572 while (VariableEntry != NULL) { 1573 // 1574 // Calculate variable total size. 1575 // 1576 VarNameSize = StrSize (VariableEntry->Name); 1577 VarNameSize += GET_PAD_SIZE (VarNameSize); 1578 VarDataSize = VariableEntry->VariableSize; 1579 VarDataSize += GET_PAD_SIZE (VarDataSize); 1580 VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize); 1581 1582 TotalNeededSize += VariableEntry->VariableSize; 1583 VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); 1584 } 1585 VA_END (Args); 1586 1587 if (RemainingVariableStorageSize >= TotalNeededSize) { 1588 // 1589 // Already have enough space. 1590 // 1591 return TRUE; 1592 } else if (AtRuntime ()) { 1593 // 1594 // At runtime, no reclaim. 1595 // The original variable space of Variables can't be reused. 1596 // 1597 return FALSE; 1598 } 1599 1600 VA_START (Args, Attributes); 1601 VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); 1602 while (VariableEntry != NULL) { 1603 // 1604 // Check if Variable[Index] has been present and get its size. 1605 // 1606 OriginalVarSize = 0; 1607 VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader); 1608 VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader); 1609 Status = FindVariableEx ( 1610 VariableEntry->Name, 1611 VariableEntry->Guid, 1612 FALSE, 1613 &VariablePtrTrack 1614 ); 1615 if (!EFI_ERROR (Status)) { 1616 // 1617 // Get size of Variable[Index]. 1618 // 1619 NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr); 1620 OriginalVarSize = (UINTN) NextVariable - (UINTN) VariablePtrTrack.CurrPtr; 1621 // 1622 // Add the original size of Variable[Index] to remaining variable storage size. 1623 // 1624 RemainingVariableStorageSize += OriginalVarSize; 1625 } 1626 if (VariableEntry->VariableSize > RemainingVariableStorageSize) { 1627 // 1628 // No enough space for Variable[Index]. 1629 // 1630 VA_END (Args); 1631 return FALSE; 1632 } 1633 // 1634 // Sub the (new) size of Variable[Index] from remaining variable storage size. 1635 // 1636 RemainingVariableStorageSize -= VariableEntry->VariableSize; 1637 VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); 1638 } 1639 VA_END (Args); 1640 1641 return TRUE; 1642 } 1643 1644 /** 1153 1645 Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang. 1154 1646 … … 1164 1656 @param[in] DataSize Size of data. 0 means delete. 1165 1657 1166 **/ 1167 VOID 1658 @retval EFI_SUCCESS The update operation is successful or ignored. 1659 @retval EFI_WRITE_PROTECTED Update PlatformLangCodes/LangCodes at runtime. 1660 @retval EFI_OUT_OF_RESOURCES No enough variable space to do the update operation. 1661 @retval Others Other errors happened during the update operation. 1662 1663 **/ 1664 EFI_STATUS 1168 1665 AutoUpdateLangVariable ( 1169 1666 IN CHAR16 *VariableName, … … 1179 1676 VARIABLE_POINTER_TRACK Variable; 1180 1677 BOOLEAN SetLanguageCodes; 1678 VARIABLE_ENTRY_CONSISTENCY VariableEntry[2]; 1181 1679 1182 1680 // … … 1184 1682 // 1185 1683 if (DataSize == 0) { 1186 return ;1684 return EFI_SUCCESS; 1187 1685 } 1188 1686 1189 1687 SetLanguageCodes = FALSE; 1190 1688 1191 if (StrCmp (VariableName, L"PlatformLangCodes") == 0) {1689 if (StrCmp (VariableName, EFI_PLATFORM_LANG_CODES_VARIABLE_NAME) == 0) { 1192 1690 // 1193 1691 // PlatformLangCodes is a volatile variable, so it can not be updated at runtime. 1194 1692 // 1195 1693 if (AtRuntime ()) { 1196 return ;1694 return EFI_WRITE_PROTECTED; 1197 1695 } 1198 1696 … … 1219 1717 ASSERT (mVariableModuleGlobal->PlatformLang != NULL); 1220 1718 1221 } else if (StrCmp (VariableName, L"LangCodes") == 0) {1719 } else if (StrCmp (VariableName, EFI_LANG_CODES_VARIABLE_NAME) == 0) { 1222 1720 // 1223 1721 // LangCodes is a volatile variable, so it can not be updated at runtime. 1224 1722 // 1225 1723 if (AtRuntime ()) { 1226 return ;1724 return EFI_WRITE_PROTECTED; 1227 1725 } 1228 1726 … … 1247 1745 // Update PlatformLang if Lang is already set 1248 1746 // 1249 Status = FindVariable ( L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);1747 Status = FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1250 1748 if (!EFI_ERROR (Status)) { 1251 1749 // 1252 1750 // Update Lang 1253 1751 // 1254 VariableName = L"PlatformLang";1752 VariableName = EFI_PLATFORM_LANG_VARIABLE_NAME; 1255 1753 Data = GetVariableDataPtr (Variable.CurrPtr); 1256 1754 DataSize = Variable.CurrPtr->DataSize; 1257 1755 } else { 1258 Status = FindVariable ( L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);1756 Status = FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1259 1757 if (!EFI_ERROR (Status)) { 1260 1758 // 1261 1759 // Update PlatformLang 1262 1760 // 1263 VariableName = L"Lang";1761 VariableName = EFI_LANG_VARIABLE_NAME; 1264 1762 Data = GetVariableDataPtr (Variable.CurrPtr); 1265 1763 DataSize = Variable.CurrPtr->DataSize; … … 1268 1766 // Neither PlatformLang nor Lang is set, directly return 1269 1767 // 1270 return; 1271 } 1272 } 1273 } 1768 return EFI_SUCCESS; 1769 } 1770 } 1771 } 1772 1773 Status = EFI_SUCCESS; 1274 1774 1275 1775 // … … 1278 1778 Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; 1279 1779 1280 if (StrCmp (VariableName, L"PlatformLang") == 0) {1780 if (StrCmp (VariableName, EFI_PLATFORM_LANG_VARIABLE_NAME) == 0) { 1281 1781 // 1282 1782 // Update Lang when PlatformLangCodes/LangCodes were set. … … 1299 1799 1300 1800 // 1301 // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously. 1302 // 1303 FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1304 1305 Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang, 1306 ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL); 1307 1308 DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang)); 1309 1310 ASSERT_EFI_ERROR(Status); 1311 } 1312 } 1313 1314 } else if (StrCmp (VariableName, L"Lang") == 0) { 1801 // Check the variable space for both Lang and PlatformLang variable. 1802 // 1803 VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1; 1804 VariableEntry[0].Guid = &gEfiGlobalVariableGuid; 1805 VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME; 1806 1807 VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang); 1808 VariableEntry[1].Guid = &gEfiGlobalVariableGuid; 1809 VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; 1810 if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { 1811 // 1812 // No enough variable space to set both Lang and PlatformLang successfully. 1813 // 1814 Status = EFI_OUT_OF_RESOURCES; 1815 } else { 1816 // 1817 // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously. 1818 // 1819 FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1820 1821 Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang, 1822 ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL); 1823 } 1824 1825 DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status)); 1826 } 1827 } 1828 1829 } else if (StrCmp (VariableName, EFI_LANG_VARIABLE_NAME) == 0) { 1315 1830 // 1316 1831 // Update PlatformLang when PlatformLangCodes/LangCodes were set. … … 1333 1848 1334 1849 // 1335 // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously. 1336 // 1337 FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1338 1339 Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang, 1340 AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL); 1341 1342 DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang)); 1343 ASSERT_EFI_ERROR (Status); 1344 } 1345 } 1850 // Check the variable space for both PlatformLang and Lang variable. 1851 // 1852 VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang); 1853 VariableEntry[0].Guid = &gEfiGlobalVariableGuid; 1854 VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; 1855 1856 VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1; 1857 VariableEntry[1].Guid = &gEfiGlobalVariableGuid; 1858 VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME; 1859 if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { 1860 // 1861 // No enough variable space to set both PlatformLang and Lang successfully. 1862 // 1863 Status = EFI_OUT_OF_RESOURCES; 1864 } else { 1865 // 1866 // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously. 1867 // 1868 FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); 1869 1870 Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang, 1871 AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL); 1872 } 1873 1874 DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status)); 1875 } 1876 } 1877 } 1878 1879 if (SetLanguageCodes) { 1880 // 1881 // Continue to set PlatformLangCodes or LangCodes. 1882 // 1883 return EFI_SUCCESS; 1884 } else { 1885 return Status; 1346 1886 } 1347 1887 } … … 1358 1898 @param[in] KeyIndex Index of associated public key. 1359 1899 @param[in] MonotonicCount Value of associated monotonic count. 1360 @param[in ] CacheVariableThe variable information which is used to keep track of variable usage.1900 @param[in, out] CacheVariable The variable information which is used to keep track of variable usage. 1361 1901 @param[in] TimeStamp Value of associated TimeStamp. 1362 1902 … … 1374 1914 IN UINT32 KeyIndex OPTIONAL, 1375 1915 IN UINT64 MonotonicCount OPTIONAL, 1376 IN 1916 IN OUT VARIABLE_POINTER_TRACK *CacheVariable, 1377 1917 IN EFI_TIME *TimeStamp OPTIONAL 1378 1918 ) … … 1381 1921 VARIABLE_HEADER *NextVariable; 1382 1922 UINTN ScratchSize; 1383 UINTN ScratchDataSize;1923 UINTN MaxDataSize; 1384 1924 UINTN NonVolatileVarableStoreSize; 1385 1925 UINTN VarNameOffset; … … 1390 1930 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; 1391 1931 UINT8 State; 1392 BOOLEAN Reclaimed;1393 1932 VARIABLE_POINTER_TRACK *Variable; 1394 1933 VARIABLE_POINTER_TRACK NvVariable; 1395 1934 VARIABLE_STORE_HEADER *VariableStoreHeader; 1396 1935 UINTN CacheOffset; 1397 UINTN BufSize; 1936 UINT8 *BufferForMerge; 1937 UINTN MergedBufSize; 1938 BOOLEAN DataReady; 1398 1939 UINTN DataOffset; 1399 UINTN RevBufSize;1400 1940 1401 1941 if (mVariableModuleGlobal->FvbInstance == NULL) { … … 1430 1970 Variable->EndPtr = GetEndPointer (VariableStoreHeader); 1431 1971 Variable->CurrPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr)); 1972 if (CacheVariable->InDeletedTransitionPtr != NULL) { 1973 Variable->InDeletedTransitionPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->InDeletedTransitionPtr - (UINTN)CacheVariable->StartPtr)); 1974 } else { 1975 Variable->InDeletedTransitionPtr = NULL; 1976 } 1432 1977 Variable->Volatile = FALSE; 1433 1978 } 1434 1979 1435 1980 Fvb = mVariableModuleGlobal->FvbInstance; 1436 Reclaimed = FALSE;1437 1981 1438 1982 // … … 1442 1986 NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)); 1443 1987 ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)); 1444 ScratchDataSize = ScratchSize - sizeof (VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName)); 1988 SetMem (NextVariable, ScratchSize, 0xff); 1989 DataReady = FALSE; 1445 1990 1446 1991 if (Variable->CurrPtr != NULL) { … … 1482 2027 // 1483 2028 if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0))|| ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0)) { 2029 if (Variable->InDeletedTransitionPtr != NULL) { 2030 // 2031 // Both ADDED and IN_DELETED_TRANSITION variable are present, 2032 // set IN_DELETED_TRANSITION one to DELETED state first. 2033 // 2034 State = Variable->InDeletedTransitionPtr->State; 2035 State &= VAR_DELETED; 2036 Status = UpdateVariableStore ( 2037 &mVariableModuleGlobal->VariableGlobal, 2038 Variable->Volatile, 2039 FALSE, 2040 Fvb, 2041 (UINTN) &Variable->InDeletedTransitionPtr->State, 2042 sizeof (UINT8), 2043 &State 2044 ); 2045 if (!EFI_ERROR (Status)) { 2046 if (!Variable->Volatile) { 2047 ASSERT (CacheVariable->InDeletedTransitionPtr != NULL); 2048 CacheVariable->InDeletedTransitionPtr->State = State; 2049 } 2050 } else { 2051 goto Done; 2052 } 2053 } 2054 1484 2055 State = Variable->CurrPtr->State; 1485 2056 State &= VAR_DELETED; … … 1498 2069 if (!Variable->Volatile) { 1499 2070 CacheVariable->CurrPtr->State = State; 2071 FlushHobVariableToFlash (VariableName, VendorGuid); 1500 2072 } 1501 2073 } … … 1507 2079 // 1508 2080 if (DataSizeOfVariable (Variable->CurrPtr) == DataSize && 1509 (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0) 2081 (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0) && 1510 2082 ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && 1511 2083 (TimeStamp == NULL)) { … … 1524 2096 if ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0) { 1525 2097 // 1526 // Cache the previous variable data into StorageArea. 2098 // NOTE: From 0 to DataOffset of NextVariable is reserved for Variable Header and Name. 2099 // From DataOffset of NextVariable is to save the existing variable data. 1527 2100 // 1528 2101 DataOffset = sizeof (VARIABLE_HEADER) + Variable->CurrPtr->NameSize + GET_PAD_SIZE (Variable->CurrPtr->NameSize); 1529 CopyMem (mStorageArea, (UINT8*)((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize); 1530 1531 if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) || 1532 (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) { 2102 BufferForMerge = (UINT8 *) ((UINTN) NextVariable + DataOffset); 2103 CopyMem (BufferForMerge, (UINT8 *) ((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize); 2104 2105 // 2106 // Set Max Common Variable Data Size as default MaxDataSize 2107 // 2108 MaxDataSize = PcdGet32 (PcdMaxVariableSize) - DataOffset; 2109 2110 if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) && 2111 ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) || 2112 (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) { 1533 2113 // 1534 // For variables with the GUID EFI_IMAGE_SECURITY_DATABASE_GUID (i.e. where the data 1535 // buffer is formatted as EFI_SIGNATURE_LIST), the driver shall not perform an append of 2114 // For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of 1536 2115 // EFI_SIGNATURE_DATA values that are already part of the existing variable value. 1537 2116 // 1538 BufSize = AppendSignatureList (mStorageArea, Variable->CurrPtr->DataSize, Data, DataSize); 1539 if (BufSize == Variable->CurrPtr->DataSize) { 2117 Status = AppendSignatureList ( 2118 BufferForMerge, 2119 Variable->CurrPtr->DataSize, 2120 MaxDataSize - Variable->CurrPtr->DataSize, 2121 Data, 2122 DataSize, 2123 &MergedBufSize 2124 ); 2125 if (Status == EFI_BUFFER_TOO_SMALL) { 2126 // 2127 // Signature List is too long, Failed to Append. 2128 // 2129 Status = EFI_INVALID_PARAMETER; 2130 goto Done; 2131 } 2132 2133 if (MergedBufSize == Variable->CurrPtr->DataSize) { 1540 2134 if ((TimeStamp == NULL) || CompareTimeStamp (TimeStamp, &Variable->CurrPtr->TimeStamp)) { 1541 2135 // … … 1550 2144 } else { 1551 2145 // 1552 // For other Variables, append the new data to the end of previous data. 2146 // For other Variables, append the new data to the end of existing data. 2147 // Max Harware error record variable data size is different from common variable 1553 2148 // 1554 CopyMem ((UINT8*)((UINTN) mStorageArea + Variable->CurrPtr->DataSize), Data, DataSize); 1555 BufSize = Variable->CurrPtr->DataSize + DataSize; 2149 if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 2150 MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - DataOffset; 2151 } 2152 2153 if (Variable->CurrPtr->DataSize + DataSize > MaxDataSize) { 2154 // 2155 // Existing data size + new data size exceed maximum variable size limitation. 2156 // 2157 Status = EFI_INVALID_PARAMETER; 2158 goto Done; 2159 } 2160 CopyMem ((UINT8*) ((UINTN) BufferForMerge + Variable->CurrPtr->DataSize), Data, DataSize); 2161 MergedBufSize = Variable->CurrPtr->DataSize + DataSize; 1556 2162 } 1557 2163 1558 RevBufSize = MIN (PcdGet32 (PcdMaxVariableSize), ScratchDataSize); 1559 if (BufSize > RevBufSize) { 1560 // 1561 // If variable size (previous + current) is bigger than reserved buffer in runtime, 1562 // return EFI_OUT_OF_RESOURCES. 1563 // 1564 return EFI_OUT_OF_RESOURCES; 1565 } 1566 1567 // 1568 // Override Data and DataSize which are used for combined data area including previous and new data. 1569 // 1570 Data = mStorageArea; 1571 DataSize = BufSize; 2164 // 2165 // BufferForMerge(from DataOffset of NextVariable) has included the merged existing and new data. 2166 // 2167 Data = BufferForMerge; 2168 DataSize = MergedBufSize; 2169 DataReady = TRUE; 1572 2170 } 1573 2171 … … 1626 2224 // Function part - create a new variable and copy the data. 1627 2225 // Both update a variable and create a variable will come here. 1628 1629 SetMem (NextVariable, ScratchSize, 0xff); 1630 2226 // 1631 2227 NextVariable->StartId = VARIABLE_DATA; 1632 2228 // … … 1670 2266 ); 1671 2267 VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize); 1672 CopyMem ( 1673 (UINT8 *) ((UINTN) NextVariable + VarDataOffset), 1674 Data, 1675 DataSize 1676 ); 2268 2269 // 2270 // If DataReady is TRUE, it means the variable data has been saved into 2271 // NextVariable during EFI_VARIABLE_APPEND_WRITE operation preparation. 2272 // 2273 if (!DataReady) { 2274 CopyMem ( 2275 (UINT8 *) ((UINTN) NextVariable + VarDataOffset), 2276 Data, 2277 DataSize 2278 ); 2279 } 2280 1677 2281 CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID)); 1678 2282 // … … 1704 2308 } 1705 2309 // 1706 // Perform garbage collection & reclaim operation. 1707 // 1708 Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, 1709 &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr); 1710 if (EFI_ERROR (Status)) { 1711 goto Done; 1712 } 1713 // 1714 // If still no enough space, return out of resources. 1715 // 1716 if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) 1717 && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize))) 1718 || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) 1719 && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) { 1720 Status = EFI_OUT_OF_RESOURCES; 1721 goto Done; 1722 } 1723 Reclaimed = TRUE; 2310 // Perform garbage collection & reclaim operation, and integrate the new variable at the same time. 2311 // 2312 Status = Reclaim ( 2313 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, 2314 &mVariableModuleGlobal->NonVolatileLastVariableOffset, 2315 FALSE, 2316 Variable, 2317 NextVariable, 2318 HEADER_ALIGN (VarSize), 2319 FALSE 2320 ); 2321 if (!EFI_ERROR (Status)) { 2322 // 2323 // The new variable has been integrated successfully during reclaiming. 2324 // 2325 if (Variable->CurrPtr != NULL) { 2326 CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr)); 2327 CacheVariable->InDeletedTransitionPtr = NULL; 2328 } 2329 UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE); 2330 FlushHobVariableToFlash (VariableName, VendorGuid); 2331 } 2332 goto Done; 1724 2333 } 1725 2334 // … … 1819 2428 ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) { 1820 2429 // 1821 // Perform garbage collection & reclaim operation. 1822 // 1823 Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, 1824 &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr); 1825 if (EFI_ERROR (Status)) { 1826 goto Done; 1827 } 1828 // 1829 // If still no enough space, return out of resources. 1830 // 1831 if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) > 1832 ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size 1833 ) { 1834 Status = EFI_OUT_OF_RESOURCES; 1835 goto Done; 1836 } 1837 Reclaimed = TRUE; 2430 // Perform garbage collection & reclaim operation, and integrate the new variable at the same time. 2431 // 2432 Status = Reclaim ( 2433 mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, 2434 &mVariableModuleGlobal->VolatileLastVariableOffset, 2435 TRUE, 2436 Variable, 2437 NextVariable, 2438 HEADER_ALIGN (VarSize), 2439 FALSE 2440 ); 2441 if (!EFI_ERROR (Status)) { 2442 // 2443 // The new variable has been integrated successfully during reclaiming. 2444 // 2445 if (Variable->CurrPtr != NULL) { 2446 CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr)); 2447 CacheVariable->InDeletedTransitionPtr = NULL; 2448 } 2449 UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE, FALSE, FALSE); 2450 } 2451 goto Done; 1838 2452 } 1839 2453 … … 1859 2473 // Mark the old variable as deleted. 1860 2474 // 1861 if (!Reclaimed && !EFI_ERROR (Status) && Variable->CurrPtr != NULL) { 2475 if (!EFI_ERROR (Status) && Variable->CurrPtr != NULL) { 2476 if (Variable->InDeletedTransitionPtr != NULL) { 2477 // 2478 // Both ADDED and IN_DELETED_TRANSITION old variable are present, 2479 // set IN_DELETED_TRANSITION one to DELETED state first. 2480 // 2481 State = Variable->InDeletedTransitionPtr->State; 2482 State &= VAR_DELETED; 2483 Status = UpdateVariableStore ( 2484 &mVariableModuleGlobal->VariableGlobal, 2485 Variable->Volatile, 2486 FALSE, 2487 Fvb, 2488 (UINTN) &Variable->InDeletedTransitionPtr->State, 2489 sizeof (UINT8), 2490 &State 2491 ); 2492 if (!EFI_ERROR (Status)) { 2493 if (!Variable->Volatile) { 2494 ASSERT (CacheVariable->InDeletedTransitionPtr != NULL); 2495 CacheVariable->InDeletedTransitionPtr->State = State; 2496 } 2497 } else { 2498 goto Done; 2499 } 2500 } 2501 1862 2502 State = Variable->CurrPtr->State; 1863 2503 State &= VAR_DELETED; … … 1879 2519 if (!EFI_ERROR (Status)) { 1880 2520 UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE, FALSE, FALSE); 2521 if (!Volatile) { 2522 FlushHobVariableToFlash (VariableName, VendorGuid); 2523 } 1881 2524 } 1882 2525 … … 1886 2529 1887 2530 /** 2531 Check if a Unicode character is a hexadecimal character. 2532 2533 This function checks if a Unicode character is a 2534 hexadecimal character. The valid hexadecimal character is 2535 L'0' to L'9', L'a' to L'f', or L'A' to L'F'. 2536 2537 2538 @param Char The character to check against. 2539 2540 @retval TRUE If the Char is a hexadecmial character. 2541 @retval FALSE If the Char is not a hexadecmial character. 2542 2543 **/ 2544 BOOLEAN 2545 EFIAPI 2546 IsHexaDecimalDigitCharacter ( 2547 IN CHAR16 Char 2548 ) 2549 { 2550 return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f')); 2551 } 2552 2553 /** 2554 2555 This code checks if variable is hardware error record variable or not. 2556 2557 According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid 2558 and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value. 2559 2560 @param VariableName Pointer to variable name. 2561 @param VendorGuid Variable Vendor Guid. 2562 2563 @retval TRUE Variable is hardware error record variable. 2564 @retval FALSE Variable is not hardware error record variable. 2565 2566 **/ 2567 BOOLEAN 2568 EFIAPI 2569 IsHwErrRecVariable ( 2570 IN CHAR16 *VariableName, 2571 IN EFI_GUID *VendorGuid 2572 ) 2573 { 2574 if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) || 2575 (StrLen (VariableName) != StrLen (L"HwErrRec####")) || 2576 (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) || 2577 !IsHexaDecimalDigitCharacter (VariableName[0x8]) || 2578 !IsHexaDecimalDigitCharacter (VariableName[0x9]) || 2579 !IsHexaDecimalDigitCharacter (VariableName[0xA]) || 2580 !IsHexaDecimalDigitCharacter (VariableName[0xB])) { 2581 return FALSE; 2582 } 2583 2584 return TRUE; 2585 } 2586 2587 /** 2588 This code checks if variable guid is global variable guid first. 2589 If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2 and attributes matched. 2590 2591 @param[in] VariableName Pointer to variable name. 2592 @param[in] VendorGuid Variable Vendor Guid. 2593 @param[in] Attributes Attributes of the variable. 2594 2595 @retval EFI_SUCCESS Variable is not global variable, or Variable is global variable, variable name is in the lists and attributes matched. 2596 @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists or attributes unmatched. 2597 2598 **/ 2599 EFI_STATUS 2600 EFIAPI 2601 CheckEfiGlobalVariable ( 2602 IN CHAR16 *VariableName, 2603 IN EFI_GUID *VendorGuid, 2604 IN UINT32 Attributes 2605 ) 2606 { 2607 UINTN Index; 2608 UINTN NameLength; 2609 2610 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){ 2611 // 2612 // Try list 1, exactly match. 2613 // 2614 for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) { 2615 if ((StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) && 2616 (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList[Index].Attributes)) { 2617 return EFI_SUCCESS; 2618 } 2619 } 2620 2621 // 2622 // Try list 2. 2623 // 2624 NameLength = StrLen (VariableName) - 4; 2625 for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) { 2626 if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) && 2627 (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) && 2628 IsHexaDecimalDigitCharacter (VariableName[NameLength]) && 2629 IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) && 2630 IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) && 2631 IsHexaDecimalDigitCharacter (VariableName[NameLength + 3]) && 2632 (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList2[Index].Attributes)) { 2633 return EFI_SUCCESS; 2634 } 2635 } 2636 2637 DEBUG ((EFI_D_INFO, "[Variable]: set global variable with invalid variable name or attributes - %g:%s:%x\n", VendorGuid, VariableName, Attributes)); 2638 return EFI_INVALID_PARAMETER; 2639 } 2640 2641 return EFI_SUCCESS; 2642 } 2643 2644 /** 2645 Mark a variable that will become read-only after leaving the DXE phase of execution. 2646 2647 @param[in] This The VARIABLE_LOCK_PROTOCOL instance. 2648 @param[in] VariableName A pointer to the variable name that will be made read-only subsequently. 2649 @param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently. 2650 2651 @retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked 2652 as pending to be read-only. 2653 @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL. 2654 Or VariableName is an empty string. 2655 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has 2656 already been signaled. 2657 @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request. 2658 **/ 2659 EFI_STATUS 2660 EFIAPI 2661 VariableLockRequestToLock ( 2662 IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, 2663 IN CHAR16 *VariableName, 2664 IN EFI_GUID *VendorGuid 2665 ) 2666 { 2667 VARIABLE_ENTRY *Entry; 2668 2669 if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { 2670 return EFI_INVALID_PARAMETER; 2671 } 2672 2673 if (mEndOfDxe) { 2674 return EFI_ACCESS_DENIED; 2675 } 2676 2677 Entry = AllocateRuntimePool (sizeof (*Entry) + StrSize (VariableName)); 2678 if (Entry == NULL) { 2679 return EFI_OUT_OF_RESOURCES; 2680 } 2681 2682 DEBUG ((EFI_D_INFO, "[Variable] Lock: %g:%s\n", VendorGuid, VariableName)); 2683 2684 AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); 2685 2686 Entry->Name = (CHAR16 *) (Entry + 1); 2687 StrCpy (Entry->Name, VariableName); 2688 CopyGuid (&Entry->Guid, VendorGuid); 2689 InsertTailList (&mLockedVariableList, &Entry->Link); 2690 2691 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); 2692 2693 return EFI_SUCCESS; 2694 } 2695 2696 /** 2697 This code checks if variable should be treated as read-only variable. 2698 2699 @param[in] VariableName Name of the Variable. 2700 @param[in] VendorGuid GUID of the Variable. 2701 2702 @retval TRUE This variable is read-only variable. 2703 @retval FALSE This variable is NOT read-only variable. 2704 2705 **/ 2706 BOOLEAN 2707 IsReadOnlyVariable ( 2708 IN CHAR16 *VariableName, 2709 IN EFI_GUID *VendorGuid 2710 ) 2711 { 2712 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) { 2713 if ((StrCmp (VariableName, EFI_SETUP_MODE_NAME) == 0) || 2714 (StrCmp (VariableName, EFI_SIGNATURE_SUPPORT_NAME) == 0) || 2715 (StrCmp (VariableName, EFI_SECURE_BOOT_MODE_NAME) == 0) || 2716 (StrCmp (VariableName, EFI_VENDOR_KEYS_VARIABLE_NAME) == 0) || 2717 (StrCmp (VariableName, EFI_KEK_DEFAULT_VARIABLE_NAME) == 0) || 2718 (StrCmp (VariableName, EFI_PK_DEFAULT_VARIABLE_NAME) == 0) || 2719 (StrCmp (VariableName, EFI_DB_DEFAULT_VARIABLE_NAME) == 0) || 2720 (StrCmp (VariableName, EFI_DBX_DEFAULT_VARIABLE_NAME) == 0) || 2721 (StrCmp (VariableName, EFI_DBT_DEFAULT_VARIABLE_NAME) == 0)) { 2722 return TRUE; 2723 } 2724 } 2725 2726 return FALSE; 2727 } 2728 2729 /** 1888 2730 1889 2731 This code finds variable in storage blocks (Volatile or Non-Volatile). 2732 2733 Caution: This function may receive untrusted input. 2734 This function may be invoked in SMM mode, and datasize is external input. 2735 This function will do basic validation, before parse the data. 1890 2736 1891 2737 @param VariableName Name of Variable to be found. … … 1966 2812 This code Finds the Next available variable. 1967 2813 2814 Caution: This function may receive untrusted input. 2815 This function may be invoked in SMM mode. This function will do basic validation, before parse the data. 2816 1968 2817 @param VariableNameSize Size of the variable name. 1969 2818 @param VariableName Pointer to variable name. … … 1987 2836 VARIABLE_POINTER_TRACK Variable; 1988 2837 VARIABLE_POINTER_TRACK VariableInHob; 2838 VARIABLE_POINTER_TRACK VariablePtrTrack; 1989 2839 UINTN VarNameSize; 1990 2840 EFI_STATUS Status; … … 2022 2872 // Switch from Volatile to HOB, to Non-Volatile. 2023 2873 // 2024 while ((Variable.CurrPtr >= Variable.EndPtr) || 2025 (Variable.CurrPtr == NULL) || 2026 !IsValidVariableHeader (Variable.CurrPtr) 2027 ) { 2874 while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) { 2028 2875 // 2029 2876 // Find current storage index … … 2060 2907 // Variable is found 2061 2908 // 2062 if (Variable.CurrPtr->State == VAR_ADDED) { 2063 if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) { 2909 if (Variable.CurrPtr->State == VAR_ADDED || Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 2910 if (!AtRuntime () || ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) { 2911 if (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 2912 // 2913 // If it is a IN_DELETED_TRANSITION variable, 2914 // and there is also a same ADDED one at the same time, 2915 // don't return it. 2916 // 2917 VariablePtrTrack.StartPtr = Variable.StartPtr; 2918 VariablePtrTrack.EndPtr = Variable.EndPtr; 2919 Status = FindVariableEx ( 2920 GetVariableNamePtr (Variable.CurrPtr), 2921 &Variable.CurrPtr->VendorGuid, 2922 FALSE, 2923 &VariablePtrTrack 2924 ); 2925 if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State == VAR_ADDED) { 2926 Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr); 2927 continue; 2928 } 2929 } 2064 2930 2065 2931 // … … 2111 2977 This code sets variable in storage blocks (Volatile or Non-Volatile). 2112 2978 2979 Caution: This function may receive untrusted input. 2980 This function may be invoked in SMM mode, and datasize and data are external input. 2981 This function will do basic validation, before parse the data. 2982 This function will parse the authentication carefully to avoid security issues, like 2983 buffer overflow, integer overflow. 2984 This function will check attribute carefully to avoid authentication bypass. 2985 2113 2986 @param VariableName Name of Variable to be found. 2114 2987 @param VendorGuid Variable vendor GUID. … … 2140 3013 EFI_PHYSICAL_ADDRESS Point; 2141 3014 UINTN PayloadSize; 3015 LIST_ENTRY *Link; 3016 VARIABLE_ENTRY *Entry; 2142 3017 2143 3018 // … … 2148 3023 } 2149 3024 3025 if (IsReadOnlyVariable (VariableName, VendorGuid)) { 3026 return EFI_WRITE_PROTECTED; 3027 } 3028 2150 3029 if (DataSize != 0 && Data == NULL) { 3030 return EFI_INVALID_PARAMETER; 3031 } 3032 3033 // 3034 // Check for reserverd bit in variable attribute. 3035 // 3036 if ((Attributes & (~EFI_VARIABLE_ATTRIBUTES_MASK)) != 0) { 2151 3037 return EFI_INVALID_PARAMETER; 2152 3038 } … … 2190 3076 } 2191 3077 3078 if ((UINTN)(~0) - PayloadSize < StrSize(VariableName)){ 3079 // 3080 // Prevent whole variable size overflow 3081 // 3082 return EFI_INVALID_PARAMETER; 3083 } 3084 2192 3085 // 2193 3086 // The size of the VariableName, including the Unicode Null in bytes plus … … 2196 3089 // 2197 3090 if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 2198 if ((PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize)) || 2199 (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize))) { 3091 if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) { 2200 3092 return EFI_INVALID_PARAMETER; 2201 3093 } 2202 // 2203 // According to UEFI spec, HARDWARE_ERROR_RECORD variable name convention should be L"HwErrRecXXXX". 2204 // 2205 if (StrnCmp(VariableName, L"HwErrRec", StrLen(L"HwErrRec")) != 0) { 3094 if (!IsHwErrRecVariable(VariableName, VendorGuid)) { 2206 3095 return EFI_INVALID_PARAMETER; 2207 3096 } … … 2211 3100 // the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes. 2212 3101 // 2213 if ((PayloadSize > PcdGet32 (PcdMaxVariableSize)) || 2214 (sizeof (VARIABLE_HEADER) + StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize))) { 3102 if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) { 2215 3103 return EFI_INVALID_PARAMETER; 2216 3104 } 3105 } 3106 3107 Status = CheckEfiGlobalVariable (VariableName, VendorGuid, Attributes); 3108 if (EFI_ERROR (Status)) { 3109 return Status; 2217 3110 } 2218 3111 … … 2228 3121 // 2229 3122 NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point); 2230 while ((NextVariable < GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point)) 2231 && IsValidVariableHeader (NextVariable)) { 3123 while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *) (UINTN) Point))) { 2232 3124 NextVariable = GetNextVariablePtr (NextVariable); 2233 3125 } 2234 3126 mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) Point; 3127 } 3128 3129 if (mEndOfDxe && mEnableLocking) { 3130 // 3131 // Treat the variables listed in the forbidden variable list as read-only after leaving DXE phase. 3132 // 3133 for ( Link = GetFirstNode (&mLockedVariableList) 3134 ; !IsNull (&mLockedVariableList, Link) 3135 ; Link = GetNextNode (&mLockedVariableList, Link) 3136 ) { 3137 Entry = BASE_CR (Link, VARIABLE_ENTRY, Link); 3138 if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Entry->Name, VariableName) == 0)) { 3139 Status = EFI_WRITE_PROTECTED; 3140 DEBUG ((EFI_D_INFO, "[Variable]: Changing readonly variable after leaving DXE phase - %g:%s\n", VendorGuid, VariableName)); 3141 goto Done; 3142 } 3143 } 2235 3144 } 2236 3145 … … 2241 3150 if (!EFI_ERROR (Status)) { 2242 3151 if (((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) && AtRuntime ()) { 2243 return EFI_WRITE_PROTECTED; 2244 } 2245 } 2246 2247 // 2248 // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang. 2249 // 2250 AutoUpdateLangVariable (VariableName, Data, DataSize); 3152 Status = EFI_WRITE_PROTECTED; 3153 goto Done; 3154 } 3155 if (Attributes != 0 && (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Variable.CurrPtr->Attributes) { 3156 // 3157 // If a preexisting variable is rewritten with different attributes, SetVariable() shall not 3158 // modify the variable and shall return EFI_INVALID_PARAMETER. Two exceptions to this rule: 3159 // 1. No access attributes specified 3160 // 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE 3161 // 3162 Status = EFI_INVALID_PARAMETER; 3163 goto Done; 3164 } 3165 } 3166 3167 if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) { 3168 // 3169 // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang. 3170 // 3171 Status = AutoUpdateLangVariable (VariableName, Data, DataSize); 3172 if (EFI_ERROR (Status)) { 3173 // 3174 // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang. 3175 // 3176 goto Done; 3177 } 3178 } 3179 2251 3180 // 2252 3181 // Process PK, KEK, Sigdb seperately. … … 2258 3187 } else if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) && 2259 3188 ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) { 2260 Status = ProcessVarWithKek (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes); 3189 Status = ProcessVarWithPk (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes, FALSE); 3190 if (EFI_ERROR (Status)) { 3191 Status = ProcessVarWithKek (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes); 3192 } 2261 3193 } else { 2262 3194 Status = ProcessVariable (VariableName, VendorGuid, Data, DataSize, &Variable, Attributes); 2263 3195 } 2264 3196 3197 Done: 2265 3198 InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState); 2266 3199 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); 2267 3200 3201 if (!AtRuntime ()) { 3202 if (!EFI_ERROR (Status)) { 3203 SecureBootHook ( 3204 VariableName, 3205 VendorGuid 3206 ); 3207 } 3208 } 3209 2268 3210 return Status; 2269 3211 } … … 2272 3214 2273 3215 This code returns information about the EFI variables. 3216 3217 Caution: This function may receive untrusted input. 3218 This function may be invoked in SMM mode. This function will do basic validation, before parse the data. 2274 3219 2275 3220 @param Attributes Attributes bitmask to specify the type of variables … … 2282 3227 associated with the attributes specified. 2283 3228 2284 @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.2285 3229 @return EFI_SUCCESS Query successfully. 2286 @return EFI_UNSUPPORTED The attribute is not supported on this platform.2287 3230 2288 3231 **/ 2289 3232 EFI_STATUS 2290 3233 EFIAPI 2291 VariableServiceQueryVariableInfo (3234 VariableServiceQueryVariableInfoInternal ( 2292 3235 IN UINT32 Attributes, 2293 3236 OUT UINT64 *MaximumVariableStorageSize, … … 2302 3245 UINT64 CommonVariableTotalSize; 2303 3246 UINT64 HwErrVariableTotalSize; 3247 EFI_STATUS Status; 3248 VARIABLE_POINTER_TRACK VariablePtrTrack; 2304 3249 2305 3250 CommonVariableTotalSize = 0; 2306 3251 HwErrVariableTotalSize = 0; 2307 2308 if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {2309 return EFI_INVALID_PARAMETER;2310 }2311 2312 if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {2313 //2314 // Make sure the Attributes combination is supported by the platform.2315 //2316 return EFI_UNSUPPORTED;2317 } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {2318 //2319 // Make sure if runtime bit is set, boot service bit is set also.2320 //2321 return EFI_INVALID_PARAMETER;2322 } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {2323 //2324 // Make sure RT Attribute is set if we are in Runtime phase.2325 //2326 return EFI_INVALID_PARAMETER;2327 } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {2328 //2329 // Make sure Hw Attribute is set with NV.2330 //2331 return EFI_INVALID_PARAMETER;2332 }2333 2334 AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);2335 3252 2336 3253 if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) { … … 2378 3295 // Now walk through the related variable store. 2379 3296 // 2380 while ( (Variable < GetEndPointer (VariableStoreHeader)) && IsValidVariableHeader (Variable)) {3297 while (IsValidVariableHeader (Variable, GetEndPointer (VariableStoreHeader))) { 2381 3298 NextVariable = GetNextVariablePtr (Variable); 2382 3299 VariableSize = (UINT64) (UINTN) NextVariable - (UINT64) (UINTN) Variable; … … 2405 3322 CommonVariableTotalSize += VariableSize; 2406 3323 } 3324 } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { 3325 // 3326 // If it is a IN_DELETED_TRANSITION variable, 3327 // and there is not also a same ADDED one at the same time, 3328 // this IN_DELETED_TRANSITION variable is valid. 3329 // 3330 VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader); 3331 VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader); 3332 Status = FindVariableEx ( 3333 GetVariableNamePtr (Variable), 3334 &Variable->VendorGuid, 3335 FALSE, 3336 &VariablePtrTrack 3337 ); 3338 if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != VAR_ADDED) { 3339 if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 3340 HwErrVariableTotalSize += VariableSize; 3341 } else { 3342 CommonVariableTotalSize += VariableSize; 3343 } 3344 } 2407 3345 } 2408 3346 } … … 2426 3364 } 2427 3365 2428 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);2429 3366 return EFI_SUCCESS; 2430 3367 } 2431 3368 3369 /** 3370 3371 This code returns information about the EFI variables. 3372 3373 Caution: This function may receive untrusted input. 3374 This function may be invoked in SMM mode. This function will do basic validation, before parse the data. 3375 3376 @param Attributes Attributes bitmask to specify the type of variables 3377 on which to return information. 3378 @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available 3379 for the EFI variables associated with the attributes specified. 3380 @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available 3381 for EFI variables associated with the attributes specified. 3382 @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables 3383 associated with the attributes specified. 3384 3385 @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied. 3386 @return EFI_SUCCESS Query successfully. 3387 @return EFI_UNSUPPORTED The attribute is not supported on this platform. 3388 3389 **/ 3390 EFI_STATUS 3391 EFIAPI 3392 VariableServiceQueryVariableInfo ( 3393 IN UINT32 Attributes, 3394 OUT UINT64 *MaximumVariableStorageSize, 3395 OUT UINT64 *RemainingVariableStorageSize, 3396 OUT UINT64 *MaximumVariableSize 3397 ) 3398 { 3399 EFI_STATUS Status; 3400 3401 if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) { 3402 return EFI_INVALID_PARAMETER; 3403 } 3404 3405 if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) { 3406 // 3407 // Make sure the Attributes combination is supported by the platform. 3408 // 3409 return EFI_UNSUPPORTED; 3410 } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) { 3411 // 3412 // Make sure if runtime bit is set, boot service bit is set also. 3413 // 3414 return EFI_INVALID_PARAMETER; 3415 } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) { 3416 // 3417 // Make sure RT Attribute is set if we are in Runtime phase. 3418 // 3419 return EFI_INVALID_PARAMETER; 3420 } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 3421 // 3422 // Make sure Hw Attribute is set with NV. 3423 // 3424 return EFI_INVALID_PARAMETER; 3425 } 3426 3427 AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); 3428 3429 Status = VariableServiceQueryVariableInfoInternal ( 3430 Attributes, 3431 MaximumVariableStorageSize, 3432 RemainingVariableStorageSize, 3433 MaximumVariableSize 3434 ); 3435 3436 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); 3437 return Status; 3438 } 2432 3439 2433 3440 /** 2434 3441 This function reclaims variable storage if free size is below the threshold. 3442 3443 Caution: This function may be invoked at SMM mode. 3444 Care must be taken to make sure not security issue. 2435 3445 2436 3446 **/ … … 2444 3454 UINTN RemainingCommonVariableSpace; 2445 3455 UINTN RemainingHwErrVariableSpace; 3456 STATIC BOOLEAN Reclaimed; 3457 3458 // 3459 // This function will be called only once at EndOfDxe or ReadyToBoot event. 3460 // 3461 if (Reclaimed) { 3462 return; 3463 } 3464 Reclaimed = TRUE; 2446 3465 2447 3466 Status = EFI_SUCCESS; … … 2462 3481 &mVariableModuleGlobal->NonVolatileLastVariableOffset, 2463 3482 FALSE, 2464 NULL 3483 NULL, 3484 NULL, 3485 0, 3486 FALSE 2465 3487 ); 2466 3488 ASSERT_EFI_ERROR (Status); … … 2468 3490 } 2469 3491 2470 2471 3492 /** 2472 Initializes variable write service after FVB was ready. 3493 Init non-volatile variable store. 3494 3495 @retval EFI_SUCCESS Function successfully executed. 3496 @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource. 3497 @retval EFI_VOLUME_CORRUPTED Variable Store or Firmware Volume for Variable Store is corrupted. 3498 3499 **/ 3500 EFI_STATUS 3501 InitNonVolatileVariableStore ( 3502 VOID 3503 ) 3504 { 3505 EFI_FIRMWARE_VOLUME_HEADER *FvHeader; 3506 VARIABLE_HEADER *NextVariable; 3507 EFI_PHYSICAL_ADDRESS VariableStoreBase; 3508 UINT64 VariableStoreLength; 3509 UINTN VariableSize; 3510 EFI_HOB_GUID_TYPE *GuidHob; 3511 EFI_PHYSICAL_ADDRESS NvStorageBase; 3512 UINT8 *NvStorageData; 3513 UINT32 NvStorageSize; 3514 FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; 3515 UINT32 BackUpOffset; 3516 UINT32 BackUpSize; 3517 3518 mVariableModuleGlobal->FvbInstance = NULL; 3519 3520 // 3521 // Note that in EdkII variable driver implementation, Hardware Error Record type variable 3522 // is stored with common variable in the same NV region. So the platform integrator should 3523 // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of 3524 // PcdFlashNvStorageVariableSize. 3525 // 3526 ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize)); 3527 3528 // 3529 // Allocate runtime memory used for a memory copy of the FLASH region. 3530 // Keep the memory and the FLASH in sync as updates occur. 3531 // 3532 NvStorageSize = PcdGet32 (PcdFlashNvStorageVariableSize); 3533 NvStorageData = AllocateRuntimeZeroPool (NvStorageSize); 3534 if (NvStorageData == NULL) { 3535 return EFI_OUT_OF_RESOURCES; 3536 } 3537 3538 NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64); 3539 if (NvStorageBase == 0) { 3540 NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase); 3541 } 3542 // 3543 // Copy NV storage data to the memory buffer. 3544 // 3545 CopyMem (NvStorageData, (UINT8 *) (UINTN) NvStorageBase, NvStorageSize); 3546 3547 // 3548 // Check the FTW last write data hob. 3549 // 3550 GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); 3551 if (GuidHob != NULL) { 3552 FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob); 3553 if (FtwLastWriteData->TargetAddress == NvStorageBase) { 3554 DEBUG ((EFI_D_INFO, "Variable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress)); 3555 // 3556 // Copy the backed up NV storage data to the memory buffer from spare block. 3557 // 3558 CopyMem (NvStorageData, (UINT8 *) (UINTN) (FtwLastWriteData->SpareAddress), NvStorageSize); 3559 } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) && 3560 (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) { 3561 // 3562 // Flash NV storage from the Offset is backed up in spare block. 3563 // 3564 BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase); 3565 BackUpSize = NvStorageSize - BackUpOffset; 3566 DEBUG ((EFI_D_INFO, "Variable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress)); 3567 // 3568 // Copy the partial backed up NV storage data to the memory buffer from spare block. 3569 // 3570 CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) FtwLastWriteData->SpareAddress, BackUpSize); 3571 } 3572 } 3573 3574 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) NvStorageData; 3575 3576 // 3577 // Check if the Firmware Volume is not corrupted 3578 // 3579 if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) { 3580 FreePool (NvStorageData); 3581 DEBUG ((EFI_D_ERROR, "Firmware Volume for Variable Store is corrupted\n")); 3582 return EFI_VOLUME_CORRUPTED; 3583 } 3584 3585 VariableStoreBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) FvHeader + FvHeader->HeaderLength); 3586 VariableStoreLength = (UINT64) (NvStorageSize - FvHeader->HeaderLength); 3587 3588 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase; 3589 mNvVariableCache = (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase; 3590 if (GetVariableStoreStatus (mNvVariableCache) != EfiValid) { 3591 FreePool (NvStorageData); 3592 DEBUG((EFI_D_ERROR, "Variable Store header is corrupted\n")); 3593 return EFI_VOLUME_CORRUPTED; 3594 } 3595 ASSERT(mNvVariableCache->Size == VariableStoreLength); 3596 3597 // 3598 // The max variable or hardware error variable size should be < variable store size. 3599 // 3600 ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) < VariableStoreLength); 3601 3602 // 3603 // Parse non-volatile variable data and get last variable offset. 3604 // 3605 NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase); 3606 while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) { 3607 VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); 3608 if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 3609 mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); 3610 } else { 3611 mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); 3612 } 3613 3614 NextVariable = GetNextVariablePtr (NextVariable); 3615 } 3616 mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase; 3617 3618 return EFI_SUCCESS; 3619 } 3620 3621 /** 3622 Flush the HOB variable to flash. 3623 3624 @param[in] VariableName Name of variable has been updated or deleted. 3625 @param[in] VendorGuid Guid of variable has been updated or deleted. 3626 3627 **/ 3628 VOID 3629 FlushHobVariableToFlash ( 3630 IN CHAR16 *VariableName, 3631 IN EFI_GUID *VendorGuid 3632 ) 3633 { 3634 EFI_STATUS Status; 3635 VARIABLE_STORE_HEADER *VariableStoreHeader; 3636 VARIABLE_HEADER *Variable; 3637 VOID *VariableData; 3638 BOOLEAN ErrorFlag; 3639 3640 ErrorFlag = FALSE; 3641 3642 // 3643 // Flush the HOB variable to flash. 3644 // 3645 if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) { 3646 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase; 3647 // 3648 // Set HobVariableBase to 0, it can avoid SetVariable to call back. 3649 // 3650 mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0; 3651 for ( Variable = GetStartPointer (VariableStoreHeader) 3652 ; IsValidVariableHeader (Variable, GetEndPointer (VariableStoreHeader)) 3653 ; Variable = GetNextVariablePtr (Variable) 3654 ) { 3655 if (Variable->State != VAR_ADDED) { 3656 // 3657 // The HOB variable has been set to DELETED state in local. 3658 // 3659 continue; 3660 } 3661 ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0); 3662 if (VendorGuid == NULL || VariableName == NULL || 3663 !CompareGuid (VendorGuid, &Variable->VendorGuid) || 3664 StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) { 3665 VariableData = GetVariableDataPtr (Variable); 3666 Status = VariableServiceSetVariable ( 3667 GetVariableNamePtr (Variable), 3668 &Variable->VendorGuid, 3669 Variable->Attributes, 3670 Variable->DataSize, 3671 VariableData 3672 ); 3673 DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", &Variable->VendorGuid, GetVariableNamePtr (Variable), Status)); 3674 } else { 3675 // 3676 // The updated or deleted variable is matched with the HOB variable. 3677 // Don't break here because we will try to set other HOB variables 3678 // since this variable could be set successfully. 3679 // 3680 Status = EFI_SUCCESS; 3681 } 3682 if (!EFI_ERROR (Status)) { 3683 // 3684 // If set variable successful, or the updated or deleted variable is matched with the HOB variable, 3685 // set the HOB variable to DELETED state in local. 3686 // 3687 DEBUG ((EFI_D_INFO, "Variable driver set the HOB variable to DELETED state in local: %g %s\n", &Variable->VendorGuid, GetVariableNamePtr (Variable))); 3688 Variable->State &= VAR_DELETED; 3689 } else { 3690 ErrorFlag = TRUE; 3691 } 3692 } 3693 if (ErrorFlag) { 3694 // 3695 // We still have HOB variable(s) not flushed in flash. 3696 // 3697 mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader; 3698 } else { 3699 // 3700 // All HOB variables have been flushed in flash. 3701 // 3702 DEBUG ((EFI_D_INFO, "Variable driver: all HOB variables have been flushed in flash.\n")); 3703 if (!AtRuntime ()) { 3704 FreePool ((VOID *) VariableStoreHeader); 3705 } 3706 } 3707 } 3708 3709 } 3710 3711 /** 3712 Initializes variable write service after FTW was ready. 2473 3713 2474 3714 @retval EFI_SUCCESS Function successfully executed. … … 2486 3726 UINT8 Data; 2487 3727 EFI_PHYSICAL_ADDRESS VariableStoreBase; 2488 VARIABLE_HEADER *Variable; 2489 VOID *VariableData; 2490 2491 VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase; 3728 EFI_PHYSICAL_ADDRESS NvStorageBase; 3729 3730 NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64); 3731 if (NvStorageBase == 0) { 3732 NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase); 3733 } 3734 VariableStoreBase = NvStorageBase + (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(NvStorageBase))->HeaderLength); 3735 3736 // 3737 // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready. 3738 // 3739 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase; 2492 3740 VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase; 2493 3741 … … 2505 3753 &mVariableModuleGlobal->NonVolatileLastVariableOffset, 2506 3754 FALSE, 2507 NULL 3755 NULL, 3756 NULL, 3757 0, 3758 FALSE 2508 3759 ); 2509 3760 if (EFI_ERROR (Status)) { … … 2514 3765 } 2515 3766 2516 2517 // 2518 // Flush the HOB variable to flash and invalidate HOB variable. 2519 // 2520 if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) { 2521 // 2522 // Clear the HobVariableBase to avoid SetVariable() updating the variable in HOB 2523 // 2524 VariableStoreHeader = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase; 2525 mVariableModuleGlobal->VariableGlobal.HobVariableBase = 0; 2526 2527 for ( Variable = GetStartPointer (VariableStoreHeader) 2528 ; (Variable < GetEndPointer (VariableStoreHeader) && IsValidVariableHeader (Variable)) 2529 ; Variable = GetNextVariablePtr (Variable) 2530 ) { 2531 ASSERT (Variable->State == VAR_ADDED); 2532 ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0); 2533 VariableData = GetVariableDataPtr (Variable); 2534 Status = VariableServiceSetVariable ( 2535 GetVariableNamePtr (Variable), 2536 &Variable->VendorGuid, 2537 Variable->Attributes, 2538 Variable->DataSize, 2539 VariableData 2540 ); 2541 ASSERT_EFI_ERROR (Status); 2542 } 2543 } 3767 FlushHobVariableToFlash (NULL, NULL); 2544 3768 2545 3769 // … … 2567 3791 VARIABLE_STORE_HEADER *VolatileVariableStore; 2568 3792 VARIABLE_STORE_HEADER *VariableStoreHeader; 2569 VARIABLE_HEADER *NextVariable;2570 EFI_PHYSICAL_ADDRESS TempVariableStoreHeader;2571 EFI_PHYSICAL_ADDRESS VariableStoreBase;2572 3793 UINT64 VariableStoreLength; 2573 3794 UINTN ScratchSize; 2574 UINTN VariableSize;2575 3795 EFI_HOB_GUID_TYPE *GuidHob; 2576 3796 … … 2586 3806 2587 3807 // 2588 // Note that in EdkII variable driver implementation, Hardware Error Record type variable2589 // is stored with common variable in the same NV region. So the platform integrator should2590 // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of2591 // PcdFlashNvStorageVariableSize.2592 //2593 ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize));2594 2595 //2596 3808 // Get HOB variable store. 2597 3809 // … … 2599 3811 if (GuidHob != NULL) { 2600 3812 VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob); 3813 VariableStoreLength = (UINT64) (GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE)); 2601 3814 if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) { 2602 mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VariableStoreHeader; 3815 mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader); 3816 if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) { 3817 FreePool (mVariableModuleGlobal); 3818 return EFI_OUT_OF_RESOURCES; 3819 } 2603 3820 } else { 2604 3821 DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n")); … … 2612 3829 VolatileVariableStore = AllocateRuntimePool (PcdGet32 (PcdVariableStoreSize) + ScratchSize); 2613 3830 if (VolatileVariableStore == NULL) { 3831 if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) { 3832 FreePool ((VOID *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase); 3833 } 2614 3834 FreePool (mVariableModuleGlobal); 2615 3835 return EFI_OUT_OF_RESOURCES; … … 2623 3843 mVariableModuleGlobal->VariableGlobal.VolatileVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) VolatileVariableStore; 2624 3844 mVariableModuleGlobal->VolatileLastVariableOffset = (UINTN) GetStartPointer (VolatileVariableStore) - (UINTN) VolatileVariableStore; 2625 mVariableModuleGlobal->FvbInstance = NULL;2626 3845 2627 3846 CopyGuid (&VolatileVariableStore->Signature, &gEfiAuthenticatedVariableGuid); … … 2633 3852 2634 3853 // 2635 // Get non-volatile variable store. 2636 // 2637 2638 TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64); 2639 if (TempVariableStoreHeader == 0) { 2640 TempVariableStoreHeader = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase); 2641 } 2642 2643 // 2644 // Check if the Firmware Volume is not corrupted 2645 // 2646 if ((((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader))->Signature != EFI_FVH_SIGNATURE) || 2647 (!CompareGuid (&gEfiSystemNvDataFvGuid, &((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader))->FileSystemGuid))) { 2648 Status = EFI_VOLUME_CORRUPTED; 2649 DEBUG ((EFI_D_ERROR, "Firmware Volume for Variable Store is corrupted\n")); 2650 goto Done; 2651 } 2652 2653 VariableStoreBase = TempVariableStoreHeader + \ 2654 (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader)) -> HeaderLength); 2655 VariableStoreLength = (UINT64) PcdGet32 (PcdFlashNvStorageVariableSize) - \ 2656 (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(TempVariableStoreHeader)) -> HeaderLength); 2657 2658 mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase; 2659 VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase; 2660 if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) { 2661 Status = EFI_VOLUME_CORRUPTED; 2662 DEBUG((EFI_D_INFO, "Variable Store header is corrupted\n")); 2663 goto Done; 2664 } 2665 ASSERT(VariableStoreHeader->Size == VariableStoreLength); 2666 2667 // 2668 // Parse non-volatile variable data and get last variable offset. 2669 // 2670 NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase); 2671 while (IsValidVariableHeader (NextVariable)) { 2672 VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); 2673 if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { 2674 mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); 2675 } else { 2676 mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); 2677 } 2678 2679 NextVariable = GetNextVariablePtr (NextVariable); 2680 } 2681 2682 mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase; 2683 2684 // 2685 // Allocate runtime memory used for a memory copy of the FLASH region. 2686 // Keep the memory and the FLASH in sync as updates occur 2687 // 2688 mNvVariableCache = AllocateRuntimeZeroPool ((UINTN)VariableStoreLength); 2689 if (mNvVariableCache == NULL) { 2690 Status = EFI_OUT_OF_RESOURCES; 2691 goto Done; 2692 } 2693 CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableStoreBase, (UINTN)VariableStoreLength); 2694 Status = EFI_SUCCESS; 2695 2696 Done: 3854 // Init non-volatile variable store. 3855 // 3856 Status = InitNonVolatileVariableStore (); 2697 3857 if (EFI_ERROR (Status)) { 3858 if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) { 3859 FreePool ((VOID *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase); 3860 } 2698 3861 FreePool (mVariableModuleGlobal); 2699 3862 FreePool (VolatileVariableStore); … … 2728 3891 EFI_FVB_ATTRIBUTES_2 Attributes; 2729 3892 3893 HandleBuffer = NULL; 2730 3894 // 2731 3895 // Get all FVB handles. -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
r48674 r58459 3 3 internal structure and functions used by Variable modules. 4 4 5 Copyright (c) 2009 - 201 2, Intel Corporation. All rights reserved.<BR>5 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 6 This program and the accompanying materials 7 7 are licensed and made available under the terms and conditions of the BSD License … … 22 22 #include <Protocol/FirmwareVolumeBlock.h> 23 23 #include <Protocol/Variable.h> 24 #include <Protocol/VariableLock.h> 24 25 #include <Library/PcdLib.h> 25 26 #include <Library/HobLib.h> … … 41 42 #include <Guid/ImageAuthentication.h> 42 43 #include <Guid/SystemNvDataGuid.h> 43 44 #define VARIABLE_RECLAIM_THRESHOLD (1024) 44 #include <Guid/FaultTolerantWrite.h> 45 #include <Guid/HardwareErrorVariable.h> 46 47 #define EFI_VARIABLE_ATTRIBUTES_MASK (EFI_VARIABLE_NON_VOLATILE | \ 48 EFI_VARIABLE_BOOTSERVICE_ACCESS | \ 49 EFI_VARIABLE_RUNTIME_ACCESS | \ 50 EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ 51 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ 52 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ 53 EFI_VARIABLE_APPEND_WRITE) 54 55 #define VARIABLE_ATTRIBUTE_BS_RT (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS) 56 #define VARIABLE_ATTRIBUTE_NV_BS_RT (VARIABLE_ATTRIBUTE_BS_RT | EFI_VARIABLE_NON_VOLATILE) 57 #define VARIABLE_ATTRIBUTE_NV_BS_RT_AT (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) 58 59 typedef struct { 60 CHAR16 *Name; 61 UINT32 Attributes; 62 } GLOBAL_VARIABLE_ENTRY; 45 63 46 64 /// … … 58 76 typedef struct { 59 77 VARIABLE_HEADER *CurrPtr; 78 // 79 // If both ADDED and IN_DELETED_TRANSITION variable are present, 80 // InDeletedTransitionPtr will point to the IN_DELETED_TRANSITION one. 81 // Otherwise, CurrPtr will point to the ADDED or IN_DELETED_TRANSITION one, 82 // and InDeletedTransitionPtr will be NULL at the same time. 83 // 84 VARIABLE_HEADER *InDeletedTransitionPtr; 60 85 VARIABLE_HEADER *EndPtr; 61 86 VARIABLE_HEADER *StartPtr; … … 87 112 EFI_GUID *Guid; 88 113 CHAR16 *Name; 89 UINT32 Attributes; 90 UINTN DataSize; 91 VOID *Data; 92 } VARIABLE_CACHE_ENTRY; 114 UINTN VariableSize; 115 } VARIABLE_ENTRY_CONSISTENCY; 116 117 typedef struct { 118 EFI_GUID Guid; 119 CHAR16 *Name; 120 LIST_ENTRY Link; 121 } VARIABLE_ENTRY; 122 123 /** 124 Flush the HOB variable to flash. 125 126 @param[in] VariableName Name of variable has been updated or deleted. 127 @param[in] VendorGuid Guid of variable has been updated or deleted. 128 129 **/ 130 VOID 131 FlushHobVariableToFlash ( 132 IN CHAR16 *VariableName, 133 IN EFI_GUID *VendorGuid 134 ); 93 135 94 136 /** … … 100 142 101 143 @param VariableBase Base address of the variable to write. 102 @param Buffer Point to the data buffer. 103 @param BufferSize The number of bytes of the data Buffer. 144 @param VariableBuffer Point to the variable data buffer. 104 145 105 146 @retval EFI_SUCCESS The function completed successfully. … … 111 152 FtwVariableSpace ( 112 153 IN EFI_PHYSICAL_ADDRESS VariableBase, 113 IN UINT8 *Buffer, 114 IN UINTN BufferSize 154 IN VARIABLE_STORE_HEADER *VariableBuffer 115 155 ); 116 156 … … 179 219 180 220 /** 221 This function is to check if the remaining variable space is enough to set 222 all Variables from argument list successfully. The purpose of the check 223 is to keep the consistency of the Variables to be in variable storage. 224 225 Note: Variables are assumed to be in same storage. 226 The set sequence of Variables will be same with the sequence of VariableEntry from argument list, 227 so follow the argument sequence to check the Variables. 228 229 @param[in] Attributes Variable attributes for Variable entries. 230 @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. 231 A NULL terminates the list. The VariableSize of 232 VARIABLE_ENTRY_CONSISTENCY is the variable data size as input. 233 It will be changed to variable total size as output. 234 235 @retval TRUE Have enough variable space to set the Variables successfully. 236 @retval FALSE No enough variable space to set the Variables successfully. 237 238 **/ 239 BOOLEAN 240 EFIAPI 241 CheckRemainingSpaceForConsistency ( 242 IN UINT32 Attributes, 243 ... 244 ); 245 246 /** 181 247 Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set, 182 248 index of associated public key is needed. … … 189 255 @param[in] KeyIndex Index of associated public key. 190 256 @param[in] MonotonicCount Value of associated monotonic count. 191 @param[in ] VariableThe variable information that is used to keep track of variable usage.257 @param[in, out] Variable The variable information that is used to keep track of variable usage. 192 258 193 259 @param[in] TimeStamp Value of associated TimeStamp. … … 206 272 IN UINT32 KeyIndex OPTIONAL, 207 273 IN UINT64 MonotonicCount OPTIONAL, 208 IN 274 IN OUT VARIABLE_POINTER_TRACK *Variable, 209 275 IN EFI_TIME *TimeStamp OPTIONAL 210 276 ); … … 347 413 348 414 /** 415 416 Variable store garbage collection and reclaim operation. 417 418 If ReclaimPubKeyStore is FALSE, reclaim variable space by deleting the obsoleted varaibles. 419 If ReclaimPubKeyStore is TRUE, reclaim invalid key in public key database and update the PubKeyIndex 420 for all the count-based authenticate variable in NV storage. 421 422 @param[in] VariableBase Base address of variable store. 423 @param[out] LastVariableOffset Offset of last variable. 424 @param[in] IsVolatile The variable store is volatile or not; 425 if it is non-volatile, need FTW. 426 @param[in, out] UpdatingPtrTrack Pointer to updating variable pointer track structure. 427 @param[in] NewVariable Pointer to new variable. 428 @param[in] NewVariableSize New variable size. 429 @param[in] ReclaimPubKeyStore Reclaim for public key database or not. 430 431 @return EFI_SUCCESS Reclaim operation has finished successfully. 432 @return EFI_OUT_OF_RESOURCES No enough memory resources or variable space. 433 @return EFI_DEVICE_ERROR The public key database doesn't exist. 434 @return Others Unexpect error happened during reclaim operation. 435 436 **/ 437 EFI_STATUS 438 Reclaim ( 439 IN EFI_PHYSICAL_ADDRESS VariableBase, 440 OUT UINTN *LastVariableOffset, 441 IN BOOLEAN IsVolatile, 442 IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack, 443 IN VARIABLE_HEADER *NewVariable, 444 IN UINTN NewVariableSize, 445 IN BOOLEAN ReclaimPubKeyStore 446 ); 447 448 /** 349 449 This function reclaims variable storage if free size is below the threshold. 350 450 … … 401 501 402 502 This code finds variable in storage blocks (Volatile or Non-Volatile). 503 504 Caution: This function may receive untrusted input. 505 This function may be invoked in SMM mode, and datasize and data are external input. 506 This function will do basic validation, before parse the data. 403 507 404 508 @param VariableName Name of Variable to be found. … … 429 533 This code Finds the Next available variable. 430 534 535 Caution: This function may receive untrusted input. 536 This function may be invoked in SMM mode. This function will do basic validation, before parse the data. 537 431 538 @param VariableNameSize Size of the variable name. 432 539 @param VariableName Pointer to variable name. … … 450 557 451 558 This code sets variable in storage blocks (Volatile or Non-Volatile). 559 560 Caution: This function may receive untrusted input. 561 This function may be invoked in SMM mode, and datasize and data are external input. 562 This function will do basic validation, before parse the data. 563 This function will parse the authentication carefully to avoid security issues, like 564 buffer overflow, integer overflow. 565 This function will check attribute carefully to avoid authentication bypass. 452 566 453 567 @param VariableName Name of Variable to be found. … … 478 592 479 593 This code returns information about the EFI variables. 594 595 Caution: This function may receive untrusted input. 596 This function may be invoked in SMM mode. This function will do basic validation, before parse the data. 480 597 481 598 @param Attributes Attributes bitmask to specify the type of variables … … 488 605 associated with the attributes specified. 489 606 607 @return EFI_SUCCESS Query successfully. 608 609 **/ 610 EFI_STATUS 611 EFIAPI 612 VariableServiceQueryVariableInfoInternal ( 613 IN UINT32 Attributes, 614 OUT UINT64 *MaximumVariableStorageSize, 615 OUT UINT64 *RemainingVariableStorageSize, 616 OUT UINT64 *MaximumVariableSize 617 ); 618 619 /** 620 621 This code returns information about the EFI variables. 622 623 Caution: This function may receive untrusted input. 624 This function may be invoked in SMM mode. This function will do basic validation, before parse the data. 625 626 @param Attributes Attributes bitmask to specify the type of variables 627 on which to return information. 628 @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available 629 for the EFI variables associated with the attributes specified. 630 @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available 631 for EFI variables associated with the attributes specified. 632 @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables 633 associated with the attributes specified. 634 490 635 @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied. 491 636 @return EFI_SUCCESS Query successfully. … … 501 646 OUT UINT64 *MaximumVariableSize 502 647 ); 503 648 649 /** 650 Mark a variable that will become read-only after leaving the DXE phase of execution. 651 652 @param[in] This The VARIABLE_LOCK_PROTOCOL instance. 653 @param[in] VariableName A pointer to the variable name that will be made read-only subsequently. 654 @param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently. 655 656 @retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked 657 as pending to be read-only. 658 @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL. 659 Or VariableName is an empty string. 660 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has 661 already been signaled. 662 @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request. 663 **/ 664 EFI_STATUS 665 EFIAPI 666 VariableLockRequestToLock ( 667 IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, 668 IN CHAR16 *VariableName, 669 IN EFI_GUID *VendorGuid 670 ); 671 504 672 extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal; 505 673 -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
r48674 r58459 3 3 and volatile storage space and install variable architecture protocol. 4 4 5 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> 5 Copyright (C) 2013, Red Hat, Inc. 6 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 6 7 This program and the accompanying materials 7 8 are licensed and made available under the terms and conditions of the BSD License … … 17 18 #include "AuthService.h" 18 19 19 extern VARIABLE_STORE_HEADER *mNvVariableCache; 20 extern VARIABLE_INFO_ENTRY *gVariableInfo; 21 EFI_HANDLE mHandle = NULL; 22 EFI_EVENT mVirtualAddressChangeEvent = NULL; 23 EFI_EVENT mFtwRegistration = NULL; 20 extern VARIABLE_STORE_HEADER *mNvVariableCache; 21 extern VARIABLE_INFO_ENTRY *gVariableInfo; 22 EFI_HANDLE mHandle = NULL; 23 EFI_EVENT mVirtualAddressChangeEvent = NULL; 24 EFI_EVENT mFtwRegistration = NULL; 25 extern LIST_ENTRY mLockedVariableList; 26 extern BOOLEAN mEndOfDxe; 27 EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock }; 24 28 25 29 /** … … 219 223 ) 220 224 { 225 LIST_ENTRY *Link; 226 VARIABLE_ENTRY *Entry; 227 EFI_STATUS Status; 228 221 229 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize); 222 230 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress); … … 234 242 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal); 235 243 EfiConvertPointer (0x0, (VOID **) &mHashCtx); 236 EfiConvertPointer (0x0, (VOID **) &mStorageArea);237 244 EfiConvertPointer (0x0, (VOID **) &mSerializationRuntimeBuffer); 238 245 EfiConvertPointer (0x0, (VOID **) &mNvVariableCache); 246 EfiConvertPointer (0x0, (VOID **) &mPubKeyStore); 247 EfiConvertPointer (0x0, (VOID **) &mCertDbStore); 248 249 // 250 // in the list of locked variables, convert the name pointers first 251 // 252 for ( Link = GetFirstNode (&mLockedVariableList) 253 ; !IsNull (&mLockedVariableList, Link) 254 ; Link = GetNextNode (&mLockedVariableList, Link) 255 ) { 256 Entry = BASE_CR (Link, VARIABLE_ENTRY, Link); 257 Status = EfiConvertPointer (0x0, (VOID **) &Entry->Name); 258 ASSERT_EFI_ERROR (Status); 259 } 260 // 261 // second, convert the list itself using UefiRuntimeLib 262 // 263 Status = EfiConvertList (0x0, &mLockedVariableList); 264 ASSERT_EFI_ERROR (Status); 239 265 } 240 266 … … 258 284 ) 259 285 { 286 // 287 // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled. 288 // 289 mEndOfDxe = TRUE; 260 290 ReclaimForOS (); 261 291 if (FeaturePcdGet (PcdVariableCollectStatistics)) { … … 264 294 } 265 295 296 /** 297 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group. 298 299 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group. 300 301 @param Event Event whose notification function is being invoked. 302 @param Context Pointer to the notification function's context. 303 304 **/ 305 VOID 306 EFIAPI 307 OnEndOfDxe ( 308 EFI_EVENT Event, 309 VOID *Context 310 ) 311 { 312 mEndOfDxe = TRUE; 313 if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) { 314 ReclaimForOS (); 315 } 316 } 266 317 267 318 /** … … 291 342 EFI_PHYSICAL_ADDRESS VariableStoreBase; 292 343 UINT64 VariableStoreLength; 344 UINTN FtwMaxBlockSize; 293 345 294 346 // … … 300 352 } 301 353 354 Status = FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize); 355 if (!EFI_ERROR (Status)) { 356 ASSERT (PcdGet32 (PcdFlashNvStorageVariableSize) <= FtwMaxBlockSize); 357 } 358 302 359 // 303 360 // Find the proper FVB protocol for variable. … … 316 373 // Mark the variable storage region of the FLASH as RUNTIME. 317 374 // 318 VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase;375 VariableStoreBase = NvStorageVariableBase + (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(NvStorageVariableBase))->HeaderLength); 319 376 VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size; 320 377 BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK); … … 324 381 Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor); 325 382 if (EFI_ERROR (Status)) { 326 DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));383 DEBUG ((DEBUG_WARN, "Variable driver failed to get flash memory attribute.\n")); 327 384 } else { 328 385 Status = gDS->SetMemorySpaceAttributes ( … … 337 394 338 395 Status = VariableWriteServiceInitialize (); 339 ASSERT_EFI_ERROR (Status); 396 if (EFI_ERROR (Status)) { 397 DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status)); 398 } 340 399 341 400 // … … 379 438 EFI_STATUS Status; 380 439 EFI_EVENT ReadyToBootEvent; 440 EFI_EVENT EndOfDxeEvent; 381 441 382 442 Status = VariableCommonInitialize (); 443 ASSERT_EFI_ERROR (Status); 444 445 Status = gBS->InstallMultipleProtocolInterfaces ( 446 &mHandle, 447 &gEdkiiVariableLockProtocolGuid, 448 &mVariableLock, 449 NULL 450 ); 383 451 ASSERT_EFI_ERROR (Status); 384 452 … … 429 497 &ReadyToBootEvent 430 498 ); 499 ASSERT_EFI_ERROR (Status); 500 501 // 502 // Register the event handling function to set the End Of DXE flag. 503 // 504 Status = gBS->CreateEventEx ( 505 EVT_NOTIFY_SIGNAL, 506 TPL_NOTIFY, 507 OnEndOfDxe, 508 NULL, 509 &gEfiEndOfDxeEventGroupGuid, 510 &EndOfDxeEvent 511 ); 512 ASSERT_EFI_ERROR (Status); 431 513 432 514 return EFI_SUCCESS; -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
r48674 r58459 1 1 ## @file 2 # Component description file for Authenticated Variable module.2 # Provides authenticated variable service 3 3 # 4 # Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> 4 # This module installs variable arch protocol and variable write arch protocol to provide 5 # variable services: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo. 6 # 7 # Caution: This module requires additional review when modified. 8 # This driver will have external input - variable data. 9 # This external input must be validated carefully to avoid security issues such as 10 # buffer overflow or integer overflow. 11 # 12 # Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR> 5 13 # This program and the accompanying materials 6 14 # are licensed and made available under the terms and conditions of the BSD License … … 14 22 [Defines] 15 23 INF_VERSION = 0x00010005 16 BASE_NAME = VariableRuntimeDxe 24 BASE_NAME = VariableAuthRuntimeDxe 25 MODULE_UNI_FILE = VariableAuthRuntimeDxe.uni 17 26 FILE_GUID = 2226F30F-3D5B-402d-9936-A97184EB4516 18 27 MODULE_TYPE = DXE_RUNTIME_DRIVER … … 35 44 AuthService.c 36 45 AuthService.h 46 Measurement.c 37 47 38 48 [Packages] … … 57 67 PlatformSecureLib 58 68 HobLib 69 TpmMeasurementLib 59 70 60 71 [Protocols] 61 gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES 62 gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES 63 gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES 64 gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES 72 gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES 73 ## CONSUMES 74 ## NOTIFY 75 gEfiFaultTolerantWriteProtocolGuid 76 gEfiVariableWriteArchProtocolGuid ## PRODUCES 77 gEfiVariableArchProtocolGuid ## PRODUCES 78 gEdkiiVariableLockProtocolGuid ## PRODUCES 79 65 80 66 81 [Guids] 67 gEfiAuthenticatedVariableGuid ## PRODUCES ## Configuration Table Guid 68 gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid 69 gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event 70 gEfiCertTypeRsa2048Sha256Guid 82 ## PRODUCES ## GUID # Variable store header 83 ## CONSUMES ## GUID # Variable store header 84 ## SOMETIMES_CONSUMES ## HOB 85 ## SOMETIMES_PRODUCES ## SystemTable 86 gEfiAuthenticatedVariableGuid 87 88 ## SOMETIMES_CONSUMES ## Variable:L"PlatformLang" 89 ## SOMETIMES_PRODUCES ## Variable:L"PlatformLang" 90 ## SOMETIMES_CONSUMES ## Variable:L"Lang" 91 ## SOMETIMES_PRODUCES ## Variable:L"Lang" 92 ## SOMETIMES_CONSUMES ## Variable:L"HwErrRecSupport" 93 ## CONSUMES ## Variable:L"SetupMode" 94 ## PRODUCES ## Variable:L"SetupMode" 95 ## SOMETIMES_CONSUMES ## Variable:L"PK" 96 ## SOMETIMES_CONSUMES ## Variable:L"KEK" 97 ## CONSUMES ## Variable:L"SecureBoot" 98 ## PRODUCES ## Variable:L"SecureBoot" 99 ## CONSUMES ## Variable:L"SignatureSupport" 100 ## PRODUCES ## Variable:L"SignatureSupport" 101 ## PRODUCES ## Variable:L"VendorKeys" 102 gEfiGlobalVariableGuid 103 104 ## SOMETIMES_CONSUMES ## Variable:L"DB" 105 ## SOMETIMES_CONSUMES ## Variable:L"DBX" 71 106 gEfiImageSecurityDatabaseGuid 72 gEfiCertX509Guid73 gEfiCertPkcs7Guid74 gEfiCertRsa2048Guid107 108 ## CONSUMES ## Variable:L"SecureBootEnable" 109 ## PRODUCES ## Variable:L"SecureBootEnable" 75 110 gEfiSecureBootEnableDisableGuid 111 112 ## CONSUMES ## Variable:L"CustomMode" 113 ## PRODUCES ## Variable:L"CustomMode" 76 114 gEfiCustomModeEnableGuid 77 gEfiSystemNvDataFvGuid ## CONSUMES 115 116 ## CONSUMES ## Variable:L"certdb" 117 ## PRODUCES ## Variable:L"certdb" 78 118 gEfiCertDbGuid 119 120 ## CONSUMES ## Variable:L"VendorKeysNv" 121 ## PRODUCES ## Variable:L"VendorKeysNv" 122 gEfiVendorKeysNvGuid 123 124 gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event 125 gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event 126 gEfiCertTypeRsa2048Sha256Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the certificate. 127 gEfiCertPkcs7Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the certificate. 128 gEfiCertX509Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. 129 gEfiSystemNvDataFvGuid ## CONSUMES ## GUID 130 gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"HwErrRec####" 131 gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB 79 132 80 133 [Pcd] 81 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize 82 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase 83 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 84 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize 85 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize 86 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize 87 gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize 134 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES 135 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES 136 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES 137 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES 138 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES 139 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES 140 gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES 141 gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## CONSUMES 88 142 89 143 [FeaturePcd] 90 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.) 144 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. 145 gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang 91 146 92 147 [Depex] 93 gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid148 TRUE 94 149 95 # [Event] 96 # ## 97 # # Event will be signaled for VIRTUAL_ADDRESS_CHANGE event. 98 # # 99 # EVENT_TYPE_NOTIFY_SIGNAL ## PRODUCES 100 # 101 # 102 150 [UserExtensions.TianoCore."ExtraFiles"] 151 VariableRuntimeDxeExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
r48674 r58459 4 4 to provide variable services. 5 5 6 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> 6 Caution: This module requires additional review when modified. 7 This driver will have external input - variable data and communicate buffer in SMM mode. 8 This external input must be validated carefully to avoid security issue like 9 buffer overflow, integer overflow. 10 11 SmmVariableHandler() will receive untrusted input and do basic validation. 12 13 Each sub function VariableServiceGetVariable(), VariableServiceGetNextVariableName(), 14 VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), 15 SmmVariableGetStatistics() should also do validation based on its own knowledge. 16 17 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 7 18 This program and the accompanying materials 8 19 are licensed and made available under the terms and conditions of the BSD License … … 18 29 #include <Protocol/SmmFirmwareVolumeBlock.h> 19 30 #include <Protocol/SmmFaultTolerantWrite.h> 31 #include <Protocol/SmmEndOfDxe.h> 32 20 33 #include <Library/SmmServicesTableLib.h> 34 #include <Library/SmmMemLib.h> 21 35 22 36 #include <Guid/AuthenticatedVariableFormat.h> … … 29 43 BOOLEAN mAtRuntime = FALSE; 30 44 EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; 31 45 UINT8 *mVariableBufferPayload = NULL; 46 UINTN mVariableBufferPayloadSize; 47 extern BOOLEAN mEndOfDxe; 48 extern BOOLEAN mEnableLocking; 49 50 /** 51 SecureBoot Hook for SetVariable. 52 53 @param[in] VariableName Name of Variable to be found. 54 @param[in] VendorGuid Variable vendor GUID. 55 56 **/ 57 VOID 58 EFIAPI 59 SecureBootHook ( 60 IN CHAR16 *VariableName, 61 IN EFI_GUID *VendorGuid 62 ) 63 { 64 return ; 65 } 66 67 /** 68 69 This code sets variable in storage blocks (Volatile or Non-Volatile). 70 71 @param VariableName Name of Variable to be found. 72 @param VendorGuid Variable vendor GUID. 73 @param Attributes Attribute value of the variable found 74 @param DataSize Size of Data found. If size is less than the 75 data, this value contains the required size. 76 @param Data Data pointer. 77 78 @return EFI_INVALID_PARAMETER Invalid parameter. 79 @return EFI_SUCCESS Set successfully. 80 @return EFI_OUT_OF_RESOURCES Resource not enough to set variable. 81 @return EFI_NOT_FOUND Not found. 82 @return EFI_WRITE_PROTECTED Variable is read-only. 83 84 **/ 85 EFI_STATUS 86 EFIAPI 87 SmmVariableSetVariable ( 88 IN CHAR16 *VariableName, 89 IN EFI_GUID *VendorGuid, 90 IN UINT32 Attributes, 91 IN UINTN DataSize, 92 IN VOID *Data 93 ) 94 { 95 EFI_STATUS Status; 96 97 // 98 // Disable write protection when the calling SetVariable() through EFI_SMM_VARIABLE_PROTOCOL. 99 // 100 mEnableLocking = FALSE; 101 Status = VariableServiceSetVariable ( 102 VariableName, 103 VendorGuid, 104 Attributes, 105 DataSize, 106 Data 107 ); 108 mEnableLocking = TRUE; 109 return Status; 110 } 111 32 112 EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = { 33 113 VariableServiceGetVariable, 34 114 VariableServiceGetNextVariableName, 35 VariableServiceSetVariable,115 SmmVariableSetVariable, 36 116 VariableServiceQueryVariableInfo 37 117 }; 38 39 118 40 119 /** … … 233 312 if (EFI_ERROR(Status)) { 234 313 *NumberHandles = 0; 314 FreePool (*Buffer); 315 *Buffer = NULL; 235 316 } 236 317 … … 241 322 /** 242 323 Get the variable statistics information from the information buffer pointed by gVariableInfo. 324 325 Caution: This function may be invoked at SMM runtime. 326 InfoEntry and InfoSize are external input. Care must be taken to make sure not security issue at runtime. 243 327 244 328 @param[in, out] InfoEntry A pointer to the buffer of variable information entry. … … 266 350 UINTN StatisticsInfoSize; 267 351 CHAR16 *InfoName; 352 EFI_GUID VendorGuid; 268 353 269 354 if (InfoEntry == NULL) { … … 277 362 278 363 StatisticsInfoSize = sizeof (VARIABLE_INFO_ENTRY) + StrSize (VariableInfo->Name); 279 if (*InfoSize < sizeof (VARIABLE_INFO_ENTRY)) {364 if (*InfoSize < StatisticsInfoSize) { 280 365 *InfoSize = StatisticsInfoSize; 281 366 return EFI_BUFFER_TOO_SMALL; … … 283 368 InfoName = (CHAR16 *)(InfoEntry + 1); 284 369 285 if (CompareGuid (&InfoEntry->VendorGuid, &mZeroGuid)) { 370 CopyGuid (&VendorGuid, &InfoEntry->VendorGuid); 371 372 if (CompareGuid (&VendorGuid, &mZeroGuid)) { 286 373 // 287 374 // Return the first variable info … … 297 384 // 298 385 while (VariableInfo != NULL) { 299 if (CompareGuid (&VariableInfo->VendorGuid, & InfoEntry->VendorGuid)) {386 if (CompareGuid (&VariableInfo->VendorGuid, &VendorGuid)) { 300 387 NameLength = StrSize (VariableInfo->Name); 301 388 if (NameLength == StrSize (InfoName)) { … … 339 426 This SMI handler provides services for the variable wrapper driver. 340 427 428 Caution: This function may receive untrusted input. 429 This variable data and communicate buffer are external input, so this function will do basic validation. 430 Each sub function VariableServiceGetVariable(), VariableServiceGetNextVariableName(), 431 VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(), 432 SmmVariableGetStatistics() should also do validation based on its own knowledge. 433 341 434 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). 342 435 @param[in] RegisterContext Points to an optional handler context which was specified when the … … 353 446 be called. 354 447 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced. 355 @retval EFI_INVALID_PARAMETER Input parameter is invalid.356 448 357 449 **/ … … 371 463 SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo; 372 464 VARIABLE_INFO_ENTRY *VariableInfo; 465 SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock; 373 466 UINTN InfoSize; 374 375 if (CommBuffer == NULL) { 376 return EFI_INVALID_PARAMETER; 377 } 378 467 UINTN NameBufferSize; 468 UINTN CommBufferPayloadSize; 469 UINTN TempCommBufferSize; 470 471 // 472 // If input is invalid, stop processing this SMI 473 // 474 if (CommBuffer == NULL || CommBufferSize == NULL) { 475 return EFI_SUCCESS; 476 } 477 478 TempCommBufferSize = *CommBufferSize; 479 480 if (TempCommBufferSize < SMM_VARIABLE_COMMUNICATE_HEADER_SIZE) { 481 DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer size invalid!\n")); 482 return EFI_SUCCESS; 483 } 484 CommBufferPayloadSize = TempCommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE; 485 if (CommBufferPayloadSize > mVariableBufferPayloadSize) { 486 DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer payload size invalid!\n")); 487 return EFI_SUCCESS; 488 } 489 490 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { 491 DEBUG ((EFI_D_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n")); 492 return EFI_SUCCESS; 493 } 494 379 495 SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer; 496 380 497 switch (SmmVariableFunctionHeader->Function) { 381 498 case SMM_VARIABLE_FUNCTION_GET_VARIABLE: 382 SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data; 499 if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) { 500 DEBUG ((EFI_D_ERROR, "GetVariable: SMM communication buffer size invalid!\n")); 501 return EFI_SUCCESS; 502 } 503 // 504 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload. 505 // 506 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize); 507 SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) mVariableBufferPayload; 508 if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) || 509 ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) { 510 // 511 // Prevent InfoSize overflow happen 512 // 513 Status = EFI_ACCESS_DENIED; 514 goto EXIT; 515 } 516 InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) 517 + SmmVariableHeader->DataSize + SmmVariableHeader->NameSize; 518 519 // 520 // SMRAM range check already covered before 521 // 522 if (InfoSize > CommBufferPayloadSize) { 523 DEBUG ((EFI_D_ERROR, "GetVariable: Data size exceed communication buffer size limit!\n")); 524 Status = EFI_ACCESS_DENIED; 525 goto EXIT; 526 } 527 528 if (SmmVariableHeader->NameSize < sizeof (CHAR16) || SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0') { 529 // 530 // Make sure VariableName is A Null-terminated string. 531 // 532 Status = EFI_ACCESS_DENIED; 533 goto EXIT; 534 } 535 383 536 Status = VariableServiceGetVariable ( 384 537 SmmVariableHeader->Name, … … 388 541 (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize 389 542 ); 543 CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize); 390 544 break; 391 545 392 546 case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME: 393 GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) SmmVariableFunctionHeader->Data; 547 if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) { 548 DEBUG ((EFI_D_ERROR, "GetNextVariableName: SMM communication buffer size invalid!\n")); 549 return EFI_SUCCESS; 550 } 551 // 552 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload. 553 // 554 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize); 555 GetNextVariableName = (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) mVariableBufferPayload; 556 if ((UINTN)(~0) - GetNextVariableName->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) { 557 // 558 // Prevent InfoSize overflow happen 559 // 560 Status = EFI_ACCESS_DENIED; 561 goto EXIT; 562 } 563 InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + GetNextVariableName->NameSize; 564 565 // 566 // SMRAM range check already covered before 567 // 568 if (InfoSize > CommBufferPayloadSize) { 569 DEBUG ((EFI_D_ERROR, "GetNextVariableName: Data size exceed communication buffer size limit!\n")); 570 Status = EFI_ACCESS_DENIED; 571 goto EXIT; 572 } 573 574 NameBufferSize = CommBufferPayloadSize - OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name); 575 if (NameBufferSize < sizeof (CHAR16) || GetNextVariableName->Name[NameBufferSize/sizeof (CHAR16) - 1] != L'\0') { 576 // 577 // Make sure input VariableName is A Null-terminated string. 578 // 579 Status = EFI_ACCESS_DENIED; 580 goto EXIT; 581 } 582 394 583 Status = VariableServiceGetNextVariableName ( 395 584 &GetNextVariableName->NameSize, … … 397 586 &GetNextVariableName->Guid 398 587 ); 588 CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize); 399 589 break; 400 590 401 591 case SMM_VARIABLE_FUNCTION_SET_VARIABLE: 402 SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) SmmVariableFunctionHeader->Data; 592 if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) { 593 DEBUG ((EFI_D_ERROR, "SetVariable: SMM communication buffer size invalid!\n")); 594 return EFI_SUCCESS; 595 } 596 // 597 // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload. 598 // 599 CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize); 600 SmmVariableHeader = (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *) mVariableBufferPayload; 601 if (((UINTN)(~0) - SmmVariableHeader->DataSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) || 602 ((UINTN)(~0) - SmmVariableHeader->NameSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + SmmVariableHeader->DataSize)) { 603 // 604 // Prevent InfoSize overflow happen 605 // 606 Status = EFI_ACCESS_DENIED; 607 goto EXIT; 608 } 609 InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) 610 + SmmVariableHeader->DataSize + SmmVariableHeader->NameSize; 611 612 // 613 // SMRAM range check already covered before 614 // Data buffer should not contain SMM range 615 // 616 if (InfoSize > CommBufferPayloadSize) { 617 DEBUG ((EFI_D_ERROR, "SetVariable: Data size exceed communication buffer size limit!\n")); 618 Status = EFI_ACCESS_DENIED; 619 goto EXIT; 620 } 621 622 if (SmmVariableHeader->NameSize < sizeof (CHAR16) || SmmVariableHeader->Name[SmmVariableHeader->NameSize/sizeof (CHAR16) - 1] != L'\0') { 623 // 624 // Make sure VariableName is A Null-terminated string. 625 // 626 Status = EFI_ACCESS_DENIED; 627 goto EXIT; 628 } 629 403 630 Status = VariableServiceSetVariable ( 404 631 SmmVariableHeader->Name, … … 411 638 412 639 case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO: 640 if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) { 641 DEBUG ((EFI_D_ERROR, "QueryVariableInfo: SMM communication buffer size invalid!\n")); 642 return EFI_SUCCESS; 643 } 413 644 QueryVariableInfo = (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *) SmmVariableFunctionHeader->Data; 645 414 646 Status = VariableServiceQueryVariableInfo ( 415 647 QueryVariableInfo->Attributes, … … 421 653 422 654 case SMM_VARIABLE_FUNCTION_READY_TO_BOOT: 655 mEndOfDxe = TRUE; 656 if (AtRuntime()) { 657 Status = EFI_UNSUPPORTED; 658 break; 659 } 423 660 ReclaimForOS (); 424 661 Status = EFI_SUCCESS; … … 432 669 case SMM_VARIABLE_FUNCTION_GET_STATISTICS: 433 670 VariableInfo = (VARIABLE_INFO_ENTRY *) SmmVariableFunctionHeader->Data; 434 InfoSize = *CommBufferSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data); 671 InfoSize = TempCommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE; 672 673 // 674 // Do not need to check SmmVariableFunctionHeader->Data in SMRAM here. 675 // It is covered by previous CommBuffer check 676 // 677 678 if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) { 679 DEBUG ((EFI_D_ERROR, "GetStatistics: SMM communication buffer in SMRAM!\n")); 680 Status = EFI_ACCESS_DENIED; 681 goto EXIT; 682 } 683 435 684 Status = SmmVariableGetStatistics (VariableInfo, &InfoSize); 436 *CommBufferSize = InfoSize + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_HEADER, Data);685 *CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE; 437 686 break; 438 687 688 case SMM_VARIABLE_FUNCTION_LOCK_VARIABLE: 689 if (mEndOfDxe) { 690 Status = EFI_ACCESS_DENIED; 691 } else { 692 VariableToLock = (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *) SmmVariableFunctionHeader->Data; 693 Status = VariableLockRequestToLock ( 694 NULL, 695 VariableToLock->Name, 696 &VariableToLock->Guid 697 ); 698 } 699 break; 700 439 701 default: 440 ASSERT (FALSE);441 702 Status = EFI_UNSUPPORTED; 442 703 } 443 704 705 EXIT: 706 444 707 SmmVariableFunctionHeader->ReturnStatus = Status; 445 446 708 return EFI_SUCCESS; 447 709 } 448 710 711 /** 712 SMM END_OF_DXE protocol notification event handler. 713 714 @param Protocol Points to the protocol's unique identifier 715 @param Interface Points to the interface instance 716 @param Handle The handle on which the interface was installed 717 718 @retval EFI_SUCCESS SmmEndOfDxeCallback runs successfully 719 720 **/ 721 EFI_STATUS 722 EFIAPI 723 SmmEndOfDxeCallback ( 724 IN CONST EFI_GUID *Protocol, 725 IN VOID *Interface, 726 IN EFI_HANDLE Handle 727 ) 728 { 729 DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n")); 730 mEndOfDxe = TRUE; 731 if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) { 732 ReclaimForOS (); 733 } 734 return EFI_SUCCESS; 735 } 449 736 450 737 /** … … 474 761 EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; 475 762 EFI_PHYSICAL_ADDRESS NvStorageVariableBase; 763 UINTN FtwMaxBlockSize; 476 764 477 765 if (mVariableModuleGlobal->FvbInstance != NULL) { … … 487 775 } 488 776 777 Status = FtwProtocol->GetMaxBlockSize (FtwProtocol, &FtwMaxBlockSize); 778 if (!EFI_ERROR (Status)) { 779 ASSERT (PcdGet32 (PcdFlashNvStorageVariableSize) <= FtwMaxBlockSize); 780 } 781 489 782 // 490 783 // Find the proper FVB protocol for variable. … … 502 795 503 796 Status = VariableWriteServiceInitialize (); 504 ASSERT_EFI_ERROR (Status); 797 if (EFI_ERROR (Status)) { 798 DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status)); 799 } 505 800 506 801 // … … 541 836 EFI_HANDLE VariableHandle; 542 837 VOID *SmmFtwRegistration; 543 838 VOID *SmmEndOfDxeRegistration; 839 544 840 // 545 841 // Variable initialize. … … 560 856 ASSERT_EFI_ERROR (Status); 561 857 858 mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) + 859 OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER); 860 861 Status = gSmst->SmmAllocatePool ( 862 EfiRuntimeServicesData, 863 mVariableBufferPayloadSize, 864 (VOID **)&mVariableBufferPayload 865 ); 866 ASSERT_EFI_ERROR (Status); 867 562 868 /// 563 869 /// Register SMM variable SMI handler … … 579 885 580 886 // 887 // Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function. 888 // 889 Status = gSmst->SmmRegisterProtocolNotify ( 890 &gEfiSmmEndOfDxeProtocolGuid, 891 SmmEndOfDxeCallback, 892 &SmmEndOfDxeRegistration 893 ); 894 ASSERT_EFI_ERROR (Status); 895 896 // 581 897 // Register FtwNotificationEvent () notify function. 582 898 // -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
r48674 r58459 1 1 ## @file 2 # Component description file for SMM Authenticated Variable module.2 # Provides SMM authenticated variable service 3 3 # 4 4 # This module installs SMM variable protocol into SMM protocol database, … … 7 7 # Dxe driver that the SMM variable service is ready. 8 8 # This module should be used with SMM Runtime DXE module together. The 9 # SMM Runtime DXE module would installvariable arch protocol and variable9 # SMM Runtime DXE module installs variable arch protocol and variable 10 10 # write arch protocol based on SMM variable module. 11 11 # 12 # Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR> 12 # Caution: This module requires additional review when modified. 13 # This driver will have external input - variable data and communicate buffer in SMM mode. 14 # This external input must be validated carefully to avoid security issues such as 15 # buffer overflow or integer overflow. 16 # The whole SMM authentication variable design relies on the integrity of flash part and SMM. 17 # which is assumed to be protected by platform. All variable code and metadata in flash/SMM Memory 18 # may not be modified without authorization. If platform fails to protect these resources, 19 # the authentication service provided in this driver will be broken, and the behavior is undefined. 20 # 21 # Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 13 22 # This program and the accompanying materials 14 23 # are licensed and made available under the terms and conditions of the BSD License … … 22 31 [Defines] 23 32 INF_VERSION = 0x00010005 24 BASE_NAME = VariableSmm 33 BASE_NAME = VariableAuthSmm 34 MODULE_UNI_FILE = VariableAuthSmm.uni 25 35 FILE_GUID = D34BDC5E-968A-40f5-A48C-E594F45AE211 26 36 MODULE_TYPE = DXE_SMM_DRIVER … … 63 73 PlatformSecureLib 64 74 HobLib 75 SmmMemLib 65 76 66 77 [Protocols] 67 gEfiSmmFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES 68 gEfiSmmVariableProtocolGuid ## ALWAYS_PRODUCES 69 gEfiSmmFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES 78 gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES 79 80 ## PRODUCES 81 ## UNDEFINED # SmiHandlerRegister 82 gEfiSmmVariableProtocolGuid 83 84 ## CONSUMES 85 ## NOTIFY 86 gEfiSmmFaultTolerantWriteProtocolGuid 87 gEfiSmmEndOfDxeProtocolGuid ## NOTIFY 70 88 71 89 [Guids] 72 gEfiAuthenticatedVariableGuid ## PRODUCES ## Configuration Table Guid 73 gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid 74 gSmmVariableWriteGuid ## PRODUCES ## SMM Variable Write Guid 75 gEfiCertTypeRsa2048Sha256Guid 90 ## PRODUCES ## GUID # Variable store header 91 ## CONSUMES ## GUID # Variable store header 92 ## SOMETIMES_CONSUMES ## HOB 93 gEfiAuthenticatedVariableGuid 94 95 ## SOMETIMES_CONSUMES ## Variable:L"PlatformLang" 96 ## SOMETIMES_PRODUCES ## Variable:L"PlatformLang" 97 ## SOMETIMES_CONSUMES ## Variable:L"Lang" 98 ## SOMETIMES_PRODUCES ## Variable:L"Lang" 99 ## SOMETIMES_CONSUMES ## Variable:L"HwErrRecSupport" 100 ## CONSUMES ## Variable:L"SetupMode" 101 ## PRODUCES ## Variable:L"SetupMode" 102 ## SOMETIMES_CONSUMES ## Variable:L"PK" 103 ## SOMETIMES_CONSUMES ## Variable:L"KEK" 104 ## CONSUMES ## Variable:L"SecureBoot" 105 ## PRODUCES ## Variable:L"SecureBoot" 106 ## CONSUMES ## Variable:L"SignatureSupport" 107 ## PRODUCES ## Variable:L"SignatureSupport" 108 ## PRODUCES ## Variable:L"VendorKeys" 109 gEfiGlobalVariableGuid 110 111 ## SOMETIMES_CONSUMES ## Variable:L"DB" 112 ## SOMETIMES_CONSUMES ## Variable:L"DBX" 76 113 gEfiImageSecurityDatabaseGuid 77 gEfiCertX509Guid78 gEfiCertPkcs7Guid79 gEfiCertRsa2048Guid114 115 ## CONSUMES ## Variable:L"SecureBootEnable" 116 ## PRODUCES ## Variable:L"SecureBootEnable" 80 117 gEfiSecureBootEnableDisableGuid 118 119 ## CONSUMES ## Variable:L"CustomMode" 120 ## PRODUCES ## Variable:L"CustomMode" 81 121 gEfiCustomModeEnableGuid 82 gEfiSystemNvDataFvGuid ## CONSUMES 122 123 ## CONSUMES ## Variable:L"certdb" 124 ## PRODUCES ## Variable:L"certdb" 83 125 gEfiCertDbGuid 84 126 127 ## CONSUMES ## Variable:L"VendorKeysNv" 128 ## PRODUCES ## Variable:L"VendorKeysNv" 129 gEfiVendorKeysNvGuid 130 131 gSmmVariableWriteGuid ## PRODUCES ## GUID # Install protocol 132 gEfiCertTypeRsa2048Sha256Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the format of the CertData. 133 gEfiCertPkcs7Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the format of the CertData. 134 gEfiCertX509Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. 135 gEfiSystemNvDataFvGuid ## CONSUMES ## GUID 136 gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"HwErrRec####" 137 gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB 138 85 139 [Pcd] 86 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize 87 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase 88 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 89 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize 90 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize 91 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize 92 gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize 140 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES 141 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES 142 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES 143 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES 144 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES 145 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES 146 gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES 147 gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## CONSUMES 93 148 94 149 [FeaturePcd] 95 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.) 150 gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. 151 gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang 96 152 97 153 [Depex] 98 154 TRUE 99 100 155 156 [UserExtensions.TianoCore."ExtraFiles"] 157 VariableSmmExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
r48674 r58459 4 4 based on SMM variable module. 5 5 6 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> 6 Caution: This module requires additional review when modified. 7 This driver will have external input - variable data. 8 This external input must be validated carefully to avoid security issue like 9 buffer overflow, integer overflow. 10 11 RuntimeServiceGetVariable() and RuntimeServiceSetVariable() are external API 12 to receive data buffer. The size should be checked carefully. 13 14 InitCommunicateBuffer() is really function to check the variable data size. 15 16 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 7 17 This program and the accompanying materials 8 18 are licensed and made available under the terms and conditions of the BSD License … … 20 30 #include <Protocol/SmmCommunication.h> 21 31 #include <Protocol/SmmVariable.h> 32 #include <Protocol/VariableLock.h> 22 33 23 34 #include <Library/UefiBootServicesTableLib.h> … … 43 54 UINT8 *mVariableBufferPhysical = NULL; 44 55 UINTN mVariableBufferSize; 45 56 UINTN mVariableBufferPayloadSize; 57 EFI_LOCK mVariableServicesLock; 58 EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; 59 60 /** 61 SecureBoot Hook for SetVariable. 62 63 @param[in] VariableName Name of Variable to be found. 64 @param[in] VendorGuid Variable vendor GUID. 65 66 **/ 67 VOID 68 EFIAPI 69 SecureBootHook ( 70 IN CHAR16 *VariableName, 71 IN EFI_GUID *VendorGuid 72 ); 73 74 /** 75 Acquires lock only at boot time. Simply returns at runtime. 76 77 This is a temperary function that will be removed when 78 EfiAcquireLock() in UefiLib can handle the call in UEFI 79 Runtimer driver in RT phase. 80 It calls EfiAcquireLock() at boot time, and simply returns 81 at runtime. 82 83 @param Lock A pointer to the lock to acquire. 84 85 **/ 86 VOID 87 AcquireLockOnlyAtBootTime ( 88 IN EFI_LOCK *Lock 89 ) 90 { 91 if (!EfiAtRuntime ()) { 92 EfiAcquireLock (Lock); 93 } 94 } 95 96 /** 97 Releases lock only at boot time. Simply returns at runtime. 98 99 This is a temperary function which will be removed when 100 EfiReleaseLock() in UefiLib can handle the call in UEFI 101 Runtimer driver in RT phase. 102 It calls EfiReleaseLock() at boot time and simply returns 103 at runtime. 104 105 @param Lock A pointer to the lock to release. 106 107 **/ 108 VOID 109 ReleaseLockOnlyAtBootTime ( 110 IN EFI_LOCK *Lock 111 ) 112 { 113 if (!EfiAtRuntime ()) { 114 EfiReleaseLock (Lock); 115 } 116 } 46 117 47 118 /** … … 50 121 The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + 51 122 DataSize. 123 124 Caution: This function may receive untrusted input. 125 The data size external input, so this function will validate it carefully to avoid buffer overflow. 52 126 53 127 @param[out] DataPtr Points to the data in the communicate buffer. … … 116 190 } 117 191 192 /** 193 Mark a variable that will become read-only after leaving the DXE phase of execution. 194 195 @param[in] This The VARIABLE_LOCK_PROTOCOL instance. 196 @param[in] VariableName A pointer to the variable name that will be made read-only subsequently. 197 @param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently. 198 199 @retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked 200 as pending to be read-only. 201 @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL. 202 Or VariableName is an empty string. 203 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has 204 already been signaled. 205 @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request. 206 **/ 207 EFI_STATUS 208 EFIAPI 209 VariableLockRequestToLock ( 210 IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, 211 IN CHAR16 *VariableName, 212 IN EFI_GUID *VendorGuid 213 ) 214 { 215 EFI_STATUS Status; 216 UINTN VariableNameSize; 217 UINTN PayloadSize; 218 SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock; 219 220 if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { 221 return EFI_INVALID_PARAMETER; 222 } 223 224 VariableNameSize = StrSize (VariableName); 225 VariableToLock = NULL; 226 227 // 228 // If VariableName exceeds SMM payload limit. Return failure 229 // 230 if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name)) { 231 return EFI_INVALID_PARAMETER; 232 } 233 234 AcquireLockOnlyAtBootTime(&mVariableServicesLock); 235 236 // 237 // Init the communicate buffer. The buffer data size is: 238 // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize. 239 // 240 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name) + VariableNameSize; 241 Status = InitCommunicateBuffer ((VOID **) &VariableToLock, PayloadSize, SMM_VARIABLE_FUNCTION_LOCK_VARIABLE); 242 if (EFI_ERROR (Status)) { 243 goto Done; 244 } 245 ASSERT (VariableToLock != NULL); 246 247 CopyGuid (&VariableToLock->Guid, VendorGuid); 248 VariableToLock->NameSize = VariableNameSize; 249 CopyMem (VariableToLock->Name, VariableName, VariableToLock->NameSize); 250 251 // 252 // Send data to SMM. 253 // 254 Status = SendCommunicateBuffer (PayloadSize); 255 256 Done: 257 ReleaseLockOnlyAtBootTime (&mVariableServicesLock); 258 return Status; 259 } 118 260 119 261 /** 120 262 This code finds variable in storage blocks (Volatile or Non-Volatile). 263 264 Caution: This function may receive untrusted input. 265 The data size is external input, so this function will validate it carefully to avoid buffer overflow. 121 266 122 267 @param[in] VariableName Name of Variable to be found. … … 146 291 UINTN PayloadSize; 147 292 SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *SmmVariableHeader; 293 UINTN TempDataSize; 294 UINTN VariableNameSize; 148 295 149 296 if (VariableName == NULL || VendorGuid == NULL || DataSize == NULL) { … … 154 301 return EFI_INVALID_PARAMETER; 155 302 } 156 303 304 TempDataSize = *DataSize; 305 VariableNameSize = StrSize (VariableName); 306 SmmVariableHeader = NULL; 307 308 // 309 // If VariableName exceeds SMM payload limit. Return failure 310 // 311 if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) { 312 return EFI_INVALID_PARAMETER; 313 } 314 315 AcquireLockOnlyAtBootTime(&mVariableServicesLock); 316 157 317 // 158 318 // Init the communicate buffer. The buffer data size is: 159 319 // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize. 160 320 // 161 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + StrSize (VariableName); 321 if (TempDataSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize) { 322 // 323 // If output data buffer exceed SMM payload limit. Trim output buffer to SMM payload size 324 // 325 TempDataSize = mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize; 326 } 327 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + VariableNameSize + TempDataSize; 328 162 329 Status = InitCommunicateBuffer ((VOID **)&SmmVariableHeader, PayloadSize, SMM_VARIABLE_FUNCTION_GET_VARIABLE); 163 330 if (EFI_ERROR (Status)) { 164 return Status;331 goto Done; 165 332 } 166 333 ASSERT (SmmVariableHeader != NULL); 167 334 168 335 CopyGuid (&SmmVariableHeader->Guid, VendorGuid); 169 SmmVariableHeader->DataSize = *DataSize;170 SmmVariableHeader->NameSize = StrSize (VariableName);336 SmmVariableHeader->DataSize = TempDataSize; 337 SmmVariableHeader->NameSize = VariableNameSize; 171 338 if (Attributes == NULL) { 172 339 SmmVariableHeader->Attributes = 0; … … 184 351 // Get data from SMM. 185 352 // 186 *DataSize = SmmVariableHeader->DataSize; 353 if (Status == EFI_SUCCESS || Status == EFI_BUFFER_TOO_SMALL) { 354 // 355 // SMM CommBuffer DataSize can be a trimed value 356 // Only update DataSize when needed 357 // 358 *DataSize = SmmVariableHeader->DataSize; 359 } 187 360 if (Attributes != NULL) { 188 361 *Attributes = SmmVariableHeader->Attributes; … … 190 363 191 364 if (EFI_ERROR (Status)) { 192 return Status;365 goto Done; 193 366 } 194 367 195 368 CopyMem (Data, (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize, SmmVariableHeader->DataSize); 196 369 370 Done: 371 ReleaseLockOnlyAtBootTime (&mVariableServicesLock); 197 372 return Status; 198 373 } … … 223 398 UINTN PayloadSize; 224 399 SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *SmmGetNextVariableName; 400 UINTN OutVariableNameSize; 401 UINTN InVariableNameSize; 225 402 226 403 if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) { 227 404 return EFI_INVALID_PARAMETER; 228 405 } 229 406 407 OutVariableNameSize = *VariableNameSize; 408 InVariableNameSize = StrSize (VariableName); 409 SmmGetNextVariableName = NULL; 410 411 // 412 // If input string exceeds SMM payload limit. Return failure 413 // 414 if (InVariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) { 415 return EFI_INVALID_PARAMETER; 416 } 417 418 AcquireLockOnlyAtBootTime(&mVariableServicesLock); 419 230 420 // 231 421 // Init the communicate buffer. The buffer data size is: 232 422 // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize. 233 423 // 234 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + *VariableNameSize; 424 if (OutVariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) { 425 // 426 // If output buffer exceed SMM payload limit. Trim output buffer to SMM payload size 427 // 428 OutVariableNameSize = mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name); 429 } 430 // 431 // Payload should be Guid + NameSize + MAX of Input & Output buffer 432 // 433 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + MAX (OutVariableNameSize, InVariableNameSize); 434 235 435 Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName, PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME); 236 436 if (EFI_ERROR (Status)) { 237 return Status;437 goto Done; 238 438 } 239 439 ASSERT (SmmGetNextVariableName != NULL); 240 440 241 SmmGetNextVariableName->NameSize = *VariableNameSize; 441 // 442 // SMM comm buffer->NameSize is buffer size for return string 443 // 444 SmmGetNextVariableName->NameSize = OutVariableNameSize; 445 242 446 CopyGuid (&SmmGetNextVariableName->Guid, VendorGuid); 243 CopyMem (SmmGetNextVariableName->Name, VariableName, *VariableNameSize); 447 // 448 // Copy whole string 449 // 450 CopyMem (SmmGetNextVariableName->Name, VariableName, InVariableNameSize); 451 if (OutVariableNameSize > InVariableNameSize) { 452 ZeroMem ((UINT8 *) SmmGetNextVariableName->Name + InVariableNameSize, OutVariableNameSize - InVariableNameSize); 453 } 244 454 245 455 // … … 251 461 // Get data from SMM. 252 462 // 253 *VariableNameSize = SmmGetNextVariableName->NameSize; 463 if (Status == EFI_SUCCESS || Status == EFI_BUFFER_TOO_SMALL) { 464 // 465 // SMM CommBuffer NameSize can be a trimed value 466 // Only update VariableNameSize when needed 467 // 468 *VariableNameSize = SmmGetNextVariableName->NameSize; 469 } 254 470 if (EFI_ERROR (Status)) { 255 return Status;471 goto Done; 256 472 } 257 473 … … 259 475 CopyMem (VariableName, SmmGetNextVariableName->Name, SmmGetNextVariableName->NameSize); 260 476 477 Done: 478 ReleaseLockOnlyAtBootTime (&mVariableServicesLock); 261 479 return Status; 262 480 } … … 264 482 /** 265 483 This code sets variable in storage blocks (Volatile or Non-Volatile). 484 485 Caution: This function may receive untrusted input. 486 The data size and data are external input, so this function will validate it carefully to avoid buffer overflow. 266 487 267 488 @param[in] VariableName Name of Variable to be found. … … 292 513 UINTN PayloadSize; 293 514 SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *SmmVariableHeader; 515 UINTN VariableNameSize; 294 516 295 517 // … … 303 525 return EFI_INVALID_PARAMETER; 304 526 } 305 527 528 VariableNameSize = StrSize (VariableName); 529 SmmVariableHeader = NULL; 530 531 // 532 // If VariableName or DataSize exceeds SMM payload limit. Return failure 533 // 534 if ((VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) || 535 (DataSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - VariableNameSize)){ 536 return EFI_INVALID_PARAMETER; 537 } 538 539 AcquireLockOnlyAtBootTime(&mVariableServicesLock); 540 306 541 // 307 542 // Init the communicate buffer. The buffer data size is: 308 543 // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize. 309 544 // 310 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + StrSize (VariableName)+ DataSize;545 PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + VariableNameSize + DataSize; 311 546 Status = InitCommunicateBuffer ((VOID **)&SmmVariableHeader, PayloadSize, SMM_VARIABLE_FUNCTION_SET_VARIABLE); 312 547 if (EFI_ERROR (Status)) { 313 return Status;548 goto Done; 314 549 } 315 550 ASSERT (SmmVariableHeader != NULL); … … 317 552 CopyGuid ((EFI_GUID *) &SmmVariableHeader->Guid, VendorGuid); 318 553 SmmVariableHeader->DataSize = DataSize; 319 SmmVariableHeader->NameSize = StrSize (VariableName);554 SmmVariableHeader->NameSize = VariableNameSize; 320 555 SmmVariableHeader->Attributes = Attributes; 321 556 CopyMem (SmmVariableHeader->Name, VariableName, SmmVariableHeader->NameSize); … … 326 561 // 327 562 Status = SendCommunicateBuffer (PayloadSize); 328 563 564 Done: 565 ReleaseLockOnlyAtBootTime (&mVariableServicesLock); 566 567 if (!EfiAtRuntime ()) { 568 if (!EFI_ERROR (Status)) { 569 SecureBootHook ( 570 VariableName, 571 VendorGuid 572 ); 573 } 574 } 329 575 return Status; 330 576 } … … 361 607 SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *SmmQueryVariableInfo; 362 608 609 SmmQueryVariableInfo = NULL; 610 363 611 if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) { 364 612 return EFI_INVALID_PARAMETER; 365 613 } 366 614 615 AcquireLockOnlyAtBootTime(&mVariableServicesLock); 616 367 617 // 368 618 // Init the communicate buffer. The buffer data size is: … … 372 622 Status = InitCommunicateBuffer ((VOID **)&SmmQueryVariableInfo, PayloadSize, SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO); 373 623 if (EFI_ERROR (Status)) { 374 return Status;624 goto Done; 375 625 } 376 626 ASSERT (SmmQueryVariableInfo != NULL); … … 383 633 Status = SendCommunicateBuffer (PayloadSize); 384 634 if (EFI_ERROR (Status)) { 385 return Status;635 goto Done; 386 636 } 387 637 … … 392 642 *MaximumVariableStorageSize = SmmQueryVariableInfo->MaximumVariableStorageSize; 393 643 *RemainingVariableStorageSize = SmmQueryVariableInfo->RemainingVariableStorageSize; 394 395 return EFI_SUCCESS; 644 645 Done: 646 ReleaseLockOnlyAtBootTime (&mVariableServicesLock); 647 return Status; 396 648 } 397 649 … … 502 754 503 755 // 504 // Allocate memory for variable store. 505 // 506 mVariableBufferSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE; 507 mVariableBufferSize += MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)); 756 // Allocate memory for variable communicate buffer. 757 // 758 mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) + 759 OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER); 760 mVariableBufferSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize; 508 761 mVariableBuffer = AllocateRuntimePool (mVariableBufferSize); 509 762 ASSERT (mVariableBuffer != NULL); … … 586 839 ) 587 840 { 841 EFI_STATUS Status; 588 842 VOID *SmmVariableRegistration; 589 843 VOID *SmmVariableWriteRegistration; 590 844 EFI_EVENT OnReadyToBootEvent; 591 845 EFI_EVENT ExitBootServiceEvent; 592 846 847 EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY); 848 849 mVariableLock.RequestToLock = VariableLockRequestToLock; 850 Status = gBS->InstallMultipleProtocolInterfaces ( 851 &mHandle, 852 &gEdkiiVariableLockProtocolGuid, 853 &mVariableLock, 854 NULL 855 ); 856 ASSERT_EFI_ERROR (Status); 857 593 858 // 594 859 // Smm variable service is ready -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
r48674 r58459 1 1 ## @file 2 # Component description file for Authenticated Variable SmmRuntimeDxe module.2 # Runtime DXE part corresponding to SMM authenticated variable module 3 3 # 4 # This module is the Runtime DXE part correspond to SMM variable module. It 5 # installs variable arch protocol and variable write arch protocol and works 6 # with SMM variable module together. 4 # This module installs variable arch protocol and variable write arch protocol to provide 5 # variable service. This module need work together with SMM authenticated variable module. 7 6 # 8 # Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> 7 # Caution: This module requires additional review when modified. 8 # This driver will have external input - variable data. 9 # This external input must be validated carefully to avoid security issues such as 10 # buffer overflow or integer overflow. 11 # The whole SMM authentication variable design relies on the integrity of flash part and SMM. 12 # which is assumed to be protected by platform. All variable code and metadata in flash/SMM Memory 13 # may not be modified without authorization. If platform fails to protect these resources, 14 # the authentication service provided in this driver will be broken, and the behavior is undefined. 15 # 16 # Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 9 17 # This program and the accompanying materials 10 18 # are licensed and made available under the terms and conditions of the BSD License … … 18 26 [Defines] 19 27 INF_VERSION = 0x00010005 20 BASE_NAME = VariableSmmRuntimeDxe 28 BASE_NAME = VariableAuthSmmRuntimeDxe 29 MODULE_UNI_FILE = VariableAuthSmmRuntimeDxe.uni 21 30 FILE_GUID = 067E2381-7234-4798-B49C-D5FECBFF6D07 22 31 MODULE_TYPE = DXE_RUNTIME_DRIVER … … 34 43 [Sources] 35 44 VariableSmmRuntimeDxe.c 45 Measurement.c 36 46 37 47 [Packages] … … 49 59 UefiDriverEntryPoint 50 60 PcdLib 61 TpmMeasurementLib 51 62 52 63 [Protocols] 53 gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES 54 gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES 55 gEfiSmmCommunicationProtocolGuid 64 gEfiVariableWriteArchProtocolGuid ## PRODUCES 65 gEfiVariableArchProtocolGuid ## PRODUCES 66 gEfiSmmCommunicationProtocolGuid ## CONSUMES 67 gEdkiiVariableLockProtocolGuid ## PRODUCES 68 69 ## CONSUMES 70 ## NOTIFY 71 ## UNDEFINED # Used to do smm communication 56 72 gEfiSmmVariableProtocolGuid 57 73 58 74 [Guids] 59 gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event 75 gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event 76 gEfiEventExitBootServicesGuid ## CONSUMES ## Event 77 78 ## CONSUMES ## UNDEFINED # Locate protocol 79 ## CONSUMES ## UNDEFINED # Protocol notify 60 80 gSmmVariableWriteGuid 81 82 83 ## SOMETIMES_CONSUMES ## Variable:L"PK" 84 ## SOMETIMES_CONSUMES ## Variable:L"KEK" 85 ## SOMETIMES_CONSUMES ## Variable:L"SecureBoot" 86 gEfiGlobalVariableGuid 87 88 ## SOMETIMES_CONSUMES ## Variable:L"DB" 89 ## SOMETIMES_CONSUMES ## Variable:L"DBX" 90 gEfiImageSecurityDatabaseGuid 61 91 62 92 [Pcd] 63 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize 64 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize 65 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase 66 93 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES 94 gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES 95 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES 96 67 97 [Depex] 68 98 gEfiSmmCommunicationProtocolGuid 99 100 [UserExtensions.TianoCore."ExtraFiles"] 101 VariableSmmRuntimeDxeExtra.uni -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfig.vfr
r48674 r58459 2 2 VFR file used by the SecureBoot configuration component. 3 3 4 Copyright (c) 2011 - 201 2, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 33 33 34 34 subtitle text = STRING_TOKEN(STR_NULL); 35 35 36 text 37 help = STRING_TOKEN(STR_SECURE_BOOT_STATE_HELP), 38 text = STRING_TOKEN(STR_SECURE_BOOT_STATE_PROMPT), 39 text = STRING_TOKEN(STR_SECURE_BOOT_STATE_CONTENT); 40 36 41 // 37 42 // Define of Check Box: Attempt Secure Boot … … 39 44 suppressif TRUE; 40 45 checkbox varid = SECUREBOOT_CONFIGURATION.HideSecureBoot, 46 questionid = KEY_HIDE_SECURE_BOOT, 41 47 prompt = STRING_TOKEN(STR_NULL), 42 48 help = STRING_TOKEN(STR_NULL), 49 flags = INTERACTIVE, 43 50 endcheckbox; 44 51 endif; … … 48 55 // 49 56 grayoutif ideqval SECUREBOOT_CONFIGURATION.HideSecureBoot == 1; 50 checkbox varid = SECUREBOOT_CONFIGURATION. SecureBootState,57 checkbox varid = SECUREBOOT_CONFIGURATION.AttemptSecureBoot, 51 58 questionid = KEY_SECURE_BOOT_ENABLE, 52 59 prompt = STRING_TOKEN(STR_SECURE_BOOT_PROMPT), 53 60 help = STRING_TOKEN(STR_SECURE_BOOT_HELP), 54 flags = INTERACTIVE ,61 flags = INTERACTIVE | RESET_REQUIRED, 55 62 endcheckbox; 56 63 endif; … … 59 66 // Display of Oneof: 'Secure Boot Mode' 60 67 // 61 oneof varid = SECUREBOOT_CONFIGURATION.SecureBootMode, 62 questionid = KEY_SECURE_BOOT_MODE, 63 prompt = STRING_TOKEN(STR_SECURE_BOOT_MODE_PROMPT), 64 help = STRING_TOKEN(STR_SECURE_BOOT_MODE_HELP), 65 flags = INTERACTIVE, 66 option text = STRING_TOKEN(STR_STANDARD_MODE), value = SECURE_BOOT_MODE_STANDARD, flags = DEFAULT; 67 option text = STRING_TOKEN(STR_CUSTOM_MODE), value = SECURE_BOOT_MODE_CUSTOM, flags = 0; 68 endoneof; 68 disableif TRUE; 69 oneof varid = SECUREBOOT_CONFIGURATION.SecureBootMode, 70 prompt = STRING_TOKEN(STR_SECURE_BOOT_MODE_PROMPT), 71 help = STRING_TOKEN(STR_SECURE_BOOT_MODE_HELP), 72 flags = INTERACTIVE, 73 option text = STRING_TOKEN(STR_STANDARD_MODE), value = SECURE_BOOT_MODE_STANDARD, flags = 0; 74 option text = STRING_TOKEN(STR_CUSTOM_MODE), value = SECURE_BOOT_MODE_CUSTOM, flags = 0; 75 endoneof; 76 endif; 77 oneof name = SecureBootMode, 78 questionid = KEY_SECURE_BOOT_MODE, 79 prompt = STRING_TOKEN(STR_SECURE_BOOT_MODE_PROMPT), 80 help = STRING_TOKEN(STR_SECURE_BOOT_MODE_HELP), 81 flags = INTERACTIVE | NUMERIC_SIZE_1, 82 option text = STRING_TOKEN(STR_STANDARD_MODE), value = SECURE_BOOT_MODE_STANDARD, flags = DEFAULT; 83 option text = STRING_TOKEN(STR_CUSTOM_MODE), value = SECURE_BOOT_MODE_CUSTOM, flags = 0; 84 endoneof; 69 85 70 86 // … … 72 88 // Display of 'Current Secure Boot Mode' 73 89 // 74 suppressif ideqval SECUREBOOT_CONFIGURATION.SecureBootMode== SECURE_BOOT_MODE_STANDARD;90 suppressif questionref(SecureBootMode) == SECURE_BOOT_MODE_STANDARD; 75 91 grayoutif NOT ideqval SECUREBOOT_CONFIGURATION.PhysicalPresent == 1; 76 92 goto FORMID_SECURE_BOOT_OPTION_FORM, … … 159 175 prompt = STRING_TOKEN(STR_DELETE_PK), 160 176 help = STRING_TOKEN(STR_DELETE_PK_HELP), 161 flags = INTERACTIVE ,177 flags = INTERACTIVE | RESET_REQUIRED, 162 178 endcheckbox; 163 179 endif; … … 480 496 help = STRING_TOKEN(STR_SAVE_AND_EXIT), 481 497 text = STRING_TOKEN(STR_SAVE_AND_EXIT), 482 text = STRING_TOKEN(STR_NULL),483 498 flags = INTERACTIVE, 484 499 key = KEY_VALUE_SAVE_AND_EXIT_PK; … … 487 502 help = STRING_TOKEN(STR_NO_SAVE_AND_EXIT), 488 503 text = STRING_TOKEN(STR_NO_SAVE_AND_EXIT), 489 text = STRING_TOKEN(STR_NULL),490 504 flags = INTERACTIVE, 491 505 key = KEY_VALUE_NO_SAVE_AND_EXIT_PK; -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDevicePath.c
r48674 r58459 2 2 Internal function defines the default device path string for SecureBoot configuration module. 3 3 4 Copyright (c) 2012 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 14 14 15 15 #include "SecureBootConfigImpl.h" 16 17 /**18 Concatenates a formatted unicode string to allocated pool.19 The caller must free the resulting buffer.20 21 @param[in, out] Str Tracks the allocated pool, size in use, and amount of pool allocated.22 @param[in] Fmt The format string23 @param[in] ... The data will be printed.24 25 @return Allocated buffer with the formatted string printed in it.26 The caller must free the allocated buffer.27 The buffer allocation is not packed.28 29 **/30 CHAR16 *31 EFIAPI32 CatPrint (33 IN OUT POOL_PRINT *Str,34 IN CHAR16 *Fmt,35 ...36 )37 {38 UINT16 *AppendStr;39 VA_LIST Args;40 UINTN StringSize;41 42 AppendStr = AllocateZeroPool (0x1000);43 if (AppendStr == NULL) {44 return Str->Str;45 }46 47 VA_START (Args, Fmt);48 UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);49 VA_END (Args);50 if (NULL == Str->Str) {51 StringSize = StrSize (AppendStr);52 Str->Str = AllocateZeroPool (StringSize);53 ASSERT (Str->Str != NULL);54 } else {55 StringSize = StrSize (AppendStr);56 StringSize += (StrSize (Str->Str) - sizeof (UINT16));57 58 Str->Str = ReallocatePool (59 StrSize (Str->Str),60 StringSize,61 Str->Str62 );63 ASSERT (Str->Str != NULL);64 }65 66 Str->Maxlen = MAX_CHAR * sizeof (UINT16);67 if (StringSize < Str->Maxlen) {68 StrCat (Str->Str, AppendStr);69 Str->Len = StringSize - sizeof (UINT16);70 }71 72 FreePool (AppendStr);73 return Str->Str;74 }75 76 /**77 Convert Device Path to a Unicode string for printing.78 79 @param[in, out] Str The buffer holding the output string.80 This buffer contains the length of the string and81 the maixmum length reserved for the string buffer.82 @param[in] DevPath The device path.83 84 **/85 VOID86 DevPathPci (87 IN OUT POOL_PRINT *Str,88 IN VOID *DevPath89 )90 {91 PCI_DEVICE_PATH *Pci;92 93 Pci = DevPath;94 CatPrint (Str, L"Pci(%x|%x)", (UINTN) Pci->Device, (UINTN) Pci->Function);95 }96 97 /**98 Convert Device Path to a Unicode string for printing.99 100 @param[in, out] Str The buffer holding the output string.101 This buffer contains the length of the string and102 the maixmum length reserved for the string buffer.103 @param[in] DevPath The device path.104 105 **/106 VOID107 DevPathPccard (108 IN OUT POOL_PRINT *Str,109 IN VOID *DevPath110 )111 {112 PCCARD_DEVICE_PATH *Pccard;113 114 Pccard = DevPath;115 CatPrint (Str, L"Pcmcia(Function%x)", (UINTN) Pccard->FunctionNumber);116 }117 118 /**119 Convert Device Path to a Unicode string for printing.120 121 @param[in, out] Str The buffer holding the output string.122 This buffer contains the length of the string and123 the maixmum length reserved for the string buffer.124 @param[in] DevPath The device path.125 126 **/127 VOID128 DevPathMemMap (129 IN OUT POOL_PRINT *Str,130 IN VOID *DevPath131 )132 {133 MEMMAP_DEVICE_PATH *MemMap;134 135 MemMap = DevPath;136 CatPrint (137 Str,138 L"MemMap(%d:%lx-%lx)",139 (UINTN) MemMap->MemoryType,140 MemMap->StartingAddress,141 MemMap->EndingAddress142 );143 }144 145 /**146 Convert Device Path to a Unicode string for printing.147 148 @param[in, out] Str The buffer holding the output string.149 This buffer contains the length of the string and150 the maixmum length reserved for the string buffer.151 @param[in] DevPath The device path.152 153 **/154 VOID155 DevPathController (156 IN OUT POOL_PRINT *Str,157 IN VOID *DevPath158 )159 {160 CONTROLLER_DEVICE_PATH *Controller;161 162 Controller = DevPath;163 CatPrint (Str, L"Ctrl(%d)", (UINTN) Controller->ControllerNumber);164 }165 166 167 /**168 Convert Vendor device path to device name.169 170 @param[in, out] Str The buffer store device name171 @param[in] DevPath Pointer to vendor device path172 173 **/174 VOID175 DevPathVendor (176 IN OUT POOL_PRINT *Str,177 IN VOID *DevPath178 )179 {180 VENDOR_DEVICE_PATH *Vendor;181 CHAR16 *Type;182 UINTN DataLength;183 UINTN Index;184 UINT32 FlowControlMap;185 186 UINT16 Info;187 188 Vendor = DevPath;189 190 switch (DevicePathType (&Vendor->Header)) {191 case HARDWARE_DEVICE_PATH:192 Type = L"Hw";193 break;194 195 case MESSAGING_DEVICE_PATH:196 Type = L"Msg";197 if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {198 CatPrint (Str, L"VenPcAnsi()");199 return ;200 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {201 CatPrint (Str, L"VenVt100()");202 return ;203 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {204 CatPrint (Str, L"VenVt100Plus()");205 return ;206 } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {207 CatPrint (Str, L"VenUft8()");208 return ;209 } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid )) {210 FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);211 switch (FlowControlMap & 0x00000003) {212 case 0:213 CatPrint (Str, L"UartFlowCtrl(%s)", L"None");214 break;215 216 case 1:217 CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");218 break;219 220 case 2:221 CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");222 break;223 224 default:225 break;226 }227 228 return ;229 230 } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {231 CatPrint (232 Str,233 L"SAS(%lx,%lx,%x,",234 ((SAS_DEVICE_PATH *) Vendor)->SasAddress,235 ((SAS_DEVICE_PATH *) Vendor)->Lun,236 (UINTN) ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort237 );238 Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);239 if ((Info & 0x0f) == 0) {240 CatPrint (Str, L"NoTopology,0,0,0,");241 } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {242 CatPrint (243 Str,244 L"%s,%s,%s,",245 ((Info & (0x1 << 4)) != 0) ? L"SATA" : L"SAS",246 ((Info & (0x1 << 5)) != 0) ? L"External" : L"Internal",247 ((Info & (0x1 << 6)) != 0) ? L"Expanded" : L"Direct"248 );249 if ((Info & 0x0f) == 1) {250 CatPrint (Str, L"0,");251 } else {252 CatPrint (Str, L"%x,", (UINTN) ((Info >> 8) & 0xff));253 }254 } else {255 CatPrint (Str, L"0,0,0,0,");256 }257 258 CatPrint (Str, L"%x)", (UINTN) ((SAS_DEVICE_PATH *) Vendor)->Reserved);259 return ;260 261 } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {262 CatPrint (Str, L"DebugPort()");263 return ;264 }265 break;266 267 case MEDIA_DEVICE_PATH:268 Type = L"Media";269 break;270 271 default:272 Type = L"?";273 break;274 }275 276 CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);277 DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);278 if (DataLength > 0) {279 CatPrint (Str, L",");280 for (Index = 0; Index < DataLength; Index++) {281 CatPrint (Str, L"%02x", (UINTN) ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);282 }283 }284 CatPrint (Str, L")");285 }286 287 /**288 Convert Device Path to a Unicode string for printing.289 290 @param[in, out] Str The buffer holding the output string.291 This buffer contains the length of the string and292 the maixmum length reserved for the string buffer.293 @param[in] DevPath The device path.294 295 **/296 VOID297 DevPathAcpi (298 IN OUT POOL_PRINT *Str,299 IN VOID *DevPath300 )301 {302 ACPI_HID_DEVICE_PATH *Acpi;303 304 Acpi = DevPath;305 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {306 CatPrint (Str, L"Acpi(PNP%04x,%x)", (UINTN) EISA_ID_TO_NUM (Acpi->HID), (UINTN) Acpi->UID);307 } else {308 CatPrint (Str, L"Acpi(%08x,%x)", (UINTN) Acpi->HID, (UINTN) Acpi->UID);309 }310 }311 312 /**313 Convert Device Path to a Unicode string for printing.314 315 @param[in, out] Str The buffer holding the output string.316 This buffer contains the length of the string and317 the maixmum length reserved for the string buffer.318 @param[in] DevPath The device path.319 320 **/321 VOID322 DevPathExtendedAcpi (323 IN OUT POOL_PRINT *Str,324 IN VOID *DevPath325 )326 {327 ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;328 329 //330 // Index for HID, UID and CID strings, 0 for non-exist331 //332 UINT16 HIDSTRIdx;333 UINT16 UIDSTRIdx;334 UINT16 CIDSTRIdx;335 UINT16 Index;336 UINT16 Length;337 UINT16 Anchor;338 CHAR8 *AsChar8Array;339 340 HIDSTRIdx = 0;341 UIDSTRIdx = 0;342 CIDSTRIdx = 0;343 ExtendedAcpi = DevPath;344 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) ExtendedAcpi);345 346 AsChar8Array = (CHAR8 *) ExtendedAcpi;347 348 //349 // find HIDSTR350 //351 Anchor = 16;352 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {353 ;354 }355 if (Index > Anchor) {356 HIDSTRIdx = Anchor;357 }358 //359 // find UIDSTR360 //361 Anchor = (UINT16) (Index + 1);362 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {363 ;364 }365 if (Index > Anchor) {366 UIDSTRIdx = Anchor;367 }368 //369 // find CIDSTR370 //371 Anchor = (UINT16) (Index + 1);372 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {373 ;374 }375 if (Index > Anchor) {376 CIDSTRIdx = Anchor;377 }378 379 if (HIDSTRIdx == 0 && CIDSTRIdx == 0 && ExtendedAcpi->UID == 0) {380 CatPrint (Str, L"AcpiExp(");381 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {382 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));383 } else {384 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);385 }386 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {387 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));388 } else {389 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);390 }391 if (UIDSTRIdx != 0) {392 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);393 } else {394 CatPrint (Str, L"\"\")");395 }396 } else {397 CatPrint (Str, L"AcpiEx(");398 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {399 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));400 } else {401 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);402 }403 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {404 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));405 } else {406 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);407 }408 CatPrint (Str, L"%x,", (UINTN) ExtendedAcpi->UID);409 410 if (HIDSTRIdx != 0) {411 CatPrint (Str, L"%a,", AsChar8Array + HIDSTRIdx);412 } else {413 CatPrint (Str, L"\"\",");414 }415 if (CIDSTRIdx != 0) {416 CatPrint (Str, L"%a,", AsChar8Array + CIDSTRIdx);417 } else {418 CatPrint (Str, L"\"\",");419 }420 if (UIDSTRIdx != 0) {421 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);422 } else {423 CatPrint (Str, L"\"\")");424 }425 }426 427 }428 429 /**430 Convert Device Path to a Unicode string for printing.431 432 @param[in, out] Str The buffer holding the output string.433 This buffer contains the length of the string and434 the maixmum length reserved for the string buffer.435 @param[in] DevPath The device path.436 437 **/438 VOID439 DevPathAdrAcpi (440 IN OUT POOL_PRINT *Str,441 IN VOID *DevPath442 )443 {444 ACPI_ADR_DEVICE_PATH *AcpiAdr;445 UINT16 Index;446 UINT16 Length;447 UINT16 AdditionalAdrCount;448 449 AcpiAdr = DevPath;450 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);451 AdditionalAdrCount = (UINT16) ((Length - 8) / 4);452 453 CatPrint (Str, L"AcpiAdr(%x", (UINTN) AcpiAdr->ADR);454 for (Index = 0; Index < AdditionalAdrCount; Index++) {455 CatPrint (Str, L",%x", (UINTN) *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));456 }457 CatPrint (Str, L")");458 }459 460 /**461 Convert Device Path to a Unicode string for printing.462 463 @param[in, out] Str The buffer holding the output string.464 This buffer contains the length of the string and465 the maixmum length reserved for the string buffer.466 @param[in] DevPath The device path.467 468 **/469 VOID470 DevPathAtapi (471 IN OUT POOL_PRINT *Str,472 IN VOID *DevPath473 )474 {475 ATAPI_DEVICE_PATH *Atapi;476 477 Atapi = DevPath;478 CatPrint (479 Str,480 L"Ata(%s,%s)",481 (Atapi->PrimarySecondary != 0)? L"Secondary" : L"Primary",482 (Atapi->SlaveMaster != 0)? L"Slave" : L"Master"483 );484 }485 486 /**487 Convert Device Path to a Unicode string for printing.488 489 @param[in, out] Str The buffer holding the output string.490 This buffer contains the length of the string and491 the maixmum length reserved for the string buffer.492 @param[in] DevPath The device path.493 494 **/495 VOID496 DevPathScsi (497 IN OUT POOL_PRINT *Str,498 IN VOID *DevPath499 )500 {501 SCSI_DEVICE_PATH *Scsi;502 503 Scsi = DevPath;504 CatPrint (Str, L"Scsi(Pun%x,Lun%x)", (UINTN) Scsi->Pun, (UINTN) Scsi->Lun);505 }506 507 /**508 Convert Device Path to a Unicode string for printing.509 510 @param[in, out] Str The buffer holding the output string.511 This buffer contains the length of the string and512 the maixmum length reserved for the string buffer.513 @param[in] DevPath The device path.514 515 **/516 VOID517 DevPathFibre (518 IN OUT POOL_PRINT *Str,519 IN VOID *DevPath520 )521 {522 FIBRECHANNEL_DEVICE_PATH *Fibre;523 524 Fibre = DevPath;525 CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);526 }527 528 /**529 Convert Device Path to a Unicode string for printing.530 531 @param[in, out] Str The buffer holding the output string.532 This buffer contains the length of the string and533 the maixmum length reserved for the string buffer.534 @param[in] DevPath The device path.535 536 **/537 VOID538 DevPath1394 (539 IN OUT POOL_PRINT *Str,540 IN VOID *DevPath541 )542 {543 F1394_DEVICE_PATH *F1394Path;544 545 F1394Path = DevPath;546 CatPrint (Str, L"1394(%lx)", &F1394Path->Guid);547 }548 549 /**550 Convert Device Path to a Unicode string for printing.551 552 @param[in, out] Str The buffer holding the output string.553 This buffer contains the length of the string and554 the maixmum length reserved for the string buffer.555 @param[in] DevPath The device path.556 557 **/558 VOID559 DevPathUsb (560 IN OUT POOL_PRINT *Str,561 IN VOID *DevPath562 )563 {564 USB_DEVICE_PATH *Usb;565 566 Usb = DevPath;567 CatPrint (Str, L"Usb(%x,%x)", (UINTN) Usb->ParentPortNumber, (UINTN) Usb->InterfaceNumber);568 }569 570 /**571 Convert Device Path to a Unicode string for printing.572 573 @param[in, out] Str The buffer holding the output string.574 This buffer contains the length of the string and575 the maixmum length reserved for the string buffer.576 @param[in] DevPath The device path.577 578 **/579 VOID580 DevPathUsbWWID (581 IN OUT POOL_PRINT *Str,582 IN VOID *DevPath583 )584 {585 USB_WWID_DEVICE_PATH *UsbWWId;586 587 UsbWWId = DevPath;588 CatPrint (589 Str,590 L"UsbWwid(%x,%x,%x,\"WWID\")",591 (UINTN) UsbWWId->VendorId,592 (UINTN) UsbWWId->ProductId,593 (UINTN) UsbWWId->InterfaceNumber594 );595 }596 597 /**598 Convert Device Path to a Unicode string for printing.599 600 @param[in, out] Str The buffer holding the output string.601 This buffer contains the length of the string and602 the maixmum length reserved for the string buffer.603 @param[in] DevPath The device path.604 605 **/606 VOID607 DevPathLogicalUnit (608 IN OUT POOL_PRINT *Str,609 IN VOID *DevPath610 )611 {612 DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;613 614 LogicalUnit = DevPath;615 CatPrint (Str, L"Unit(%x)", (UINTN) LogicalUnit->Lun);616 }617 618 /**619 Convert Device Path to a Unicode string for printing.620 621 @param[in, out] Str The buffer holding the output string.622 This buffer contains the length of the string and623 the maixmum length reserved for the string buffer.624 @param[in] DevPath The device path.625 626 **/627 VOID628 DevPathUsbClass (629 IN OUT POOL_PRINT *Str,630 IN VOID *DevPath631 )632 {633 USB_CLASS_DEVICE_PATH *UsbClass;634 635 UsbClass = DevPath;636 CatPrint (637 Str,638 L"Usb Class(%x,%x,%x,%x,%x)",639 (UINTN) UsbClass->VendorId,640 (UINTN) UsbClass->ProductId,641 (UINTN) UsbClass->DeviceClass,642 (UINTN) UsbClass->DeviceSubClass,643 (UINTN) UsbClass->DeviceProtocol644 );645 }646 647 /**648 Convert Device Path to a Unicode string for printing.649 650 @param[in, out] Str The buffer holding the output string.651 This buffer contains the length of the string and652 the maixmum length reserved for the string buffer.653 @param[in] DevPath The device path.654 655 **/656 VOID657 DevPathSata (658 IN OUT POOL_PRINT *Str,659 IN VOID *DevPath660 )661 {662 SATA_DEVICE_PATH *Sata;663 664 Sata = DevPath;665 if ((Sata->PortMultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) != 0) {666 CatPrint (667 Str,668 L"Sata(%x,%x)",669 (UINTN) Sata->HBAPortNumber,670 (UINTN) Sata->Lun671 );672 } else {673 CatPrint (674 Str,675 L"Sata(%x,%x,%x)",676 (UINTN) Sata->HBAPortNumber,677 (UINTN) Sata->PortMultiplierPortNumber,678 (UINTN) Sata->Lun679 );680 }681 }682 683 /**684 Convert Device Path to a Unicode string for printing.685 686 @param[in, out] Str The buffer holding the output string.687 This buffer contains the length of the string and688 the maixmum length reserved for the string buffer.689 @param[in] DevPath The device path.690 691 **/692 VOID693 DevPathI2O (694 IN OUT POOL_PRINT *Str,695 IN VOID *DevPath696 )697 {698 I2O_DEVICE_PATH *I2OPath;699 700 I2OPath = DevPath;701 CatPrint (Str, L"I2O(%x)", (UINTN) I2OPath->Tid);702 }703 704 /**705 Convert Device Path to a Unicode string for printing.706 707 @param[in, out] Str The buffer holding the output string.708 This buffer contains the length of the string and709 the maixmum length reserved for the string buffer.710 @param[in] DevPath The device path.711 712 **/713 VOID714 DevPathMacAddr (715 IN OUT POOL_PRINT *Str,716 IN VOID *DevPath717 )718 {719 MAC_ADDR_DEVICE_PATH *MACDevPath;720 UINTN HwAddressSize;721 UINTN Index;722 723 MACDevPath = DevPath;724 725 HwAddressSize = sizeof (EFI_MAC_ADDRESS);726 if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {727 HwAddressSize = 6;728 }729 730 CatPrint (Str, L"Mac(");731 732 for (Index = 0; Index < HwAddressSize; Index++) {733 CatPrint (Str, L"%02x", (UINTN) MACDevPath->MacAddress.Addr[Index]);734 }735 736 CatPrint (Str, L")");737 }738 739 /**740 Convert Device Path to a Unicode string for printing.741 742 @param[in, out] Str The buffer holding the output string.743 This buffer contains the length of the string and744 the maixmum length reserved for the string buffer.745 @param[in] DevPath The device path.746 747 **/748 VOID749 DevPathIPv4 (750 IN OUT POOL_PRINT *Str,751 IN VOID *DevPath752 )753 {754 IPv4_DEVICE_PATH *IPDevPath;755 756 IPDevPath = DevPath;757 CatPrint (758 Str,759 L"IPv4(%d.%d.%d.%d:%d)",760 (UINTN) IPDevPath->RemoteIpAddress.Addr[0],761 (UINTN) IPDevPath->RemoteIpAddress.Addr[1],762 (UINTN) IPDevPath->RemoteIpAddress.Addr[2],763 (UINTN) IPDevPath->RemoteIpAddress.Addr[3],764 (UINTN) IPDevPath->RemotePort765 );766 }767 768 /**769 Convert Device Path to a Unicode string for printing.770 771 @param[in, out] Str The buffer holding the output string.772 This buffer contains the length of the string and773 the maixmum length reserved for the string buffer.774 @param[in] DevPath The device path.775 776 **/777 VOID778 DevPathIPv6 (779 IN OUT POOL_PRINT *Str,780 IN VOID *DevPath781 )782 {783 IPv6_DEVICE_PATH *IPv6DevPath;784 785 IPv6DevPath = DevPath;786 CatPrint (787 Str,788 L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",789 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[0],790 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[1],791 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[2],792 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[3],793 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[4],794 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[5],795 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[6],796 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[7],797 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[8],798 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[9],799 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[10],800 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[11],801 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[12],802 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[13],803 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[14],804 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[15]805 );806 }807 808 /**809 Convert Device Path to a Unicode string for printing.810 811 @param[in, out] Str The buffer holding the output string.812 This buffer contains the length of the string and813 the maixmum length reserved for the string buffer.814 @param[in] DevPath The device path.815 816 **/817 VOID818 DevPathInfiniBand (819 IN OUT POOL_PRINT *Str,820 IN VOID *DevPath821 )822 {823 INFINIBAND_DEVICE_PATH *InfiniBand;824 825 InfiniBand = DevPath;826 CatPrint (827 Str,828 L"Infiniband(%x,%g,%lx,%lx,%lx)",829 (UINTN) InfiniBand->ResourceFlags,830 InfiniBand->PortGid,831 InfiniBand->ServiceId,832 InfiniBand->TargetPortId,833 InfiniBand->DeviceId834 );835 }836 837 /**838 Convert Device Path to a Unicode string for printing.839 840 @param[in, out] Str The buffer holding the output string.841 This buffer contains the length of the string and842 the maixmum length reserved for the string buffer.843 @param[in] DevPath The device path.844 845 **/846 VOID847 DevPathUart (848 IN OUT POOL_PRINT *Str,849 IN VOID *DevPath850 )851 {852 UART_DEVICE_PATH *Uart;853 CHAR8 Parity;854 855 Uart = DevPath;856 switch (Uart->Parity) {857 case 0:858 Parity = 'D';859 break;860 861 case 1:862 Parity = 'N';863 break;864 865 case 2:866 Parity = 'E';867 break;868 869 case 3:870 Parity = 'O';871 break;872 873 case 4:874 Parity = 'M';875 break;876 877 case 5:878 Parity = 'S';879 break;880 881 default:882 Parity = 'x';883 break;884 }885 886 if (Uart->BaudRate == 0) {887 CatPrint (Str, L"Uart(DEFAULT,%c,", Parity);888 } else {889 CatPrint (Str, L"Uart(%ld,%c,", Uart->BaudRate, Parity);890 }891 892 if (Uart->DataBits == 0) {893 CatPrint (Str, L"D,");894 } else {895 CatPrint (Str, L"%d,", (UINTN) Uart->DataBits);896 }897 898 switch (Uart->StopBits) {899 case 0:900 CatPrint (Str, L"D)");901 break;902 903 case 1:904 CatPrint (Str, L"1)");905 break;906 907 case 2:908 CatPrint (Str, L"1.5)");909 break;910 911 case 3:912 CatPrint (Str, L"2)");913 break;914 915 default:916 CatPrint (Str, L"x)");917 break;918 }919 }920 921 /**922 Convert Device Path to a Unicode string for printing.923 924 @param[in, out] Str The buffer holding the output string.925 This buffer contains the length of the string and926 the maixmum length reserved for the string buffer.927 @param[in] DevPath The device path.928 929 **/930 VOID931 DevPathiSCSI (932 IN OUT POOL_PRINT *Str,933 IN VOID *DevPath934 )935 {936 ISCSI_DEVICE_PATH_WITH_NAME *IScsi;937 UINT16 Options;938 939 IScsi = DevPath;940 CatPrint (941 Str,942 L"iSCSI(%a,%x,%lx,",943 IScsi->TargetName,944 (UINTN) IScsi->TargetPortalGroupTag,945 IScsi->Lun946 );947 948 Options = IScsi->LoginOption;949 CatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");950 CatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");951 if (((Options >> 11) & 0x0001) != 0) {952 CatPrint (Str, L"%s,", L"None");953 } else if (((Options >> 12) & 0x0001) != 0) {954 CatPrint (Str, L"%s,", L"CHAP_UNI");955 } else {956 CatPrint (Str, L"%s,", L"CHAP_BI");957 958 }959 960 CatPrint (Str, L"%s)", (IScsi->NetworkProtocol == 0) ? L"TCP" : L"reserved");961 }962 963 /**964 Convert Device Path to a Unicode string for printing.965 966 @param[in, out] Str The buffer holding the output string.967 This buffer contains the length of the string and968 the maixmum length reserved for the string buffer.969 @param[in] DevPath The device path.970 971 **/972 VOID973 DevPathVlan (974 IN OUT POOL_PRINT *Str,975 IN VOID *DevPath976 )977 {978 VLAN_DEVICE_PATH *Vlan;979 980 Vlan = DevPath;981 CatPrint (Str, L"Vlan(%d)", (UINTN) Vlan->VlanId);982 }983 984 /**985 Convert Device Path to a Unicode string for printing.986 987 @param[in, out] Str The buffer holding the output string.988 This buffer contains the length of the string and989 the maixmum length reserved for the string buffer.990 @param[in] DevPath The device path.991 992 **/993 VOID994 DevPathHardDrive (995 IN OUT POOL_PRINT *Str,996 IN VOID *DevPath997 )998 {999 HARDDRIVE_DEVICE_PATH *Hd;1000 1001 Hd = DevPath;1002 switch (Hd->SignatureType) {1003 case SIGNATURE_TYPE_MBR:1004 CatPrint (1005 Str,1006 L"HD(Part%d,Sig%08x)",1007 (UINTN) Hd->PartitionNumber,1008 (UINTN) *((UINT32 *) (&(Hd->Signature[0])))1009 );1010 break;1011 1012 case SIGNATURE_TYPE_GUID:1013 CatPrint (1014 Str,1015 L"HD(Part%d,Sig%g)",1016 (UINTN) Hd->PartitionNumber,1017 (EFI_GUID *) &(Hd->Signature[0])1018 );1019 break;1020 1021 default:1022 CatPrint (1023 Str,1024 L"HD(Part%d,MBRType=%02x,SigType=%02x)",1025 (UINTN) Hd->PartitionNumber,1026 (UINTN) Hd->MBRType,1027 (UINTN) Hd->SignatureType1028 );1029 break;1030 }1031 }1032 1033 /**1034 Convert Device Path to a Unicode string for printing.1035 1036 @param[in, out] Str The buffer holding the output string.1037 This buffer contains the length of the string and1038 the maixmum length reserved for the string buffer.1039 @param[in] DevPath The device path.1040 1041 **/1042 VOID1043 DevPathCDROM (1044 IN OUT POOL_PRINT *Str,1045 IN VOID *DevPath1046 )1047 {1048 CDROM_DEVICE_PATH *Cd;1049 1050 Cd = DevPath;1051 CatPrint (Str, L"CDROM(Entry%x)", (UINTN) Cd->BootEntry);1052 }1053 1054 /**1055 Convert Device Path to a Unicode string for printing.1056 1057 @param[in, out] Str The buffer holding the output string.1058 This buffer contains the length of the string and1059 the maixmum length reserved for the string buffer.1060 @param[in] DevPath The device path.1061 1062 **/1063 VOID1064 DevPathFilePath (1065 IN OUT POOL_PRINT *Str,1066 IN VOID *DevPath1067 )1068 {1069 FILEPATH_DEVICE_PATH *Fp;1070 1071 Fp = DevPath;1072 CatPrint (Str, L"%s", Fp->PathName);1073 }1074 1075 /**1076 Convert Device Path to a Unicode string for printing.1077 1078 @param[in, out] Str The buffer holding the output string.1079 This buffer contains the length of the string and1080 the maixmum length reserved for the string buffer.1081 @param[in] DevPath The device path.1082 1083 **/1084 VOID1085 DevPathMediaProtocol (1086 IN OUT POOL_PRINT *Str,1087 IN VOID *DevPath1088 )1089 {1090 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;1091 1092 MediaProt = DevPath;1093 CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);1094 }1095 1096 /**1097 Convert Device Path to a Unicode string for printing.1098 1099 @param[in, out] Str The buffer holding the output string.1100 This buffer contains the length of the string and1101 the maixmum length reserved for the string buffer.1102 @param[in] DevPath The device path.1103 1104 **/1105 VOID1106 DevPathFvFilePath (1107 IN OUT POOL_PRINT *Str,1108 IN VOID *DevPath1109 )1110 {1111 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;1112 1113 FvFilePath = DevPath;1114 CatPrint (Str, L"%g", &FvFilePath->FvFileName);1115 }1116 1117 /**1118 Convert Device Path to a Unicode string for printing.1119 1120 @param[in, out] Str The buffer holding the output string.1121 This buffer contains the length of the string and1122 the maixmum length reserved for the string buffer.1123 @param[in] DevPath The device path.1124 1125 **/1126 VOID1127 DevPathRelativeOffsetRange (1128 IN OUT POOL_PRINT *Str,1129 IN VOID *DevPath1130 )1131 {1132 MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;1133 1134 Offset = DevPath;1135 CatPrint (1136 Str,1137 L"Offset(%lx,%lx)",1138 Offset->StartingOffset,1139 Offset->EndingOffset1140 );1141 }1142 1143 /**1144 Convert Device Path to a Unicode string for printing.1145 1146 @param[in, out] Str The buffer holding the output string.1147 This buffer contains the length of the string and1148 the maixmum length reserved for the string buffer.1149 @param[in] DevPath The device path.1150 1151 **/1152 VOID1153 DevPathBssBss (1154 IN OUT POOL_PRINT *Str,1155 IN VOID *DevPath1156 )1157 {1158 BBS_BBS_DEVICE_PATH *Bbs;1159 CHAR16 *Type;1160 1161 Bbs = DevPath;1162 switch (Bbs->DeviceType) {1163 case BBS_TYPE_FLOPPY:1164 Type = L"Floppy";1165 break;1166 1167 case BBS_TYPE_HARDDRIVE:1168 Type = L"Harddrive";1169 break;1170 1171 case BBS_TYPE_CDROM:1172 Type = L"CDROM";1173 break;1174 1175 case BBS_TYPE_PCMCIA:1176 Type = L"PCMCIA";1177 break;1178 1179 case BBS_TYPE_USB:1180 Type = L"Usb";1181 break;1182 1183 case BBS_TYPE_EMBEDDED_NETWORK:1184 Type = L"Net";1185 break;1186 1187 case BBS_TYPE_BEV:1188 Type = L"BEV";1189 break;1190 1191 default:1192 Type = L"?";1193 break;1194 }1195 CatPrint (Str, L"Legacy-%s", Type);1196 }1197 1198 /**1199 Convert Device Path to a Unicode string for printing.1200 1201 @param[in, out] Str The buffer holding the output string.1202 This buffer contains the length of the string and1203 the maixmum length reserved for the string buffer.1204 @param[in] DevPath The device path.1205 1206 **/1207 VOID1208 DevPathEndInstance (1209 IN OUT POOL_PRINT *Str,1210 IN VOID *DevPath1211 )1212 {1213 CatPrint (Str, L",");1214 }1215 1216 /**1217 Convert Device Path to a Unicode string for printing.1218 1219 @param[in, out] Str The buffer holding the output string.1220 This buffer contains the length of the string and1221 the maixmum length reserved for the string buffer.1222 @param[in] DevPath The device path.1223 1224 **/1225 VOID1226 DevPathNodeUnknown (1227 IN OUT POOL_PRINT *Str,1228 IN VOID *DevPath1229 )1230 {1231 CatPrint (Str, L"?");1232 }1233 /**1234 Convert Device Path to a Unicode string for printing.1235 1236 @param[in, out] Str The buffer holding the output string.1237 This buffer contains the length of the string and1238 the maixmum length reserved for the string buffer.1239 @param[in] DevPath The device path.1240 1241 **/1242 VOID1243 DevPathFvPath (1244 IN OUT POOL_PRINT *Str,1245 IN VOID *DevPath1246 )1247 {1248 MEDIA_FW_VOL_DEVICE_PATH *FvPath;1249 1250 FvPath = DevPath;1251 CatPrint (Str, L"Fv(%g)", &FvPath->FvName);1252 }1253 1254 DEVICE_PATH_STRING_TABLE DevPathTable[] = {1255 {1256 HARDWARE_DEVICE_PATH,1257 HW_PCI_DP,1258 DevPathPci1259 },1260 {1261 HARDWARE_DEVICE_PATH,1262 HW_PCCARD_DP,1263 DevPathPccard1264 },1265 {1266 HARDWARE_DEVICE_PATH,1267 HW_MEMMAP_DP,1268 DevPathMemMap1269 },1270 {1271 HARDWARE_DEVICE_PATH,1272 HW_VENDOR_DP,1273 DevPathVendor1274 },1275 {1276 HARDWARE_DEVICE_PATH,1277 HW_CONTROLLER_DP,1278 DevPathController1279 },1280 {1281 ACPI_DEVICE_PATH,1282 ACPI_DP,1283 DevPathAcpi1284 },1285 {1286 ACPI_DEVICE_PATH,1287 ACPI_EXTENDED_DP,1288 DevPathExtendedAcpi1289 },1290 {1291 ACPI_DEVICE_PATH,1292 ACPI_ADR_DP,1293 DevPathAdrAcpi1294 },1295 {1296 MESSAGING_DEVICE_PATH,1297 MSG_ATAPI_DP,1298 DevPathAtapi1299 },1300 {1301 MESSAGING_DEVICE_PATH,1302 MSG_SCSI_DP,1303 DevPathScsi1304 },1305 {1306 MESSAGING_DEVICE_PATH,1307 MSG_FIBRECHANNEL_DP,1308 DevPathFibre1309 },1310 {1311 MESSAGING_DEVICE_PATH,1312 MSG_1394_DP,1313 DevPath13941314 },1315 {1316 MESSAGING_DEVICE_PATH,1317 MSG_USB_DP,1318 DevPathUsb1319 },1320 {1321 MESSAGING_DEVICE_PATH,1322 MSG_USB_WWID_DP,1323 DevPathUsbWWID1324 },1325 {1326 MESSAGING_DEVICE_PATH,1327 MSG_DEVICE_LOGICAL_UNIT_DP,1328 DevPathLogicalUnit1329 },1330 {1331 MESSAGING_DEVICE_PATH,1332 MSG_USB_CLASS_DP,1333 DevPathUsbClass1334 },1335 {1336 MESSAGING_DEVICE_PATH,1337 MSG_SATA_DP,1338 DevPathSata1339 },1340 {1341 MESSAGING_DEVICE_PATH,1342 MSG_I2O_DP,1343 DevPathI2O1344 },1345 {1346 MESSAGING_DEVICE_PATH,1347 MSG_MAC_ADDR_DP,1348 DevPathMacAddr1349 },1350 {1351 MESSAGING_DEVICE_PATH,1352 MSG_IPv4_DP,1353 DevPathIPv41354 },1355 {1356 MESSAGING_DEVICE_PATH,1357 MSG_IPv6_DP,1358 DevPathIPv61359 },1360 {1361 MESSAGING_DEVICE_PATH,1362 MSG_INFINIBAND_DP,1363 DevPathInfiniBand1364 },1365 {1366 MESSAGING_DEVICE_PATH,1367 MSG_UART_DP,1368 DevPathUart1369 },1370 {1371 MESSAGING_DEVICE_PATH,1372 MSG_VENDOR_DP,1373 DevPathVendor1374 },1375 {1376 MESSAGING_DEVICE_PATH,1377 MSG_ISCSI_DP,1378 DevPathiSCSI1379 },1380 {1381 MESSAGING_DEVICE_PATH,1382 MSG_VLAN_DP,1383 DevPathVlan1384 },1385 {1386 MEDIA_DEVICE_PATH,1387 MEDIA_HARDDRIVE_DP,1388 DevPathHardDrive1389 },1390 {1391 MEDIA_DEVICE_PATH,1392 MEDIA_CDROM_DP,1393 DevPathCDROM1394 },1395 {1396 MEDIA_DEVICE_PATH,1397 MEDIA_VENDOR_DP,1398 DevPathVendor1399 },1400 {1401 MEDIA_DEVICE_PATH,1402 MEDIA_FILEPATH_DP,1403 DevPathFilePath1404 },1405 {1406 MEDIA_DEVICE_PATH,1407 MEDIA_PROTOCOL_DP,1408 DevPathMediaProtocol1409 },1410 {1411 MEDIA_DEVICE_PATH,1412 MEDIA_PIWG_FW_VOL_DP,1413 DevPathFvPath,1414 },1415 {1416 MEDIA_DEVICE_PATH,1417 MEDIA_PIWG_FW_FILE_DP,1418 DevPathFvFilePath1419 },1420 {1421 MEDIA_DEVICE_PATH,1422 MEDIA_RELATIVE_OFFSET_RANGE_DP,1423 DevPathRelativeOffsetRange,1424 },1425 {1426 BBS_DEVICE_PATH,1427 BBS_BBS_DP,1428 DevPathBssBss1429 },1430 {1431 END_DEVICE_PATH_TYPE,1432 END_INSTANCE_DEVICE_PATH_SUBTYPE,1433 DevPathEndInstance1434 },1435 {1436 0,1437 0,1438 NULL1439 }1440 };1441 16 1442 17 … … 1455 30 ) 1456 31 { 1457 POOL_PRINT Str; 1458 EFI_DEVICE_PATH_PROTOCOL *DevPathNode; 1459 VOID (*DumpNode) (POOL_PRINT *, VOID *); 1460 1461 UINTN Index; 1462 UINTN NewSize; 1463 1464 EFI_STATUS Status; 1465 CHAR16 *ToText; 1466 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; 1467 1468 ZeroMem (&Str, sizeof (Str)); 1469 1470 if (DevPath == NULL) { 1471 goto Done; 1472 } 1473 1474 Status = gBS->LocateProtocol ( 1475 &gEfiDevicePathToTextProtocolGuid, 1476 NULL, 1477 (VOID **) &DevPathToText 1478 ); 1479 if (!EFI_ERROR (Status)) { 1480 ToText = DevPathToText->ConvertDevicePathToText ( 1481 DevPath, 1482 FALSE, 1483 TRUE 1484 ); 1485 ASSERT (ToText != NULL); 1486 return ToText; 1487 } 1488 1489 // 1490 // Process each device path node 1491 // 1492 DevPathNode = DevPath; 1493 while (!IsDevicePathEnd (DevPathNode)) { 1494 // 1495 // Find the handler to dump this device path node 1496 // 1497 DumpNode = NULL; 1498 for (Index = 0; DevPathTable[Index].Function != NULL; Index += 1) { 1499 1500 if (DevicePathType (DevPathNode) == DevPathTable[Index].Type && 1501 DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType 1502 ) { 1503 DumpNode = DevPathTable[Index].Function; 1504 break; 1505 } 1506 } 1507 // 1508 // If not found, use a generic function 1509 // 1510 if (!DumpNode) { 1511 DumpNode = DevPathNodeUnknown; 1512 } 1513 // 1514 // Put a path seperator in if needed 1515 // 1516 if ((Str.Len != 0) && (DumpNode != DevPathEndInstance)) { 1517 CatPrint (&Str, L"/"); 1518 } 1519 // 1520 // Print this node of the device path 1521 // 1522 DumpNode (&Str, DevPathNode); 1523 1524 // 1525 // Next device path node 1526 // 1527 DevPathNode = NextDevicePathNode (DevPathNode); 1528 } 1529 1530 Done: 1531 NewSize = (Str.Len + 1) * sizeof (CHAR16); 1532 Str.Str = ReallocatePool (NewSize, NewSize, Str.Str); 1533 ASSERT (Str.Str != NULL); 1534 Str.Str[Str.Len] = 0; 1535 return Str.Str; 32 return ConvertDevicePathToText ( 33 DevPath, 34 FALSE, 35 TRUE 36 ); 1536 37 } 1537 38 -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
r48674 r58459 1 1 ## @file 2 # Component name for SecureBoot configuration module. 2 # Provides the capbility to configure secure boot in a setup browser 3 # By this module, user may change the content of DB, DBX, PK and KEK. 3 4 # 4 # Copyright (c) 2011 - 201 2, Intel Corporation. All rights reserved.<BR>5 # Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 5 6 # This program and the accompanying materials 6 7 # are licensed and made available under the terms and conditions of the BSD License … … 15 16 INF_VERSION = 0x00010005 16 17 BASE_NAME = SecureBootConfigDxe 18 MODULE_UNI_FILE = SecureBootConfigDxe.uni 17 19 FILE_GUID = F0E6A44F-7195-41c3-AC64-54F202CD0A21 18 20 MODULE_TYPE = DXE_DRIVER … … 54 56 DebugLib 55 57 HiiLib 56 PlatformSecureLib 58 PlatformSecureLib 59 DevicePathLib 57 60 58 61 [Guids] 59 gEfiIfrTianoGuid 62 ## SOMETIMES_CONSUMES ## Variable:L"CustomMode" 63 ## SOMETIMES_PRODUCES ## Variable:L"CustomMode" 60 64 gEfiCustomModeEnableGuid 65 66 ## SOMETIMES_CONSUMES ## Variable:L"SecureBootEnable" 67 ## SOMETIMES_PRODUCES ## Variable:L"SecureBootEnable" 61 68 gEfiSecureBootEnableDisableGuid 69 70 ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. 71 ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. 72 gEfiCertRsa2048Guid 73 74 ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. 75 ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. 76 gEfiCertX509Guid 77 78 ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. 79 ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. 80 gEfiCertSha1Guid 81 82 ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. 83 ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. 84 gEfiCertSha256Guid 85 86 ## SOMETIMES_CONSUMES ## Variable:L"db" 87 ## SOMETIMES_PRODUCES ## Variable:L"db" 88 ## SOMETIMES_CONSUMES ## Variable:L"dbx" 89 ## SOMETIMES_PRODUCES ## Variable:L"dbx" 90 gEfiImageSecurityDatabaseGuid 91 92 ## SOMETIMES_CONSUMES ## Variable:L"SetupMode" 93 ## SOMETIMES_PRODUCES ## Variable:L"PK" 94 ## SOMETIMES_CONSUMES ## Variable:L"KEK" 95 ## SOMETIMES_PRODUCES ## Variable:L"KEK" 96 ## SOMETIMES_CONSUMES ## Variable:L"SecureBoot" 97 gEfiGlobalVariableGuid 98 99 gEfiIfrTianoGuid ## PRODUCES ## GUID # HII opcode 100 ## PRODUCES ## HII 101 ## CONSUMES ## HII 62 102 gSecureBootConfigFormSetGuid 63 gEfiCertPkcs7Guid 64 gEfiCertRsa2048Guid ## CONSUMES 65 gEfiCertX509Guid ## CONSUMES 66 gEfiCertSha1Guid ## CONSUMES 67 gEfiCertSha256Guid ## CONSUMES 68 gEfiCertTypeRsa2048Sha256Guid ## CONSUMES 69 gEfiImageSecurityDatabaseGuid ## CONSUMES 70 gEfiFileSystemVolumeLabelInfoIdGuid ## CONSUMES 71 gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid 72 gEfiVT100PlusGuid ## CONSUMES ## GUID (The type of terminal) 73 gEfiVT100Guid ## CONSUMES ## GUID (The type of terminal) 74 ## CONSUMES ## GUID HOB (The hob holding memory type information) 75 gEfiVTUTF8Guid ## CONSUMES ## GUID (The type of terminal) 76 ## SOMETIMES_CONSUMES ## Variable:L"BootXX" (Boot option variable) 77 ## CONSUMES ## Variable:L"Timeout" (The time out value in second of showing progress bar) 78 ## SOMETIMES_CONSUMES ## Variable:L"BootOrder" (The boot option array) 79 ## SOMETIMES_CONSUMES ## Variable:L"DriverOrder" (The driver order list) 80 ## SOMETIMES_CONSUMES ## Variable:L"ConIn" (The device path of console in device) 81 ## SOMETIMES_CONSUMES ## Variable:L"ConOut" (The device path of console out device) 82 ## SOMETIMES_CONSUMES ## Variable:L"ErrOut" (The device path of error out device) 83 gEfiFileInfoGuid ## CONSUMES ## GUID 84 gEfiPcAnsiGuid ## CONSUMES ## GUID (The type of terminal) 85 gEfiUartDevicePathGuid ## CONSUMES ## GUID (Identify the device path for UARD device) 86 gEfiSasDevicePathGuid ## CONSUMES ## GUID (Identify the device path for SAS device) 103 gEfiCertPkcs7Guid ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the certificate. 104 gEfiCertTypeRsa2048Sha256Guid ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the certificate. 105 gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type 106 gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type 87 107 88 108 [Protocols] 89 109 gEfiHiiConfigAccessProtocolGuid ## PRODUCES 90 gEfiHiiConfigRoutingProtocolGuid ## CONSUMES 91 gEfiSimpleFileSystemProtocolGuid ## PROTOCOL CONSUMES 92 gEfiLoadFileProtocolGuid ## PROTOCOL CONSUMES 93 gEfiBlockIoProtocolGuid ## PROTOCOL CONSUMES 94 gEfiDevicePathProtocolGuid ## PROTOCOL CONSUMES 95 gEfiDevicePathToTextProtocolGuid 96 gEfiDebugPortProtocolGuid 110 gEfiDevicePathProtocolGuid ## PRODUCES 111 gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES 112 gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES 97 113 98 114 [Depex] … … 101 117 gEfiVariableArchProtocolGuid AND 102 118 gEfiVariableWriteArchProtocolGuid 119 120 [UserExtensions.TianoCore."ExtraFiles"] 121 SecureBootConfigDxeExtra.uni 122 -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigFileExplorer.c
r48674 r58459 2 2 Internal file explorer functions for SecureBoot configuration module. 3 3 4 Copyright (c) 2012 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 324 324 FileContext = (SECUREBOOT_FILE_CONTEXT *) MenuEntry->FileContext; 325 325 326 if (!FileContext->IsRoot ) {326 if (!FileContext->IsRoot && FileContext->DevicePath != NULL) { 327 327 FreePool (FileContext->DevicePath); 328 328 } else { … … 341 341 FreePool (FileContext); 342 342 343 FreePool (MenuEntry->DisplayString); 343 if (MenuEntry->DisplayString != NULL) { 344 FreePool (MenuEntry->DisplayString); 345 } 344 346 if (MenuEntry->HelpString != NULL) { 345 347 FreePool (MenuEntry->HelpString); … … 1068 1070 STRING_TOKEN (STR_NULL), 1069 1071 EFI_IFR_FLAG_CALLBACK, 1070 (UINT16) (FILE_OPTION_ OFFSET + Index)1072 (UINT16) (FILE_OPTION_GOTO_OFFSET + Index) 1071 1073 ); 1072 1074 } -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
r48674 r58459 2 2 HII Config Access protocol implementation of SecureBoot configuration module. 3 3 4 Copyright (c) 2011 - 201 2, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 49 49 50 50 51 BOOLEAN mIsEnterSecureBootForm = FALSE; 52 51 53 // 52 54 // OID ASN.1 Value for Hash Algorithms … … 69 71 }; 70 72 71 72 // Variable Definitions 73 // 74 // Variable Definitions 75 // 73 76 UINT32 mPeCoffHeaderOffset = 0; 74 77 WIN_CERTIFICATE *mCertificate = NULL; … … 82 85 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader; 83 86 87 // 88 // Possible DER-encoded certificate file suffixes, end with NULL pointer. 89 // 90 CHAR16* mDerEncodedSuffix[] = { 91 L".cer", 92 L".der", 93 L".crt", 94 NULL 95 }; 96 CHAR16* mSupportX509Suffix = L"*.cer/der/crt"; 97 98 /** 99 This code checks if the FileSuffix is one of the possible DER-encoded certificate suffix. 100 101 @param[in] FileSuffix The suffix of the input certificate file 102 103 @retval TRUE It's a DER-encoded certificate. 104 @retval FALSE It's NOT a DER-encoded certificate. 105 106 **/ 107 BOOLEAN 108 IsDerEncodeCertificate ( 109 IN CONST CHAR16 *FileSuffix 110 ) 111 { 112 UINTN Index; 113 for (Index = 0; mDerEncodedSuffix[Index] != NULL; Index++) { 114 if (StrCmp (FileSuffix, mDerEncodedSuffix[Index]) == 0) { 115 return TRUE; 116 } 117 } 118 return FALSE; 119 } 84 120 85 121 /** … … 216 252 UINT32 Attr; 217 253 218 Variable = GetVariable (VariableName, VendorGuid);254 GetVariable2 (VariableName, VendorGuid, &Variable, NULL); 219 255 if (Variable == NULL) { 220 256 return EFI_SUCCESS; 221 257 } 258 FreePool (Variable); 222 259 223 260 Data = NULL; … … 243 280 } 244 281 return Status; 282 } 283 284 /** 285 286 Set the platform secure boot mode into "Custom" or "Standard" mode. 287 288 @param[in] SecureBootMode New secure boot mode: STANDARD_SECURE_BOOT_MODE or 289 CUSTOM_SECURE_BOOT_MODE. 290 291 @return EFI_SUCCESS The platform has switched to the special mode successfully. 292 @return other Fail to operate the secure boot mode. 293 294 **/ 295 EFI_STATUS 296 SetSecureBootMode ( 297 IN UINT8 SecureBootMode 298 ) 299 { 300 return gRT->SetVariable ( 301 EFI_CUSTOM_MODE_NAME, 302 &gEfiCustomModeEnableGuid, 303 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 304 sizeof (UINT8), 305 &SecureBootMode 306 ); 245 307 } 246 308 … … 340 402 EFI_SIGNATURE_LIST *PkCert; 341 403 UINT16* FilePostFix; 404 UINTN NameLength; 342 405 343 406 if (Private->FileContext->FileName == NULL) { … … 347 410 PkCert = NULL; 348 411 349 // 350 // Parse the file's postfix. Only support *.cer(X509) files. 351 // 352 FilePostFix = Private->FileContext->FileName + StrLen (Private->FileContext->FileName) - 4; 353 if (CompareMem (FilePostFix, L".cer",4)) { 354 DEBUG ((EFI_D_ERROR, "Don't support the file, only *.cer is supported.")); 412 Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); 413 if (EFI_ERROR (Status)) { 414 return Status; 415 } 416 417 // 418 // Parse the file's postfix. Only support DER encoded X.509 certificate files. 419 // 420 NameLength = StrLen (Private->FileContext->FileName); 421 if (NameLength <= 4) { 422 return EFI_INVALID_PARAMETER; 423 } 424 FilePostFix = Private->FileContext->FileName + NameLength - 4; 425 if (!IsDerEncodeCertificate(FilePostFix)) { 426 DEBUG ((EFI_D_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.", mSupportX509Suffix)); 355 427 return EFI_INVALID_PARAMETER; 356 428 } … … 423 495 { 424 496 EFI_STATUS Status; 497 498 Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); 499 if (EFI_ERROR (Status)) { 500 return Status; 501 } 425 502 426 503 Status = DeleteVariable ( … … 733 810 { 734 811 UINT16* FilePostFix; 812 EFI_STATUS Status; 813 UINTN NameLength; 735 814 736 815 if ((Private->FileContext->FileName == NULL) || (Private->SignatureGUID == NULL)) { … … 738 817 } 739 818 740 // 741 // Parse the file's postfix. Supports .cer and .der file as X509 certificate, 819 Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); 820 if (EFI_ERROR (Status)) { 821 return Status; 822 } 823 824 // 825 // Parse the file's postfix. Supports DER-encoded X509 certificate, 742 826 // and .pbk as RSA public key file. 743 827 // 744 FilePostFix = Private->FileContext->FileName + StrLen (Private->FileContext->FileName) - 4; 745 if ((CompareMem (FilePostFix, L".cer",4) == 0) || (CompareMem (FilePostFix, L".der",4) == 0)) { 828 NameLength = StrLen (Private->FileContext->FileName); 829 if (NameLength <= 4) { 830 return EFI_INVALID_PARAMETER; 831 } 832 FilePostFix = Private->FileContext->FileName + NameLength - 4; 833 if (IsDerEncodeCertificate(FilePostFix)) { 746 834 return EnrollX509ToKek (Private); 747 835 } else if (CompareMem (FilePostFix, L".pbk",4) == 0) { … … 1017 1105 // But CheckSum field and SECURITY data directory (certificate) are excluded 1018 1106 // 1019 Magic = mNtHeader.Pe32->OptionalHeader.Magic; 1107 if (mNtHeader.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 1108 // 1109 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value 1110 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the 1111 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 1112 // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 1113 // 1114 Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; 1115 } else { 1116 // 1117 // Get the magic value from the PE/COFF Optional Header 1118 // 1119 Magic = mNtHeader.Pe32->OptionalHeader.Magic; 1120 } 1121 1020 1122 // 1021 1123 // 3. Calculate the distance from the base of the image header to the image checksum address. … … 1461 1563 { 1462 1564 UINT16* FilePostFix; 1565 EFI_STATUS Status; 1566 UINTN NameLength; 1463 1567 1464 1568 if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->SignatureGUID == NULL)) { … … 1466 1570 } 1467 1571 1572 Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); 1573 if (EFI_ERROR (Status)) { 1574 return Status; 1575 } 1576 1468 1577 // 1469 1578 // Parse the file's postfix. 1470 1579 // 1471 FilePostFix = Private->FileContext->FileName + StrLen (Private->FileContext->FileName) - 4; 1472 if ((CompareMem (FilePostFix, L".cer",4) == 0) || (CompareMem (FilePostFix, L".der",4) == 0)) { 1473 // 1474 // Supports .cer and .der file as X509 certificate. 1580 NameLength = StrLen (Private->FileContext->FileName); 1581 if (NameLength <= 4) { 1582 return EFI_INVALID_PARAMETER; 1583 } 1584 FilePostFix = Private->FileContext->FileName + NameLength - 4; 1585 if (IsDerEncodeCertificate(FilePostFix)) { 1586 // 1587 // Supports DER-encoded X509 certificate. 1475 1588 // 1476 1589 return EnrollX509toSigDB (Private, VariableName); … … 1612 1725 // The signature type is not supported in current implementation. 1613 1726 // 1727 ItemDataSize -= CertList->SignatureListSize; 1728 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); 1614 1729 continue; 1615 1730 } … … 1709 1824 Attr = 0; 1710 1825 DeleteKekIndex = QuestionId - OPTION_DEL_KEK_QUESTION_ID; 1826 1827 Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); 1828 if (EFI_ERROR (Status)) { 1829 return Status; 1830 } 1711 1831 1712 1832 // … … 1801 1921 while ((KekDataSize > 0) && (KekDataSize >= CertList->SignatureListSize)) { 1802 1922 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; 1803 DEBUG ((DEBUG_ ERROR, " CertCount = %x\n", CertCount));1923 DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount)); 1804 1924 if (CertCount != 0) { 1805 1925 CopyMem (OldData + Offset, CertList, CertList->SignatureListSize); … … 1896 2016 Cert = NULL; 1897 2017 Attr = 0; 2018 2019 Status = SetSecureBootMode(CUSTOM_SECURE_BOOT_MODE); 2020 if (EFI_ERROR (Status)) { 2021 return Status; 2022 } 1898 2023 1899 2024 // … … 1994 2119 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { 1995 2120 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; 1996 DEBUG ((DEBUG_ ERROR, " CertCount = %x\n", CertCount));2121 DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount)); 1997 2122 if (CertCount != 0) { 1998 2123 CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize); … … 2063 2188 2064 2189 // 2065 // Get the SecureBootEnable Variable2066 //2067 SecureBootEnable = GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid);2068 2069 //2070 2190 // If the SecureBootEnable Variable doesn't exist, hide the SecureBoot Enable/Disable 2071 2191 // Checkbox. 2072 2192 // 2193 ConfigData->AttemptSecureBoot = FALSE; 2194 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); 2073 2195 if (SecureBootEnable == NULL) { 2074 2196 ConfigData->HideSecureBoot = TRUE; 2075 2197 } else { 2076 2198 ConfigData->HideSecureBoot = FALSE; 2077 ConfigData->SecureBootState = *SecureBootEnable; 2078 } 2199 if ((*SecureBootEnable) == SECURE_BOOT_ENABLE) { 2200 ConfigData->AttemptSecureBoot = TRUE; 2201 } 2202 } 2203 2079 2204 // 2080 2205 // If it is Physical Presence User, set the PhysicalPresent to true. … … 2089 2214 // If there is no PK then the Delete Pk button will be gray. 2090 2215 // 2091 SetupMode = GetVariable (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid);2092 if (SetupMode == NULL || (*SetupMode) == 1) {2216 GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL); 2217 if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) { 2093 2218 ConfigData->HasPk = FALSE; 2094 2219 } else { … … 2099 2224 // Get the SecureBootMode from CustomMode variable. 2100 2225 // 2101 SecureBootMode = GetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid);2226 GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL); 2102 2227 if (SecureBootMode == NULL) { 2103 2228 ConfigData->SecureBootMode = STANDARD_SECURE_BOOT_MODE; … … 2105 2230 ConfigData->SecureBootMode = *(SecureBootMode); 2106 2231 } 2107 2232 2233 if (SecureBootEnable != NULL) { 2234 FreePool (SecureBootEnable); 2235 } 2236 if (SetupMode != NULL) { 2237 FreePool (SetupMode); 2238 } 2239 if (SecureBootMode != NULL) { 2240 FreePool (SecureBootMode); 2241 } 2108 2242 } 2109 2243 … … 2151 2285 SECUREBOOT_CONFIG_PRIVATE_DATA *PrivateData; 2152 2286 BOOLEAN AllocatedRequest; 2287 UINT8 *SecureBoot; 2153 2288 2154 2289 if (Progress == NULL || Results == NULL) { … … 2160 2295 ConfigRequest = NULL; 2161 2296 Size = 0; 2297 SecureBoot = NULL; 2162 2298 2163 2299 ZeroMem (&Configuration, sizeof (Configuration)); … … 2173 2309 // 2174 2310 SecureBootExtractConfigFromVariable (&Configuration); 2311 2312 // 2313 // Update current secure boot state. 2314 // 2315 GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SecureBoot, NULL); 2316 if (SecureBoot != NULL && *SecureBoot == SECURE_BOOT_MODE_ENABLE) { 2317 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Enabled", NULL); 2318 } else { 2319 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_SECURE_BOOT_STATE_CONTENT), L"Disabled", NULL); 2320 } 2321 if (SecureBoot != NULL) { 2322 FreePool (SecureBoot); 2323 } 2175 2324 2176 2325 BufferSize = sizeof (SECUREBOOT_CONFIGURATION); … … 2247 2396 ) 2248 2397 { 2398 UINT8 *SecureBootEnable; 2399 SECUREBOOT_CONFIGURATION IfrNvData; 2400 UINTN BufferSize; 2401 EFI_STATUS Status; 2402 2249 2403 if (Configuration == NULL || Progress == NULL) { 2250 2404 return EFI_INVALID_PARAMETER; … … 2254 2408 if (!HiiIsConfigHdrMatch (Configuration, &gSecureBootConfigFormSetGuid, mSecureBootStorageName)) { 2255 2409 return EFI_NOT_FOUND; 2410 } 2411 2412 // 2413 // Get Configuration from Variable. 2414 // 2415 SecureBootExtractConfigFromVariable (&IfrNvData); 2416 2417 // 2418 // Map the Configuration to the configuration block. 2419 // 2420 BufferSize = sizeof (SECUREBOOT_CONFIGURATION); 2421 Status = gHiiConfigRouting->ConfigToBlock ( 2422 gHiiConfigRouting, 2423 Configuration, 2424 (UINT8 *)&IfrNvData, 2425 &BufferSize, 2426 Progress 2427 ); 2428 if (EFI_ERROR (Status)) { 2429 return Status; 2430 } 2431 2432 // 2433 // Store Buffer Storage back to EFI variable if needed 2434 // 2435 SecureBootEnable = NULL; 2436 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); 2437 if (NULL != SecureBootEnable) { 2438 FreePool (SecureBootEnable); 2439 Status = SaveSecureBootVariable (IfrNvData.AttemptSecureBoot); 2440 if (EFI_ERROR (Status)) { 2441 return Status; 2442 } 2256 2443 } 2257 2444 … … 2299 2486 SECUREBOOT_CONFIGURATION *IfrNvData; 2300 2487 UINT16 LabelId; 2488 UINT8 *SecureBootEnable; 2489 UINT8 *SecureBootMode; 2490 UINT8 *SetupMode; 2491 CHAR16 PromptString[100]; 2492 2493 SecureBootEnable = NULL; 2494 SecureBootMode = NULL; 2495 SetupMode = NULL; 2301 2496 2302 2497 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { … … 2304 2499 } 2305 2500 2306 if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING)) { 2501 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { 2502 if (QuestionId == KEY_SECURE_BOOT_MODE) { 2503 mIsEnterSecureBootForm = TRUE; 2504 } 2505 2506 return EFI_SUCCESS; 2507 } 2508 2509 if (Action == EFI_BROWSER_ACTION_RETRIEVE) { 2510 Status = EFI_UNSUPPORTED; 2511 if (QuestionId == KEY_SECURE_BOOT_MODE) { 2512 if (mIsEnterSecureBootForm) { 2513 Value->u8 = SECURE_BOOT_MODE_STANDARD; 2514 Status = EFI_SUCCESS; 2515 } 2516 } 2517 return Status; 2518 } 2519 2520 if ((Action != EFI_BROWSER_ACTION_CHANGED) && 2521 (Action != EFI_BROWSER_ACTION_CHANGING) && 2522 (Action != EFI_BROWSER_ACTION_FORM_CLOSE) && 2523 (Action != EFI_BROWSER_ACTION_DEFAULT_STANDARD)) { 2307 2524 return EFI_UNSUPPORTED; 2308 2525 } … … 2321 2538 Status = EFI_SUCCESS; 2322 2539 2323 HiiGetBrowserData ( NULL, NULL, BufferSize, (UINT8 *) IfrNvData);2540 HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *) IfrNvData); 2324 2541 2325 2542 if (Action == EFI_BROWSER_ACTION_CHANGING) { … … 2327 2544 switch (QuestionId) { 2328 2545 case KEY_SECURE_BOOT_ENABLE: 2329 if (NULL != GetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid)) { 2546 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); 2547 if (NULL != SecureBootEnable) { 2548 FreePool (SecureBootEnable); 2330 2549 if (EFI_ERROR (SaveSecureBootVariable (Value->u8))) { 2331 2550 CreatePopUp ( … … 2336 2555 ); 2337 2556 Status = EFI_UNSUPPORTED; 2557 } else { 2558 CreatePopUp ( 2559 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2560 &Key, 2561 L"Configuration changed, please reset the platform to take effect!", 2562 NULL 2563 ); 2338 2564 } 2339 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;2340 2565 } 2341 2566 break; … … 2394 2619 2395 2620 case KEY_SECURE_BOOT_DELETE_PK: 2396 if (Value->u8) { 2621 if (Value->u8) { 2622 CreatePopUp ( 2623 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2624 &Key, 2625 L"Are you sure you want to delete PK? Secure boot will be disabled!", 2626 L"Press 'Y' to delete PK and exit, 'N' to discard change and return", 2627 NULL 2628 ); 2629 if (Key.UnicodeChar == 'y' || Key.UnicodeChar == 'Y') { 2397 2630 Status = DeletePlatformKey (); 2398 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; 2631 if (EFI_ERROR (Status)) { 2632 CreatePopUp ( 2633 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2634 &Key, 2635 L"Only Physical Presence User could delete PK in custom mode!", 2636 NULL 2637 ); 2638 } 2399 2639 } 2640 } 2400 2641 break; 2401 2642 … … 2436 2677 case KEY_VALUE_SAVE_AND_EXIT_KEK: 2437 2678 Status = EnrollKeyExchangeKey (Private); 2679 if (EFI_ERROR (Status)) { 2680 CreatePopUp ( 2681 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2682 &Key, 2683 L"ERROR: Unsupported file type!", 2684 L"Only supports DER-encoded X509 certificate", 2685 NULL 2686 ); 2687 } 2438 2688 break; 2439 2689 2440 2690 case KEY_VALUE_SAVE_AND_EXIT_DB: 2441 2691 Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE); 2692 if (EFI_ERROR (Status)) { 2693 CreatePopUp ( 2694 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2695 &Key, 2696 L"ERROR: Unsupported file type!", 2697 L"Only supports DER-encoded X509 certificate and executable EFI image", 2698 NULL 2699 ); 2700 } 2442 2701 break; 2443 2702 2444 2703 case KEY_VALUE_SAVE_AND_EXIT_DBX: 2445 2704 Status = EnrollSignatureDatabase (Private, EFI_IMAGE_SECURITY_DATABASE1); 2705 if (EFI_ERROR (Status)) { 2706 CreatePopUp ( 2707 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2708 &Key, 2709 L"ERROR: Unsupported file type!", 2710 L"Only supports DER-encoded X509 certificate and executable EFI image", 2711 NULL 2712 ); 2713 } 2446 2714 break; 2447 2715 2448 2716 default: 2449 if (QuestionId >= FILE_OPTION_ OFFSET) {2717 if (QuestionId >= FILE_OPTION_GOTO_OFFSET) { 2450 2718 UpdateFileExplorer (Private, QuestionId); 2451 2719 } else if ((QuestionId >= OPTION_DEL_KEK_QUESTION_ID) && … … 2480 2748 switch (QuestionId) { 2481 2749 case KEY_SECURE_BOOT_ENABLE: 2482 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_ SUBMIT;2750 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; 2483 2751 break; 2484 2752 case KEY_VALUE_SAVE_AND_EXIT_PK: 2485 2753 Status = EnrollPlatformKey (Private); 2486 2754 if (EFI_ERROR (Status)) { 2755 UnicodeSPrint ( 2756 PromptString, 2757 sizeof (PromptString), 2758 L"Only DER encoded certificate file (%s) is supported.", 2759 mSupportX509Suffix 2760 ); 2487 2761 CreatePopUp ( 2488 2762 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, 2489 2763 &Key, 2490 L"ERROR: Unsupported file type, only *.cer is supported!", 2764 L"ERROR: Unsupported file type!", 2765 PromptString, 2491 2766 NULL 2492 2767 ); 2493 2768 } else { 2494 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_ EXIT;2769 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET; 2495 2770 } 2496 2771 break; … … 2514 2789 2515 2790 case KEY_SECURE_BOOT_MODE: 2516 if (NULL != GetVariable (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid)) { 2517 Status = gRT->SetVariable ( 2518 EFI_CUSTOM_MODE_NAME, 2519 &gEfiCustomModeEnableGuid, 2520 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 2521 sizeof (UINT8), 2522 &Value->u8 2523 ); 2524 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; 2525 IfrNvData->SecureBootMode = Value->u8; 2526 } 2791 mIsEnterSecureBootForm = FALSE; 2527 2792 break; 2528 2793 … … 2544 2809 2545 2810 case KEY_SECURE_BOOT_DELETE_PK: 2546 if (Value->u8) { 2811 GetVariable2 (EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SetupMode, NULL); 2812 if (SetupMode == NULL || (*SetupMode) == SETUP_MODE) { 2813 IfrNvData->DeletePk = TRUE; 2814 IfrNvData->HasPk = FALSE; 2547 2815 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; 2816 } else { 2817 IfrNvData->DeletePk = FALSE; 2818 IfrNvData->HasPk = TRUE; 2819 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; 2548 2820 } 2549 break; 2821 if (SetupMode != NULL) { 2822 FreePool (SetupMode); 2823 } 2824 break; 2825 default: 2826 if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) { 2827 if (UpdateFileExplorer (Private, QuestionId)) { 2828 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; 2829 } 2830 } 2831 break; 2832 } 2833 } else if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) { 2834 if (QuestionId == KEY_HIDE_SECURE_BOOT) { 2835 GetVariable2 (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, (VOID**)&SecureBootEnable, NULL); 2836 if (SecureBootEnable == NULL) { 2837 IfrNvData->HideSecureBoot = TRUE; 2838 } else { 2839 FreePool (SecureBootEnable); 2840 IfrNvData->HideSecureBoot = FALSE; 2841 } 2842 Value->b = IfrNvData->HideSecureBoot; 2843 } 2844 } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { 2845 // 2846 // Force the platform back to Standard Mode once user leave the setup screen. 2847 // 2848 GetVariable2 (EFI_CUSTOM_MODE_NAME, &gEfiCustomModeEnableGuid, (VOID**)&SecureBootMode, NULL); 2849 if (NULL != SecureBootMode && *SecureBootMode == CUSTOM_SECURE_BOOT_MODE) { 2850 IfrNvData->SecureBootMode = STANDARD_SECURE_BOOT_MODE; 2851 SetSecureBootMode(STANDARD_SECURE_BOOT_MODE); 2852 } 2853 if (SecureBootMode != NULL) { 2854 FreePool (SecureBootMode); 2550 2855 } 2551 2856 } … … 2553 2858 if (!EFI_ERROR (Status)) { 2554 2859 BufferSize = sizeof (SECUREBOOT_CONFIGURATION); 2555 HiiSetBrowserData ( NULL, NULL, BufferSize, (UINT8*) IfrNvData, NULL);2860 HiiSetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8*) IfrNvData, NULL); 2556 2861 } 2557 2862 FreePool (IfrNvData); -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h
r48674 r58459 24 24 #include <Protocol/BlockIo.h> 25 25 #include <Protocol/DevicePath.h> 26 #include <Protocol/DevicePathToText.h>27 26 #include <Protocol/DebugPort.h> 28 27 #include <Protocol/LoadFile.h> -
trunk/src/VBox/Devices/EFI/Firmware/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigNvData.h
r48674 r58459 2 2 Header file for NV data structure definition. 3 3 4 Copyright (c) 2011 - 201 2, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 56 56 #define KEY_VALUE_SAVE_AND_EXIT_DBX 0x100a 57 57 #define KEY_VALUE_NO_SAVE_AND_EXIT_DBX 0x100b 58 #define KEY_HIDE_SECURE_BOOT 0x100c 58 59 59 60 #define KEY_SECURE_BOOT_OPTION 0x1100 … … 95 96 #define OPTION_DEL_DBX_QUESTION_ID 0x4000 96 97 97 98 #define FILE_OPTION_GOTO_OFFSET 0xC000 98 99 #define FILE_OPTION_OFFSET 0x8000 99 #define FILE_OPTION_MASK 0x 7FFF100 #define FILE_OPTION_MASK 0x3FFF 100 101 101 102 #define SECURE_BOOT_GUID_SIZE 36 … … 107 108 // 108 109 typedef struct { 109 BOOLEAN SecureBootState; //Secure Boot Disable/Enable;110 BOOLEAN AttemptSecureBoot; //Attempt to enable/disable Secure Boot. 110 111 BOOLEAN HideSecureBoot; //Hiden Attempt Secure Boot 111 112 CHAR16 SignatureGuid[SECURE_BOOT_GUID_STORAGE_SIZE];
Note:
See TracChangeset
for help on using the changeset viewer.