"Das U-Boot" Source Tree
at master 608 lines 17 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * UEFI runtime variable services 4 * 5 * Copyright (c) 2017 Rob Clark 6 */ 7 8#define LOG_CATEGORY LOGC_EFI 9 10#include <efi_loader.h> 11#include <efi_variable.h> 12#include <env.h> 13#include <env_internal.h> 14#include <hexdump.h> 15#include <log.h> 16#include <malloc.h> 17#include <rtc.h> 18#include <search.h> 19#include <u-boot/uuid.h> 20#include <crypto/pkcs7_parser.h> 21#include <linux/compat.h> 22#include <u-boot/crc.h> 23#include <asm/sections.h> 24 25#ifdef CONFIG_EFI_SECURE_BOOT 26 27/** 28 * efi_variable_authenticate - authenticate a variable 29 * @variable: Variable name in u16 30 * @vendor: Guid of variable 31 * @data_size: Size of @data 32 * @data: Pointer to variable's value 33 * @given_attr: Attributes to be given at SetVariable() 34 * @env_attr: Attributes that an existing variable holds 35 * @time: signed time that an existing variable holds 36 * 37 * Called by efi_set_variable() to verify that the input is correct. 38 * Will replace the given data pointer with another that points to 39 * the actual data to store in the internal memory. 40 * On success, @data and @data_size will be replaced with variable's 41 * actual data, excluding authentication data, and its size, and variable's 42 * attributes and signed time will also be returned in @env_attr and @time, 43 * respectively. 44 * 45 * Return: status code 46 */ 47static efi_status_t efi_variable_authenticate(const u16 *variable, 48 const efi_guid_t *vendor, 49 efi_uintn_t *data_size, 50 const void **data, u32 given_attr, 51 u32 *env_attr, u64 *time) 52{ 53 const struct efi_variable_authentication_2 *auth; 54 struct efi_signature_store *truststore, *truststore2; 55 struct pkcs7_message *var_sig; 56 struct efi_image_regions *regs; 57 struct efi_time timestamp; 58 struct rtc_time tm; 59 u64 new_time; 60 u8 *ebuf; 61 enum efi_auth_var_type var_type; 62 efi_status_t ret; 63 64 var_sig = NULL; 65 truststore = NULL; 66 truststore2 = NULL; 67 regs = NULL; 68 ebuf = NULL; 69 ret = EFI_SECURITY_VIOLATION; 70 71 if (*data_size < sizeof(struct efi_variable_authentication_2)) 72 goto err; 73 74 /* authentication data */ 75 auth = *data; 76 if (*data_size < (sizeof(auth->time_stamp) 77 + auth->auth_info.hdr.dwLength)) 78 goto err; 79 80 if (guidcmp(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7)) 81 goto err; 82 83 memcpy(&timestamp, &auth->time_stamp, sizeof(timestamp)); 84 if (timestamp.pad1 || timestamp.nanosecond || timestamp.timezone || 85 timestamp.daylight || timestamp.pad2) 86 goto err; 87 88 *data += sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength; 89 *data_size -= (sizeof(auth->time_stamp) 90 + auth->auth_info.hdr.dwLength); 91 92 memset(&tm, 0, sizeof(tm)); 93 tm.tm_year = timestamp.year; 94 tm.tm_mon = timestamp.month; 95 tm.tm_mday = timestamp.day; 96 tm.tm_hour = timestamp.hour; 97 tm.tm_min = timestamp.minute; 98 tm.tm_sec = timestamp.second; 99 new_time = rtc_mktime(&tm); 100 101 if (!efi_secure_boot_enabled()) { 102 /* finished checking */ 103 *time = new_time; 104 return EFI_SUCCESS; 105 } 106 107 if (new_time <= *time) 108 goto err; 109 110 /* data to be digested */ 111 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 5, 1); 112 if (!regs) 113 goto err; 114 regs->max = 5; 115 efi_image_region_add(regs, (uint8_t *)variable, 116 (uint8_t *)variable 117 + u16_strlen(variable) * sizeof(u16), 1); 118 efi_image_region_add(regs, (uint8_t *)vendor, 119 (uint8_t *)vendor + sizeof(*vendor), 1); 120 efi_image_region_add(regs, (uint8_t *)&given_attr, 121 (uint8_t *)&given_attr + sizeof(given_attr), 1); 122 efi_image_region_add(regs, (uint8_t *)&timestamp, 123 (uint8_t *)&timestamp + sizeof(timestamp), 1); 124 efi_image_region_add(regs, (uint8_t *)*data, 125 (uint8_t *)*data + *data_size, 1); 126 127 /* variable's signature list */ 128 if (auth->auth_info.hdr.dwLength < sizeof(auth->auth_info)) 129 goto err; 130 131 /* ebuf should be kept valid during the authentication */ 132 var_sig = efi_parse_pkcs7_header(auth->auth_info.cert_data, 133 auth->auth_info.hdr.dwLength 134 - sizeof(auth->auth_info), 135 &ebuf); 136 if (!var_sig) { 137 EFI_PRINT("Parsing variable's signature failed\n"); 138 goto err; 139 } 140 141 /* signature database used for authentication */ 142 var_type = efi_auth_var_get_type(variable, vendor); 143 switch (var_type) { 144 case EFI_AUTH_VAR_PK: 145 case EFI_AUTH_VAR_KEK: 146 /* with PK */ 147 truststore = efi_sigstore_parse_sigdb(u"PK"); 148 if (!truststore) 149 goto err; 150 break; 151 case EFI_AUTH_VAR_DB: 152 case EFI_AUTH_VAR_DBX: 153 /* with PK and KEK */ 154 truststore = efi_sigstore_parse_sigdb(u"KEK"); 155 truststore2 = efi_sigstore_parse_sigdb(u"PK"); 156 if (!truststore) { 157 if (!truststore2) 158 goto err; 159 160 truststore = truststore2; 161 truststore2 = NULL; 162 } 163 break; 164 default: 165 /* TODO: support private authenticated variables */ 166 ret = EFI_UNSUPPORTED; 167 goto err; 168 } 169 170 /* verify signature */ 171 if (efi_signature_verify(regs, var_sig, truststore, NULL)) { 172 EFI_PRINT("Verified\n"); 173 } else { 174 if (truststore2 && 175 efi_signature_verify(regs, var_sig, truststore2, NULL)) { 176 EFI_PRINT("Verified\n"); 177 } else { 178 EFI_PRINT("Verifying variable's signature failed\n"); 179 goto err; 180 } 181 } 182 183 /* finished checking */ 184 *time = new_time; 185 ret = EFI_SUCCESS; 186 187err: 188 efi_sigstore_free(truststore); 189 efi_sigstore_free(truststore2); 190 pkcs7_free_message(var_sig); 191 free(ebuf); 192 free(regs); 193 194 return ret; 195} 196#else 197static efi_status_t efi_variable_authenticate(const u16 *variable, 198 const efi_guid_t *vendor, 199 efi_uintn_t *data_size, 200 const void **data, u32 given_attr, 201 u32 *env_attr, u64 *time) 202{ 203 return EFI_SUCCESS; 204} 205#endif /* CONFIG_EFI_SECURE_BOOT */ 206 207efi_status_t __efi_runtime 208efi_get_variable_int(const u16 *variable_name, const efi_guid_t *vendor, 209 u32 *attributes, efi_uintn_t *data_size, void *data, 210 u64 *timep) 211{ 212 return efi_get_variable_mem(variable_name, vendor, attributes, data_size, 213 data, timep, 0); 214} 215 216efi_status_t __efi_runtime 217efi_get_next_variable_name_int(efi_uintn_t *variable_name_size, 218 u16 *variable_name, efi_guid_t *vendor) 219{ 220 return efi_get_next_variable_name_mem(variable_name_size, variable_name, 221 vendor, 0); 222} 223 224/** 225 * setvariable_allowed() - checks defined by the UEFI spec for setvariable 226 * 227 * @variable_name: name of the variable 228 * @vendor: vendor GUID 229 * @attributes: attributes of the variable 230 * @data_size: size of the buffer with the variable value 231 * @data: buffer with the variable value 232 * Return: status code 233 */ 234static efi_status_t __efi_runtime 235setvariable_allowed(const u16 *variable_name, const efi_guid_t *vendor, 236 u32 attributes, efi_uintn_t data_size, const void *data) 237{ 238 if (!variable_name || !*variable_name || !vendor) 239 return EFI_INVALID_PARAMETER; 240 241 if (data_size && !data) 242 return EFI_INVALID_PARAMETER; 243 244 /* 245 * EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated. 246 * We don't support EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS. 247 */ 248 if (attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ 249 EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS)) 250 return EFI_UNSUPPORTED; 251 252 /* Make sure if runtime bit is set, boot service bit is set also */ 253 if ((attributes & 254 (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 255 EFI_VARIABLE_RUNTIME_ACCESS) 256 return EFI_INVALID_PARAMETER; 257 258 /* only EFI_VARIABLE_NON_VOLATILE attribute is invalid */ 259 if ((attributes & EFI_VARIABLE_MASK) == EFI_VARIABLE_NON_VOLATILE) 260 return EFI_INVALID_PARAMETER; 261 262 /* Make sure HR is set with NV, BS and RT */ 263 if (attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD && 264 (!(attributes & EFI_VARIABLE_NON_VOLATILE) || 265 !(attributes & EFI_VARIABLE_RUNTIME_ACCESS) || 266 !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))) 267 return EFI_INVALID_PARAMETER; 268 269 return EFI_SUCCESS; 270} 271 272efi_status_t efi_set_variable_int(const u16 *variable_name, 273 const efi_guid_t *vendor, 274 u32 attributes, efi_uintn_t data_size, 275 const void *data, bool ro_check) 276{ 277 struct efi_var_entry *var; 278 efi_uintn_t ret; 279 bool append, delete; 280 u64 time = 0; 281 enum efi_auth_var_type var_type; 282 283 ret = setvariable_allowed(variable_name, vendor, attributes, data_size, 284 data); 285 if (ret != EFI_SUCCESS) 286 return ret; 287 288 /* check if a variable exists */ 289 var = efi_var_mem_find(vendor, variable_name, NULL); 290 append = !!(attributes & EFI_VARIABLE_APPEND_WRITE); 291 delete = !append && (!data_size || !attributes); 292 293 /* check attributes */ 294 var_type = efi_auth_var_get_type(variable_name, vendor); 295 if (var) { 296 if (ro_check && (var->attr & EFI_VARIABLE_READ_ONLY)) 297 return EFI_WRITE_PROTECTED; 298 299 if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) { 300 if (var_type >= EFI_AUTH_VAR_PK) 301 return EFI_WRITE_PROTECTED; 302 } 303 304 /* attributes won't be changed */ 305 if (!delete && 306 ((ro_check && var->attr != (attributes & ~EFI_VARIABLE_APPEND_WRITE)) || 307 (!ro_check && ((var->attr & ~EFI_VARIABLE_READ_ONLY) 308 != (attributes & ~EFI_VARIABLE_READ_ONLY))))) { 309 return EFI_INVALID_PARAMETER; 310 } 311 time = var->time; 312 } else { 313 /* 314 * UEFI specification does not clearly describe the expected 315 * behavior of append write with data size 0, we follow 316 * the EDK II reference implementation. 317 */ 318 if (append && !data_size) 319 return EFI_SUCCESS; 320 321 /* 322 * EFI_VARIABLE_APPEND_WRITE to non-existent variable is accepted 323 * and new variable is created in EDK II reference implementation. 324 * We follow it and only check the deletion here. 325 */ 326 if (delete) 327 /* Trying to delete a non-existent variable. */ 328 return EFI_NOT_FOUND; 329 } 330 331 if (var_type >= EFI_AUTH_VAR_PK) { 332 /* authentication is mandatory */ 333 if (!(attributes & 334 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) { 335 EFI_PRINT("%ls: TIME_BASED_AUTHENTICATED_WRITE_ACCESS required\n", 336 variable_name); 337 return EFI_INVALID_PARAMETER; 338 } 339 } 340 341 /* authenticate a variable */ 342 if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) { 343 if (attributes & 344 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { 345 u32 env_attr; 346 347 ret = efi_variable_authenticate(variable_name, vendor, 348 &data_size, &data, 349 attributes, &env_attr, 350 &time); 351 if (ret != EFI_SUCCESS) 352 return ret; 353 354 /* last chance to check for delete */ 355 if (!data_size) 356 delete = true; 357 } 358 } else { 359 if (attributes & 360 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) { 361 EFI_PRINT("Secure boot is not configured\n"); 362 return EFI_INVALID_PARAMETER; 363 } 364 } 365 366 if (delete) { 367 /* EFI_NOT_FOUND has been handled before */ 368 attributes = var->attr; 369 ret = EFI_SUCCESS; 370 } else if (append && var) { 371 /* 372 * data is appended if EFI_VARIABLE_APPEND_WRITE is set and 373 * variable exists. 374 */ 375 u16 *old_data = var->name; 376 377 for (; *old_data; ++old_data) 378 ; 379 ++old_data; 380 ret = efi_var_mem_ins(variable_name, vendor, 381 attributes & ~EFI_VARIABLE_APPEND_WRITE, 382 var->length, old_data, data_size, data, 383 time); 384 } else { 385 ret = efi_var_mem_ins(variable_name, vendor, attributes, 386 data_size, data, 0, NULL, time); 387 } 388 389 if (ret != EFI_SUCCESS) 390 return ret; 391 392 efi_var_mem_del(var); 393 394 if (var_type == EFI_AUTH_VAR_PK) 395 ret = efi_init_secure_state(); 396 else 397 ret = EFI_SUCCESS; 398 399 /* 400 * Write non-volatile EFI variables to file 401 * TODO: check if a value change has occured to avoid superfluous writes 402 */ 403 if (attributes & EFI_VARIABLE_NON_VOLATILE) 404 efi_var_to_file(); 405 406 return EFI_SUCCESS; 407} 408 409efi_status_t __efi_runtime 410efi_query_variable_info_int(u32 attributes, 411 u64 *maximum_variable_storage_size, 412 u64 *remaining_variable_storage_size, 413 u64 *maximum_variable_size) 414{ 415 if (!maximum_variable_storage_size || 416 !remaining_variable_storage_size || 417 !maximum_variable_size || !attributes) 418 return EFI_INVALID_PARAMETER; 419 420 /* EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated */ 421 if ((attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) || 422 ((attributes & EFI_VARIABLE_MASK) == 0)) 423 return EFI_UNSUPPORTED; 424 425 if ((attributes & EFI_VARIABLE_MASK) == EFI_VARIABLE_NON_VOLATILE) 426 return EFI_INVALID_PARAMETER; 427 428 /* Make sure if runtime bit is set, boot service bit is set also. */ 429 if ((attributes & 430 (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 431 EFI_VARIABLE_RUNTIME_ACCESS) 432 return EFI_INVALID_PARAMETER; 433 434 if (attributes & ~EFI_VARIABLE_MASK) 435 return EFI_INVALID_PARAMETER; 436 437 *maximum_variable_storage_size = EFI_VAR_BUF_SIZE - 438 sizeof(struct efi_var_file); 439 *remaining_variable_storage_size = efi_var_mem_free(); 440 *maximum_variable_size = EFI_VAR_BUF_SIZE - 441 sizeof(struct efi_var_file) - 442 sizeof(struct efi_var_entry); 443 return EFI_SUCCESS; 444} 445 446/** 447 * efi_query_variable_info_runtime() - runtime implementation of 448 * QueryVariableInfo() 449 * 450 * @attributes: bitmask to select variables to be 451 * queried 452 * @maximum_variable_storage_size: maximum size of storage area for the 453 * selected variable types 454 * @remaining_variable_storage_size: remaining size of storage are for the 455 * selected variable types 456 * @maximum_variable_size: maximum size of a variable of the 457 * selected type 458 * Returns: status code 459 */ 460static efi_status_t __efi_runtime EFIAPI efi_query_variable_info_runtime( 461 u32 attributes, 462 u64 *maximum_variable_storage_size, 463 u64 *remaining_variable_storage_size, 464 u64 *maximum_variable_size) 465{ 466 if (!(attributes & EFI_VARIABLE_RUNTIME_ACCESS)) 467 return EFI_INVALID_PARAMETER; 468 if ((attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | 469 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | 470 EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS))) 471 return EFI_UNSUPPORTED; 472 473 return efi_query_variable_info_int(attributes, 474 maximum_variable_storage_size, 475 remaining_variable_storage_size, 476 maximum_variable_size); 477} 478 479/** 480 * efi_set_variable_runtime() - runtime implementation of SetVariable() 481 * 482 * @variable_name: name of the variable 483 * @vendor: vendor GUID 484 * @attributes: attributes of the variable 485 * @data_size: size of the buffer with the variable value 486 * @data: buffer with the variable value 487 * Return: status code 488 */ 489static efi_status_t __efi_runtime EFIAPI 490efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *vendor, 491 u32 attributes, efi_uintn_t data_size, 492 const void *data) 493{ 494 struct efi_var_entry *var; 495 efi_uintn_t ret; 496 bool append, delete; 497 u64 time = 0; 498 499 if (!IS_ENABLED(CONFIG_EFI_RT_VOLATILE_STORE)) 500 return EFI_UNSUPPORTED; 501 502 /* 503 * Authenticated variables are not supported. The EFI spec 504 * in §32.3.6 requires keys to be stored in non-volatile storage which 505 * is tamper and delete resistant. 506 * The rest of the checks are in setvariable_allowed() 507 */ 508 if (attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) 509 return EFI_INVALID_PARAMETER; 510 511 ret = setvariable_allowed(variable_name, vendor, attributes, data_size, 512 data); 513 if (ret != EFI_SUCCESS) 514 return ret; 515 516 /* check if a variable exists */ 517 var = efi_var_mem_find(vendor, variable_name, NULL); 518 append = !!(attributes & EFI_VARIABLE_APPEND_WRITE); 519 attributes &= ~EFI_VARIABLE_APPEND_WRITE; 520 delete = !append && (!data_size || !attributes); 521 522 /* BS only variables are hidden deny writing them */ 523 if (!delete && !(attributes & EFI_VARIABLE_RUNTIME_ACCESS)) 524 return EFI_INVALID_PARAMETER; 525 526 if (var) { 527 if (var->attr & EFI_VARIABLE_READ_ONLY || 528 !(var->attr & EFI_VARIABLE_NON_VOLATILE)) 529 return EFI_WRITE_PROTECTED; 530 531 /* attributes won't be changed */ 532 if (!delete && (((var->attr & ~EFI_VARIABLE_READ_ONLY) != 533 (attributes & ~EFI_VARIABLE_READ_ONLY)))) 534 return EFI_INVALID_PARAMETER; 535 time = var->time; 536 } else { 537 if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) 538 return EFI_INVALID_PARAMETER; 539 if (append && !data_size) 540 return EFI_SUCCESS; 541 if (delete) 542 return EFI_NOT_FOUND; 543 } 544 545 if (delete) { 546 /* EFI_NOT_FOUND has been handled before */ 547 attributes = var->attr; 548 ret = EFI_SUCCESS; 549 } else if (append && var) { 550 u16 *old_data = (void *)((uintptr_t)var->name + 551 sizeof(u16) * (u16_strlen(var->name) + 1)); 552 553 ret = efi_var_mem_ins(variable_name, vendor, attributes, 554 var->length, old_data, data_size, data, 555 time); 556 } else { 557 ret = efi_var_mem_ins(variable_name, vendor, attributes, 558 data_size, data, 0, NULL, time); 559 } 560 561 if (ret != EFI_SUCCESS) 562 return ret; 563 /* We are always inserting new variables, get rid of the old copy */ 564 efi_var_mem_del(var); 565 566 return EFI_SUCCESS; 567} 568 569/** 570 * efi_variables_boot_exit_notify() - notify ExitBootServices() is called 571 */ 572void efi_variables_boot_exit_notify(void) 573{ 574 /* Switch variable services functions to runtime version */ 575 efi_runtime_services.get_variable = efi_get_variable_runtime; 576 efi_runtime_services.get_next_variable_name = 577 efi_get_next_variable_name_runtime; 578 efi_runtime_services.set_variable = efi_set_variable_runtime; 579 efi_runtime_services.query_variable_info = 580 efi_query_variable_info_runtime; 581 efi_update_table_header_crc32(&efi_runtime_services.hdr); 582} 583 584/** 585 * efi_init_variables() - initialize variable services 586 * 587 * Return: status code 588 */ 589efi_status_t efi_init_variables(void) 590{ 591 efi_status_t ret; 592 593 ret = efi_var_mem_init(); 594 if (ret != EFI_SUCCESS) 595 return ret; 596 597 ret = efi_var_from_file(); 598 if (ret != EFI_SUCCESS) 599 return ret; 600 if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) { 601 ret = efi_var_restore((struct efi_var_file *) 602 __efi_var_file_begin, true); 603 if (ret != EFI_SUCCESS) 604 log_err("Invalid EFI variable seed\n"); 605 } 606 607 return efi_init_secure_state(); 608}