SecureBootVariableProvisionLib.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. /** @file
  2. This library provides functions to set/clear Secure Boot
  3. keys and databases.
  4. Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
  5. (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
  6. Copyright (c) 2021, ARM Ltd. All rights reserved.<BR>
  7. Copyright (c) 2021, Semihalf All rights reserved.<BR>
  8. SPDX-License-Identifier: BSD-2-Clause-Patent
  9. **/
  10. #include <Guid/GlobalVariable.h>
  11. #include <Guid/AuthenticatedVariableFormat.h>
  12. #include <Guid/ImageAuthentication.h>
  13. #include <Library/BaseLib.h>
  14. #include <Library/BaseMemoryLib.h>
  15. #include <Library/DebugLib.h>
  16. #include <Library/UefiLib.h>
  17. #include <Library/MemoryAllocationLib.h>
  18. #include <Library/UefiRuntimeServicesTableLib.h>
  19. #include <Library/SecureBootVariableLib.h>
  20. #include <Library/SecureBootVariableProvisionLib.h>
  21. /**
  22. Enroll a key/certificate based on a default variable.
  23. @param[in] VariableName The name of the key/database.
  24. @param[in] DefaultName The name of the default variable.
  25. @param[in] VendorGuid The namespace (ie. vendor GUID) of the variable
  26. @retval EFI_OUT_OF_RESOURCES Out of memory while allocating AuthHeader.
  27. @retval EFI_SUCCESS Successful enrollment.
  28. @return Error codes from GetTime () and SetVariable ().
  29. **/
  30. STATIC
  31. EFI_STATUS
  32. EnrollFromDefault (
  33. IN CHAR16 *VariableName,
  34. IN CHAR16 *DefaultName,
  35. IN EFI_GUID *VendorGuid
  36. )
  37. {
  38. VOID *Data;
  39. UINTN DataSize;
  40. EFI_STATUS Status;
  41. Status = EFI_SUCCESS;
  42. DataSize = 0;
  43. Status = GetVariable2 (DefaultName, &gEfiGlobalVariableGuid, &Data, &DataSize);
  44. if (EFI_ERROR (Status)) {
  45. DEBUG ((DEBUG_ERROR, "error: GetVariable (\"%s): %r\n", DefaultName, Status));
  46. return Status;
  47. }
  48. CreateTimeBasedPayload (&DataSize, (UINT8 **)&Data);
  49. if (EFI_ERROR (Status)) {
  50. DEBUG ((DEBUG_ERROR, "Fail to create time-based data payload: %r", Status));
  51. return Status;
  52. }
  53. //
  54. // Allocate memory for auth variable
  55. //
  56. Status = gRT->SetVariable (
  57. VariableName,
  58. VendorGuid,
  59. (EFI_VARIABLE_NON_VOLATILE |
  60. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  61. EFI_VARIABLE_RUNTIME_ACCESS |
  62. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
  63. DataSize,
  64. Data
  65. );
  66. if (EFI_ERROR (Status)) {
  67. DEBUG ((
  68. DEBUG_ERROR,
  69. "error: %a (\"%s\", %g): %r\n",
  70. __FUNCTION__,
  71. VariableName,
  72. VendorGuid,
  73. Status
  74. ));
  75. }
  76. if (Data != NULL) {
  77. FreePool (Data);
  78. }
  79. return Status;
  80. }
  81. /** Initializes PKDefault variable with data from FFS section.
  82. @retval EFI_SUCCESS Variable was initialized successfully.
  83. @retval EFI_UNSUPPORTED Variable already exists.
  84. **/
  85. EFI_STATUS
  86. SecureBootInitPKDefault (
  87. IN VOID
  88. )
  89. {
  90. EFI_SIGNATURE_LIST *EfiSig;
  91. UINTN SigListsSize;
  92. EFI_STATUS Status;
  93. UINT8 *Data;
  94. UINTN DataSize;
  95. //
  96. // Check if variable exists, if so do not change it
  97. //
  98. Status = GetVariable2 (EFI_PK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
  99. if (Status == EFI_SUCCESS) {
  100. DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_PK_DEFAULT_VARIABLE_NAME));
  101. FreePool (Data);
  102. return EFI_UNSUPPORTED;
  103. }
  104. if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
  105. return Status;
  106. }
  107. //
  108. // Variable does not exist, can be initialized
  109. //
  110. DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_PK_DEFAULT_VARIABLE_NAME));
  111. Status = SecureBootFetchData (&gDefaultPKFileGuid, &SigListsSize, &EfiSig);
  112. if (EFI_ERROR (Status)) {
  113. DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_PK_DEFAULT_VARIABLE_NAME));
  114. return Status;
  115. }
  116. Status = gRT->SetVariable (
  117. EFI_PK_DEFAULT_VARIABLE_NAME,
  118. &gEfiGlobalVariableGuid,
  119. EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  120. SigListsSize,
  121. (VOID *)EfiSig
  122. );
  123. if (EFI_ERROR (Status)) {
  124. DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_PK_DEFAULT_VARIABLE_NAME));
  125. }
  126. FreePool (EfiSig);
  127. return Status;
  128. }
  129. /** Initializes KEKDefault variable with data from FFS section.
  130. @retval EFI_SUCCESS Variable was initialized successfully.
  131. @retval EFI_UNSUPPORTED Variable already exists.
  132. **/
  133. EFI_STATUS
  134. SecureBootInitKEKDefault (
  135. IN VOID
  136. )
  137. {
  138. EFI_SIGNATURE_LIST *EfiSig;
  139. UINTN SigListsSize;
  140. EFI_STATUS Status;
  141. UINT8 *Data;
  142. UINTN DataSize;
  143. //
  144. // Check if variable exists, if so do not change it
  145. //
  146. Status = GetVariable2 (EFI_KEK_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
  147. if (Status == EFI_SUCCESS) {
  148. DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
  149. FreePool (Data);
  150. return EFI_UNSUPPORTED;
  151. }
  152. if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
  153. return Status;
  154. }
  155. //
  156. // Variable does not exist, can be initialized
  157. //
  158. DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
  159. Status = SecureBootFetchData (&gDefaultKEKFileGuid, &SigListsSize, &EfiSig);
  160. if (EFI_ERROR (Status)) {
  161. DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
  162. return Status;
  163. }
  164. Status = gRT->SetVariable (
  165. EFI_KEK_DEFAULT_VARIABLE_NAME,
  166. &gEfiGlobalVariableGuid,
  167. EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  168. SigListsSize,
  169. (VOID *)EfiSig
  170. );
  171. if (EFI_ERROR (Status)) {
  172. DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_KEK_DEFAULT_VARIABLE_NAME));
  173. }
  174. FreePool (EfiSig);
  175. return Status;
  176. }
  177. /** Initializes dbDefault variable with data from FFS section.
  178. @retval EFI_SUCCESS Variable was initialized successfully.
  179. @retval EFI_UNSUPPORTED Variable already exists.
  180. **/
  181. EFI_STATUS
  182. SecureBootInitDbDefault (
  183. IN VOID
  184. )
  185. {
  186. EFI_SIGNATURE_LIST *EfiSig;
  187. UINTN SigListsSize;
  188. EFI_STATUS Status;
  189. UINT8 *Data;
  190. UINTN DataSize;
  191. Status = GetVariable2 (EFI_DB_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
  192. if (Status == EFI_SUCCESS) {
  193. DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DB_DEFAULT_VARIABLE_NAME));
  194. FreePool (Data);
  195. return EFI_UNSUPPORTED;
  196. }
  197. if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
  198. return Status;
  199. }
  200. DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DB_DEFAULT_VARIABLE_NAME));
  201. Status = SecureBootFetchData (&gDefaultdbFileGuid, &SigListsSize, &EfiSig);
  202. if (EFI_ERROR (Status)) {
  203. return Status;
  204. }
  205. Status = gRT->SetVariable (
  206. EFI_DB_DEFAULT_VARIABLE_NAME,
  207. &gEfiGlobalVariableGuid,
  208. EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  209. SigListsSize,
  210. (VOID *)EfiSig
  211. );
  212. if (EFI_ERROR (Status)) {
  213. DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DB_DEFAULT_VARIABLE_NAME));
  214. }
  215. FreePool (EfiSig);
  216. return Status;
  217. }
  218. /** Initializes dbxDefault variable with data from FFS section.
  219. @retval EFI_SUCCESS Variable was initialized successfully.
  220. @retval EFI_UNSUPPORTED Variable already exists.
  221. **/
  222. EFI_STATUS
  223. SecureBootInitDbxDefault (
  224. IN VOID
  225. )
  226. {
  227. EFI_SIGNATURE_LIST *EfiSig;
  228. UINTN SigListsSize;
  229. EFI_STATUS Status;
  230. UINT8 *Data;
  231. UINTN DataSize;
  232. //
  233. // Check if variable exists, if so do not change it
  234. //
  235. Status = GetVariable2 (EFI_DBX_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
  236. if (Status == EFI_SUCCESS) {
  237. DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
  238. FreePool (Data);
  239. return EFI_UNSUPPORTED;
  240. }
  241. if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
  242. return Status;
  243. }
  244. //
  245. // Variable does not exist, can be initialized
  246. //
  247. DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
  248. Status = SecureBootFetchData (&gDefaultdbxFileGuid, &SigListsSize, &EfiSig);
  249. if (EFI_ERROR (Status)) {
  250. DEBUG ((DEBUG_INFO, "Content for %s not found\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
  251. return Status;
  252. }
  253. Status = gRT->SetVariable (
  254. EFI_DBX_DEFAULT_VARIABLE_NAME,
  255. &gEfiGlobalVariableGuid,
  256. EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  257. SigListsSize,
  258. (VOID *)EfiSig
  259. );
  260. if (EFI_ERROR (Status)) {
  261. DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBX_DEFAULT_VARIABLE_NAME));
  262. }
  263. FreePool (EfiSig);
  264. return Status;
  265. }
  266. /** Initializes dbtDefault variable with data from FFS section.
  267. @retval EFI_SUCCESS Variable was initialized successfully.
  268. @retval EFI_UNSUPPORTED Variable already exists.
  269. **/
  270. EFI_STATUS
  271. SecureBootInitDbtDefault (
  272. IN VOID
  273. )
  274. {
  275. EFI_SIGNATURE_LIST *EfiSig;
  276. UINTN SigListsSize;
  277. EFI_STATUS Status;
  278. UINT8 *Data;
  279. UINTN DataSize;
  280. //
  281. // Check if variable exists, if so do not change it
  282. //
  283. Status = GetVariable2 (EFI_DBT_DEFAULT_VARIABLE_NAME, &gEfiGlobalVariableGuid, (VOID **)&Data, &DataSize);
  284. if (Status == EFI_SUCCESS) {
  285. DEBUG ((DEBUG_INFO, "Variable %s exists. Old value is preserved\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
  286. FreePool (Data);
  287. return EFI_UNSUPPORTED;
  288. }
  289. if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
  290. return Status;
  291. }
  292. //
  293. // Variable does not exist, can be initialized
  294. //
  295. DEBUG ((DEBUG_INFO, "Variable %s does not exist.\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
  296. Status = SecureBootFetchData (&gDefaultdbtFileGuid, &SigListsSize, &EfiSig);
  297. if (EFI_ERROR (Status)) {
  298. return Status;
  299. }
  300. Status = gRT->SetVariable (
  301. EFI_DBT_DEFAULT_VARIABLE_NAME,
  302. &gEfiGlobalVariableGuid,
  303. EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  304. SigListsSize,
  305. (VOID *)EfiSig
  306. );
  307. if (EFI_ERROR (Status)) {
  308. DEBUG ((DEBUG_INFO, "Failed to set %s\n", EFI_DBT_DEFAULT_VARIABLE_NAME));
  309. }
  310. FreePool (EfiSig);
  311. return EFI_SUCCESS;
  312. }
  313. /**
  314. Sets the content of the 'db' variable based on 'dbDefault' variable content.
  315. @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
  316. while VendorGuid is NULL.
  317. @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
  318. **/
  319. EFI_STATUS
  320. EFIAPI
  321. EnrollDbFromDefault (
  322. VOID
  323. )
  324. {
  325. EFI_STATUS Status;
  326. Status = EnrollFromDefault (
  327. EFI_IMAGE_SECURITY_DATABASE,
  328. EFI_DB_DEFAULT_VARIABLE_NAME,
  329. &gEfiImageSecurityDatabaseGuid
  330. );
  331. return Status;
  332. }
  333. /**
  334. Sets the content of the 'dbx' variable based on 'dbxDefault' variable content.
  335. @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
  336. while VendorGuid is NULL.
  337. @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
  338. **/
  339. EFI_STATUS
  340. EFIAPI
  341. EnrollDbxFromDefault (
  342. VOID
  343. )
  344. {
  345. EFI_STATUS Status;
  346. Status = EnrollFromDefault (
  347. EFI_IMAGE_SECURITY_DATABASE1,
  348. EFI_DBX_DEFAULT_VARIABLE_NAME,
  349. &gEfiImageSecurityDatabaseGuid
  350. );
  351. return Status;
  352. }
  353. /**
  354. Sets the content of the 'dbt' variable based on 'dbtDefault' variable content.
  355. @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
  356. while VendorGuid is NULL.
  357. @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
  358. **/
  359. EFI_STATUS
  360. EFIAPI
  361. EnrollDbtFromDefault (
  362. VOID
  363. )
  364. {
  365. EFI_STATUS Status;
  366. Status = EnrollFromDefault (
  367. EFI_IMAGE_SECURITY_DATABASE2,
  368. EFI_DBT_DEFAULT_VARIABLE_NAME,
  369. &gEfiImageSecurityDatabaseGuid
  370. );
  371. return Status;
  372. }
  373. /**
  374. Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
  375. @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
  376. while VendorGuid is NULL.
  377. @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
  378. **/
  379. EFI_STATUS
  380. EFIAPI
  381. EnrollKEKFromDefault (
  382. VOID
  383. )
  384. {
  385. EFI_STATUS Status;
  386. Status = EnrollFromDefault (
  387. EFI_KEY_EXCHANGE_KEY_NAME,
  388. EFI_KEK_DEFAULT_VARIABLE_NAME,
  389. &gEfiGlobalVariableGuid
  390. );
  391. return Status;
  392. }
  393. /**
  394. Sets the content of the 'KEK' variable based on 'KEKDefault' variable content.
  395. @retval EFI_OUT_OF_RESOURCES If memory allocation for EFI_VARIABLE_AUTHENTICATION_2 fails
  396. while VendorGuid is NULL.
  397. @retval other Errors from GetVariable2 (), GetTime () and SetVariable ()
  398. **/
  399. EFI_STATUS
  400. EFIAPI
  401. EnrollPKFromDefault (
  402. VOID
  403. )
  404. {
  405. EFI_STATUS Status;
  406. Status = EnrollFromDefault (
  407. EFI_PLATFORM_KEY_NAME,
  408. EFI_PK_DEFAULT_VARIABLE_NAME,
  409. &gEfiGlobalVariableGuid
  410. );
  411. return Status;
  412. }