1 /** @file 2 3 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR> 4 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions 7 of the BSD License which accompanies this distribution. The 8 full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include <PiDxe.h> 17 #include <Library/UefiBootServicesTableLib.h> 18 #include <Library/UefiRuntimeServicesTableLib.h> 19 #include <Library/BaseLib.h> 20 #include <Library/BaseMemoryLib.h> 21 #include <Library/LockBoxLib.h> 22 #include <Library/DebugLib.h> 23 #include <Protocol/SmmCommunication.h> 24 #include <Guid/SmmLockBox.h> 25 26 #include "SmmLockBoxLibPrivate.h" 27 28 /** 29 This function will save confidential information to lockbox. 30 31 @param Guid the guid to identify the confidential information 32 @param Buffer the address of the confidential information 33 @param Length the length of the confidential information 34 35 @retval RETURN_SUCCESS the information is saved successfully. 36 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0 37 @retval RETURN_ALREADY_STARTED the requested GUID already exist. 38 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information. 39 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface 40 @retval RETURN_NOT_STARTED it is too early to invoke this interface 41 @retval RETURN_UNSUPPORTED the service is not supported by implementaion. 42 **/ 43 RETURN_STATUS 44 EFIAPI 45 SaveLockBox ( 46 IN GUID *Guid, 47 IN VOID *Buffer, 48 IN UINTN Length 49 ) 50 { 51 EFI_STATUS Status; 52 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; 53 EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave; 54 EFI_SMM_COMMUNICATE_HEADER *CommHeader; 55 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE)]; 56 UINTN CommSize; 57 58 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SaveLockBox - Enter\n")); 59 60 // 61 // Basic check 62 // 63 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) { 64 return EFI_INVALID_PARAMETER; 65 } 66 67 // 68 // Get needed resource 69 // 70 Status = gBS->LocateProtocol ( 71 &gEfiSmmCommunicationProtocolGuid, 72 NULL, 73 (VOID **)&SmmCommunication 74 ); 75 if (EFI_ERROR (Status)) { 76 return EFI_NOT_STARTED; 77 } 78 79 // 80 // Prepare parameter 81 // 82 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; 83 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid)); 84 CommHeader->MessageLength = sizeof(*LockBoxParameterSave); 85 86 LockBoxParameterSave = (EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; 87 LockBoxParameterSave->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_SAVE; 88 LockBoxParameterSave->Header.DataLength = sizeof(*LockBoxParameterSave); 89 LockBoxParameterSave->Header.ReturnStatus = (UINT64)-1; 90 CopyMem (&LockBoxParameterSave->Guid, Guid, sizeof(*Guid)); 91 LockBoxParameterSave->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer; 92 LockBoxParameterSave->Length = (UINT64)Length; 93 94 // 95 // Send command 96 // 97 CommSize = sizeof(CommBuffer); 98 Status = SmmCommunication->Communicate ( 99 SmmCommunication, 100 &CommBuffer[0], 101 &CommSize 102 ); 103 ASSERT_EFI_ERROR (Status); 104 105 Status = (EFI_STATUS)LockBoxParameterSave->Header.ReturnStatus; 106 107 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status)); 108 109 // 110 // Done 111 // 112 return Status; 113 } 114 115 /** 116 This function will set lockbox attributes. 117 118 @param Guid the guid to identify the confidential information 119 @param Attributes the attributes of the lockbox 120 121 @retval RETURN_SUCCESS the information is saved successfully. 122 @retval RETURN_INVALID_PARAMETER attributes is invalid. 123 @retval RETURN_NOT_FOUND the requested GUID not found. 124 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface 125 @retval RETURN_NOT_STARTED it is too early to invoke this interface 126 @retval RETURN_UNSUPPORTED the service is not supported by implementaion. 127 **/ 128 RETURN_STATUS 129 EFIAPI 130 SetLockBoxAttributes ( 131 IN GUID *Guid, 132 IN UINT64 Attributes 133 ) 134 { 135 EFI_STATUS Status; 136 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; 137 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes; 138 EFI_SMM_COMMUNICATE_HEADER *CommHeader; 139 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)]; 140 UINTN CommSize; 141 142 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n")); 143 144 // 145 // Basic check 146 // 147 if ((Guid == NULL) || 148 ((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) { 149 return EFI_INVALID_PARAMETER; 150 } 151 152 // 153 // Get needed resource 154 // 155 Status = gBS->LocateProtocol ( 156 &gEfiSmmCommunicationProtocolGuid, 157 NULL, 158 (VOID **)&SmmCommunication 159 ); 160 if (EFI_ERROR (Status)) { 161 return EFI_NOT_STARTED; 162 } 163 164 // 165 // Prepare parameter 166 // 167 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; 168 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid)); 169 CommHeader->MessageLength = sizeof(*LockBoxParameterSetAttributes); 170 171 LockBoxParameterSetAttributes = (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; 172 LockBoxParameterSetAttributes->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES; 173 LockBoxParameterSetAttributes->Header.DataLength = sizeof(*LockBoxParameterSetAttributes); 174 LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)-1; 175 CopyMem (&LockBoxParameterSetAttributes->Guid, Guid, sizeof(*Guid)); 176 LockBoxParameterSetAttributes->Attributes = (UINT64)Attributes; 177 178 // 179 // Send command 180 // 181 CommSize = sizeof(CommBuffer); 182 Status = SmmCommunication->Communicate ( 183 SmmCommunication, 184 &CommBuffer[0], 185 &CommSize 186 ); 187 ASSERT_EFI_ERROR (Status); 188 189 Status = (EFI_STATUS)LockBoxParameterSetAttributes->Header.ReturnStatus; 190 191 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status)); 192 193 // 194 // Done 195 // 196 return Status; 197 } 198 199 /** 200 This function will update confidential information to lockbox. 201 202 @param Guid the guid to identify the original confidential information 203 @param Offset the offset of the original confidential information 204 @param Buffer the address of the updated confidential information 205 @param Length the length of the updated confidential information 206 207 @retval RETURN_SUCCESS the information is saved successfully. 208 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0. 209 @retval RETURN_NOT_FOUND the requested GUID not found. 210 @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold new information. 211 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface 212 @retval RETURN_NOT_STARTED it is too early to invoke this interface 213 @retval RETURN_UNSUPPORTED the service is not supported by implementaion. 214 **/ 215 RETURN_STATUS 216 EFIAPI 217 UpdateLockBox ( 218 IN GUID *Guid, 219 IN UINTN Offset, 220 IN VOID *Buffer, 221 IN UINTN Length 222 ) 223 { 224 EFI_STATUS Status; 225 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; 226 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate; 227 EFI_SMM_COMMUNICATE_HEADER *CommHeader; 228 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)]; 229 UINTN CommSize; 230 231 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib UpdateLockBox - Enter\n")); 232 233 // 234 // Basic check 235 // 236 if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) { 237 return EFI_INVALID_PARAMETER; 238 } 239 240 // 241 // Get needed resource 242 // 243 Status = gBS->LocateProtocol ( 244 &gEfiSmmCommunicationProtocolGuid, 245 NULL, 246 (VOID **)&SmmCommunication 247 ); 248 if (EFI_ERROR (Status)) { 249 return EFI_NOT_STARTED; 250 } 251 252 // 253 // Prepare parameter 254 // 255 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; 256 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid)); 257 CommHeader->MessageLength = sizeof(*LockBoxParameterUpdate); 258 259 LockBoxParameterUpdate = (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; 260 LockBoxParameterUpdate->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_UPDATE; 261 LockBoxParameterUpdate->Header.DataLength = sizeof(*LockBoxParameterUpdate); 262 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)-1; 263 CopyMem (&LockBoxParameterUpdate->Guid, Guid, sizeof(*Guid)); 264 LockBoxParameterUpdate->Offset = (UINT64)Offset; 265 LockBoxParameterUpdate->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer; 266 LockBoxParameterUpdate->Length = (UINT64)Length; 267 268 // 269 // Send command 270 // 271 CommSize = sizeof(CommBuffer); 272 Status = SmmCommunication->Communicate ( 273 SmmCommunication, 274 &CommBuffer[0], 275 &CommSize 276 ); 277 ASSERT_EFI_ERROR (Status); 278 279 Status = (EFI_STATUS)LockBoxParameterUpdate->Header.ReturnStatus; 280 281 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status)); 282 283 // 284 // Done 285 // 286 return Status; 287 } 288 289 /** 290 This function will restore confidential information from lockbox. 291 292 @param Guid the guid to identify the confidential information 293 @param Buffer the address of the restored confidential information 294 NULL means restored to original address, Length MUST be NULL at same time. 295 @param Length the length of the restored confidential information 296 297 @retval RETURN_SUCCESS the information is restored successfully. 298 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL. 299 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no 300 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute. 301 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information. 302 @retval RETURN_NOT_FOUND the requested GUID not found. 303 @retval RETURN_NOT_STARTED it is too early to invoke this interface 304 @retval RETURN_ACCESS_DENIED not allow to restore to the address 305 @retval RETURN_UNSUPPORTED the service is not supported by implementaion. 306 **/ 307 RETURN_STATUS 308 EFIAPI 309 RestoreLockBox ( 310 IN GUID *Guid, 311 IN VOID *Buffer, OPTIONAL 312 IN OUT UINTN *Length OPTIONAL 313 ) 314 { 315 EFI_STATUS Status; 316 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; 317 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore; 318 EFI_SMM_COMMUNICATE_HEADER *CommHeader; 319 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)]; 320 UINTN CommSize; 321 322 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreLockBox - Enter\n")); 323 324 // 325 // Basic check 326 // 327 if ((Guid == NULL) || 328 ((Buffer == NULL) && (Length != NULL)) || 329 ((Buffer != NULL) && (Length == NULL))) { 330 return EFI_INVALID_PARAMETER; 331 } 332 333 // 334 // Get needed resource 335 // 336 Status = gBS->LocateProtocol ( 337 &gEfiSmmCommunicationProtocolGuid, 338 NULL, 339 (VOID **)&SmmCommunication 340 ); 341 if (EFI_ERROR (Status)) { 342 return EFI_NOT_STARTED; 343 } 344 345 // 346 // Prepare parameter 347 // 348 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; 349 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid)); 350 CommHeader->MessageLength = sizeof(*LockBoxParameterRestore); 351 352 LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; 353 LockBoxParameterRestore->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE; 354 LockBoxParameterRestore->Header.DataLength = sizeof(*LockBoxParameterRestore); 355 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1; 356 CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof(*Guid)); 357 LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer; 358 if (Length != NULL) { 359 LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length; 360 } else { 361 LockBoxParameterRestore->Length = 0; 362 } 363 364 // 365 // Send command 366 // 367 CommSize = sizeof(CommBuffer); 368 Status = SmmCommunication->Communicate ( 369 SmmCommunication, 370 &CommBuffer[0], 371 &CommSize 372 ); 373 ASSERT_EFI_ERROR (Status); 374 375 if (Length != NULL) { 376 *Length = (UINTN)LockBoxParameterRestore->Length; 377 } 378 379 Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus; 380 381 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status)); 382 383 // 384 // Done 385 // 386 return Status; 387 } 388 389 /** 390 This function will restore confidential information from all lockbox which have RestoreInPlace attribute. 391 392 @retval RETURN_SUCCESS the information is restored successfully. 393 @retval RETURN_NOT_STARTED it is too early to invoke this interface 394 @retval RETURN_UNSUPPORTED the service is not supported by implementaion. 395 **/ 396 RETURN_STATUS 397 EFIAPI 398 RestoreAllLockBoxInPlace ( 399 VOID 400 ) 401 { 402 EFI_STATUS Status; 403 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; 404 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace; 405 EFI_SMM_COMMUNICATE_HEADER *CommHeader; 406 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)]; 407 UINTN CommSize; 408 409 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n")); 410 411 // 412 // Get needed resource 413 // 414 Status = gBS->LocateProtocol ( 415 &gEfiSmmCommunicationProtocolGuid, 416 NULL, 417 (VOID **)&SmmCommunication 418 ); 419 if (EFI_ERROR (Status)) { 420 return EFI_NOT_STARTED; 421 } 422 423 // 424 // Prepare parameter 425 // 426 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; 427 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid)); 428 CommHeader->MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace); 429 430 LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; 431 LockBoxParameterRestoreAllInPlace->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE; 432 LockBoxParameterRestoreAllInPlace->Header.DataLength = sizeof(*LockBoxParameterRestoreAllInPlace); 433 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1; 434 435 // 436 // Send command 437 // 438 CommSize = sizeof(CommBuffer); 439 Status = SmmCommunication->Communicate ( 440 SmmCommunication, 441 &CommBuffer[0], 442 &CommSize 443 ); 444 ASSERT_EFI_ERROR (Status); 445 446 Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus; 447 448 DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status)); 449 450 // 451 // Done 452 // 453 return Status; 454 } 455 456