efi_variable.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * UEFI runtime variable services
  4. *
  5. * Copyright (c) 2017 Rob Clark
  6. */
  7. #include <common.h>
  8. #include <efi_loader.h>
  9. #include <env_internal.h>
  10. #include <hexdump.h>
  11. #include <malloc.h>
  12. #include <rtc.h>
  13. #include <search.h>
  14. #include <crypto/pkcs7_parser.h>
  15. #include <linux/compat.h>
  16. #include <u-boot/crc.h>
  17. enum efi_secure_mode {
  18. EFI_MODE_SETUP,
  19. EFI_MODE_USER,
  20. EFI_MODE_AUDIT,
  21. EFI_MODE_DEPLOYED,
  22. };
  23. const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
  24. static bool efi_secure_boot;
  25. static int efi_secure_mode;
  26. static u8 efi_vendor_keys;
  27. #define READ_ONLY BIT(31)
  28. /*
  29. * Mapping between EFI variables and u-boot variables:
  30. *
  31. * efi_$guid_$varname = {attributes}(type)value
  32. *
  33. * For example:
  34. *
  35. * efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_OsIndicationsSupported=
  36. * "{ro,boot,run}(blob)0000000000000000"
  37. * efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder=
  38. * "(blob)00010000"
  39. *
  40. * The attributes are a comma separated list of these possible
  41. * attributes:
  42. *
  43. * + ro - read-only
  44. * + boot - boot-services access
  45. * + run - runtime access
  46. *
  47. * NOTE: with current implementation, no variables are available after
  48. * ExitBootServices, and all are persisted (if possible).
  49. *
  50. * If not specified, the attributes default to "{boot}".
  51. *
  52. * The required type is one of:
  53. *
  54. * + utf8 - raw utf8 string
  55. * + blob - arbitrary length hex string
  56. *
  57. * Maybe a utf16 type would be useful to for a string value to be auto
  58. * converted to utf16?
  59. */
  60. #define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_"))
  61. /**
  62. * efi_to_native() - convert the UEFI variable name and vendor GUID to U-Boot
  63. * variable name
  64. *
  65. * The U-Boot variable name is a concatenation of prefix 'efi', the hexstring
  66. * encoded vendor GUID, and the UTF-8 encoded UEFI variable name separated by
  67. * underscores, e.g. 'efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder'.
  68. *
  69. * @native: pointer to pointer to U-Boot variable name
  70. * @variable_name: UEFI variable name
  71. * @vendor: vendor GUID
  72. * Return: status code
  73. */
  74. static efi_status_t efi_to_native(char **native, const u16 *variable_name,
  75. const efi_guid_t *vendor)
  76. {
  77. size_t len;
  78. char *pos;
  79. len = PREFIX_LEN + utf16_utf8_strlen(variable_name) + 1;
  80. *native = malloc(len);
  81. if (!*native)
  82. return EFI_OUT_OF_RESOURCES;
  83. pos = *native;
  84. pos += sprintf(pos, "efi_%pUl_", vendor);
  85. utf16_utf8_strcpy(&pos, variable_name);
  86. return EFI_SUCCESS;
  87. }
  88. /**
  89. * prefix() - skip over prefix
  90. *
  91. * Skip over a prefix string.
  92. *
  93. * @str: string with prefix
  94. * @prefix: prefix string
  95. * Return: string without prefix, or NULL if prefix not found
  96. */
  97. static const char *prefix(const char *str, const char *prefix)
  98. {
  99. size_t n = strlen(prefix);
  100. if (!strncmp(prefix, str, n))
  101. return str + n;
  102. return NULL;
  103. }
  104. /**
  105. * parse_attr() - decode attributes part of variable value
  106. *
  107. * Convert the string encoded attributes of a UEFI variable to a bit mask.
  108. * TODO: Several attributes are not supported.
  109. *
  110. * @str: value of U-Boot variable
  111. * @attrp: pointer to UEFI attributes
  112. * @timep: pointer to time attribute
  113. * Return: pointer to remainder of U-Boot variable value
  114. */
  115. static const char *parse_attr(const char *str, u32 *attrp, u64 *timep)
  116. {
  117. u32 attr = 0;
  118. char sep = '{';
  119. if (*str != '{') {
  120. *attrp = EFI_VARIABLE_BOOTSERVICE_ACCESS;
  121. return str;
  122. }
  123. while (*str == sep) {
  124. const char *s;
  125. str++;
  126. if ((s = prefix(str, "ro"))) {
  127. attr |= READ_ONLY;
  128. } else if ((s = prefix(str, "nv"))) {
  129. attr |= EFI_VARIABLE_NON_VOLATILE;
  130. } else if ((s = prefix(str, "boot"))) {
  131. attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
  132. } else if ((s = prefix(str, "run"))) {
  133. attr |= EFI_VARIABLE_RUNTIME_ACCESS;
  134. } else if ((s = prefix(str, "time="))) {
  135. attr |= EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  136. hex2bin((u8 *)timep, s, sizeof(*timep));
  137. s += sizeof(*timep) * 2;
  138. } else if (*str == '}') {
  139. break;
  140. } else {
  141. printf("invalid attribute: %s\n", str);
  142. break;
  143. }
  144. str = s;
  145. sep = ',';
  146. }
  147. str++;
  148. *attrp = attr;
  149. return str;
  150. }
  151. static efi_status_t efi_set_variable_internal(u16 *variable_name,
  152. const efi_guid_t *vendor,
  153. u32 attributes,
  154. efi_uintn_t data_size,
  155. const void *data,
  156. bool ro_check);
  157. /**
  158. * efi_transfer_secure_state - handle a secure boot state transition
  159. * @mode: new state
  160. *
  161. * Depending on @mode, secure boot related variables are updated.
  162. * Those variables are *read-only* for users, efi_set_variable_internal()
  163. * is called here.
  164. *
  165. * Return: EFI_SUCCESS on success, status code (negative) on error
  166. */
  167. static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode)
  168. {
  169. u32 attributes;
  170. u8 val;
  171. efi_status_t ret;
  172. debug("Secure state from %d to %d\n", efi_secure_mode, mode);
  173. attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
  174. EFI_VARIABLE_RUNTIME_ACCESS;
  175. if (mode == EFI_MODE_DEPLOYED) {
  176. val = 1;
  177. ret = efi_set_variable_internal(L"SecureBoot",
  178. &efi_global_variable_guid,
  179. attributes | READ_ONLY,
  180. sizeof(val), &val,
  181. false);
  182. if (ret != EFI_SUCCESS)
  183. goto err;
  184. val = 0;
  185. ret = efi_set_variable_internal(L"SetupMode",
  186. &efi_global_variable_guid,
  187. attributes | READ_ONLY,
  188. sizeof(val), &val,
  189. false);
  190. if (ret != EFI_SUCCESS)
  191. goto err;
  192. val = 0;
  193. ret = efi_set_variable_internal(L"AuditMode",
  194. &efi_global_variable_guid,
  195. attributes | READ_ONLY,
  196. sizeof(val), &val,
  197. false);
  198. if (ret != EFI_SUCCESS)
  199. goto err;
  200. val = 1;
  201. ret = efi_set_variable_internal(L"DeployedMode",
  202. &efi_global_variable_guid,
  203. attributes | READ_ONLY,
  204. sizeof(val), &val,
  205. false);
  206. if (ret != EFI_SUCCESS)
  207. goto err;
  208. efi_secure_boot = true;
  209. } else if (mode == EFI_MODE_AUDIT) {
  210. ret = efi_set_variable_internal(L"PK",
  211. &efi_global_variable_guid,
  212. attributes,
  213. 0, NULL,
  214. false);
  215. if (ret != EFI_SUCCESS)
  216. goto err;
  217. val = 0;
  218. ret = efi_set_variable_internal(L"SecureBoot",
  219. &efi_global_variable_guid,
  220. attributes | READ_ONLY,
  221. sizeof(val), &val,
  222. false);
  223. if (ret != EFI_SUCCESS)
  224. goto err;
  225. val = 1;
  226. ret = efi_set_variable_internal(L"SetupMode",
  227. &efi_global_variable_guid,
  228. attributes | READ_ONLY,
  229. sizeof(val), &val,
  230. false);
  231. if (ret != EFI_SUCCESS)
  232. goto err;
  233. val = 1;
  234. ret = efi_set_variable_internal(L"AuditMode",
  235. &efi_global_variable_guid,
  236. attributes | READ_ONLY,
  237. sizeof(val), &val,
  238. false);
  239. if (ret != EFI_SUCCESS)
  240. goto err;
  241. val = 0;
  242. ret = efi_set_variable_internal(L"DeployedMode",
  243. &efi_global_variable_guid,
  244. attributes | READ_ONLY,
  245. sizeof(val), &val,
  246. false);
  247. if (ret != EFI_SUCCESS)
  248. goto err;
  249. efi_secure_boot = true;
  250. } else if (mode == EFI_MODE_USER) {
  251. val = 1;
  252. ret = efi_set_variable_internal(L"SecureBoot",
  253. &efi_global_variable_guid,
  254. attributes | READ_ONLY,
  255. sizeof(val), &val,
  256. false);
  257. if (ret != EFI_SUCCESS)
  258. goto err;
  259. val = 0;
  260. ret = efi_set_variable_internal(L"SetupMode",
  261. &efi_global_variable_guid,
  262. attributes | READ_ONLY,
  263. sizeof(val), &val,
  264. false);
  265. if (ret != EFI_SUCCESS)
  266. goto err;
  267. val = 0;
  268. ret = efi_set_variable_internal(L"AuditMode",
  269. &efi_global_variable_guid,
  270. attributes,
  271. sizeof(val), &val,
  272. false);
  273. if (ret != EFI_SUCCESS)
  274. goto err;
  275. val = 0;
  276. ret = efi_set_variable_internal(L"DeployedMode",
  277. &efi_global_variable_guid,
  278. attributes,
  279. sizeof(val), &val,
  280. false);
  281. if (ret != EFI_SUCCESS)
  282. goto err;
  283. efi_secure_boot = true;
  284. } else if (mode == EFI_MODE_SETUP) {
  285. val = 0;
  286. ret = efi_set_variable_internal(L"SecureBoot",
  287. &efi_global_variable_guid,
  288. attributes | READ_ONLY,
  289. sizeof(val), &val,
  290. false);
  291. if (ret != EFI_SUCCESS)
  292. goto err;
  293. val = 1;
  294. ret = efi_set_variable_internal(L"SetupMode",
  295. &efi_global_variable_guid,
  296. attributes | READ_ONLY,
  297. sizeof(val), &val,
  298. false);
  299. if (ret != EFI_SUCCESS)
  300. goto err;
  301. val = 0;
  302. ret = efi_set_variable_internal(L"AuditMode",
  303. &efi_global_variable_guid,
  304. attributes,
  305. sizeof(val), &val,
  306. false);
  307. if (ret != EFI_SUCCESS)
  308. goto err;
  309. val = 0;
  310. ret = efi_set_variable_internal(L"DeployedMode",
  311. &efi_global_variable_guid,
  312. attributes | READ_ONLY,
  313. sizeof(val), &val,
  314. false);
  315. if (ret != EFI_SUCCESS)
  316. goto err;
  317. } else {
  318. return EFI_INVALID_PARAMETER;
  319. }
  320. efi_secure_mode = mode;
  321. return EFI_SUCCESS;
  322. err:
  323. /* TODO: What action should be taken here? */
  324. printf("ERROR: Secure state transition failed\n");
  325. return ret;
  326. }
  327. /**
  328. * efi_init_secure_state - initialize secure boot state
  329. *
  330. * Return: EFI_SUCCESS on success, status code (negative) on error
  331. */
  332. static efi_status_t efi_init_secure_state(void)
  333. {
  334. enum efi_secure_mode mode;
  335. efi_uintn_t size;
  336. efi_status_t ret;
  337. /*
  338. * TODO:
  339. * Since there is currently no "platform-specific" installation
  340. * method of Platform Key, we can't say if VendorKeys is 0 or 1
  341. * precisely.
  342. */
  343. size = 0;
  344. ret = EFI_CALL(efi_get_variable(L"PK", &efi_global_variable_guid,
  345. NULL, &size, NULL));
  346. if (ret == EFI_BUFFER_TOO_SMALL) {
  347. if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
  348. mode = EFI_MODE_USER;
  349. else
  350. mode = EFI_MODE_SETUP;
  351. efi_vendor_keys = 0;
  352. } else if (ret == EFI_NOT_FOUND) {
  353. mode = EFI_MODE_SETUP;
  354. efi_vendor_keys = 1;
  355. } else {
  356. goto err;
  357. }
  358. ret = efi_transfer_secure_state(mode);
  359. if (ret == EFI_SUCCESS)
  360. ret = efi_set_variable_internal(L"VendorKeys",
  361. &efi_global_variable_guid,
  362. EFI_VARIABLE_BOOTSERVICE_ACCESS
  363. | EFI_VARIABLE_RUNTIME_ACCESS
  364. | READ_ONLY,
  365. sizeof(efi_vendor_keys),
  366. &efi_vendor_keys,
  367. false);
  368. err:
  369. return ret;
  370. }
  371. /**
  372. * efi_secure_boot_enabled - return if secure boot is enabled or not
  373. *
  374. * Return: true if enabled, false if disabled
  375. */
  376. bool efi_secure_boot_enabled(void)
  377. {
  378. return efi_secure_boot;
  379. }
  380. #ifdef CONFIG_EFI_SECURE_BOOT
  381. static u8 pkcs7_hdr[] = {
  382. /* SEQUENCE */
  383. 0x30, 0x82, 0x05, 0xc7,
  384. /* OID: pkcs7-signedData */
  385. 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
  386. /* Context Structured? */
  387. 0xa0, 0x82, 0x05, 0xb8,
  388. };
  389. /**
  390. * efi_variable_parse_signature - parse a signature in variable
  391. * @buf: Pointer to variable's value
  392. * @buflen: Length of @buf
  393. *
  394. * Parse a signature embedded in variable's value and instantiate
  395. * a pkcs7_message structure. Since pkcs7_parse_message() accepts only
  396. * pkcs7's signedData, some header needed be prepended for correctly
  397. * parsing authentication data, particularly for variable's.
  398. *
  399. * Return: Pointer to pkcs7_message structure on success, NULL on error
  400. */
  401. static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
  402. size_t buflen)
  403. {
  404. u8 *ebuf;
  405. size_t ebuflen, len;
  406. struct pkcs7_message *msg;
  407. /*
  408. * This is the best assumption to check if the binary is
  409. * already in a form of pkcs7's signedData.
  410. */
  411. if (buflen > sizeof(pkcs7_hdr) &&
  412. !memcmp(&((u8 *)buf)[4], &pkcs7_hdr[4], 11)) {
  413. msg = pkcs7_parse_message(buf, buflen);
  414. goto out;
  415. }
  416. /*
  417. * Otherwise, we should add a dummy prefix sequence for pkcs7
  418. * message parser to be able to process.
  419. * NOTE: EDK2 also uses similar hack in WrapPkcs7Data()
  420. * in CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyCommon.c
  421. * TODO:
  422. * The header should be composed in a more refined manner.
  423. */
  424. debug("Makeshift prefix added to authentication data\n");
  425. ebuflen = sizeof(pkcs7_hdr) + buflen;
  426. if (ebuflen <= 0x7f) {
  427. debug("Data is too short\n");
  428. return NULL;
  429. }
  430. ebuf = malloc(ebuflen);
  431. if (!ebuf) {
  432. debug("Out of memory\n");
  433. return NULL;
  434. }
  435. memcpy(ebuf, pkcs7_hdr, sizeof(pkcs7_hdr));
  436. memcpy(ebuf + sizeof(pkcs7_hdr), buf, buflen);
  437. len = ebuflen - 4;
  438. ebuf[2] = (len >> 8) & 0xff;
  439. ebuf[3] = len & 0xff;
  440. len = ebuflen - 0x13;
  441. ebuf[0x11] = (len >> 8) & 0xff;
  442. ebuf[0x12] = len & 0xff;
  443. msg = pkcs7_parse_message(ebuf, ebuflen);
  444. free(ebuf);
  445. out:
  446. if (IS_ERR(msg))
  447. return NULL;
  448. return msg;
  449. }
  450. /**
  451. * efi_variable_authenticate - authenticate a variable
  452. * @variable: Variable name in u16
  453. * @vendor: Guid of variable
  454. * @data_size: Size of @data
  455. * @data: Pointer to variable's value
  456. * @given_attr: Attributes to be given at SetVariable()
  457. * @env_attr: Attributes that an existing variable holds
  458. * @time: signed time that an existing variable holds
  459. *
  460. * Called by efi_set_variable() to verify that the input is correct.
  461. * Will replace the given data pointer with another that points to
  462. * the actual data to store in the internal memory.
  463. * On success, @data and @data_size will be replaced with variable's
  464. * actual data, excluding authentication data, and its size, and variable's
  465. * attributes and signed time will also be returned in @env_attr and @time,
  466. * respectively.
  467. *
  468. * Return: EFI_SUCCESS on success, status code (negative) on error
  469. */
  470. static efi_status_t efi_variable_authenticate(u16 *variable,
  471. const efi_guid_t *vendor,
  472. efi_uintn_t *data_size,
  473. const void **data, u32 given_attr,
  474. u32 *env_attr, u64 *time)
  475. {
  476. const struct efi_variable_authentication_2 *auth;
  477. struct efi_signature_store *truststore, *truststore2;
  478. struct pkcs7_message *var_sig;
  479. struct efi_image_regions *regs;
  480. struct efi_time timestamp;
  481. struct rtc_time tm;
  482. u64 new_time;
  483. efi_status_t ret;
  484. var_sig = NULL;
  485. truststore = NULL;
  486. truststore2 = NULL;
  487. regs = NULL;
  488. ret = EFI_SECURITY_VIOLATION;
  489. if (*data_size < sizeof(struct efi_variable_authentication_2))
  490. goto err;
  491. /* authentication data */
  492. auth = *data;
  493. if (*data_size < (sizeof(auth->time_stamp)
  494. + auth->auth_info.hdr.dwLength))
  495. goto err;
  496. if (guidcmp(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
  497. goto err;
  498. *data += sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength;
  499. *data_size -= (sizeof(auth->time_stamp)
  500. + auth->auth_info.hdr.dwLength);
  501. memcpy(&timestamp, &auth->time_stamp, sizeof(timestamp));
  502. memset(&tm, 0, sizeof(tm));
  503. tm.tm_year = timestamp.year;
  504. tm.tm_mon = timestamp.month;
  505. tm.tm_mday = timestamp.day;
  506. tm.tm_hour = timestamp.hour;
  507. tm.tm_min = timestamp.minute;
  508. tm.tm_sec = timestamp.second;
  509. new_time = rtc_mktime(&tm);
  510. if (!efi_secure_boot_enabled()) {
  511. /* finished checking */
  512. *time = new_time;
  513. return EFI_SUCCESS;
  514. }
  515. if (new_time <= *time)
  516. goto err;
  517. /* data to be digested */
  518. regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 5, 1);
  519. if (!regs)
  520. goto err;
  521. regs->max = 5;
  522. efi_image_region_add(regs, (uint8_t *)variable,
  523. (uint8_t *)variable
  524. + u16_strlen(variable) * sizeof(u16), 1);
  525. efi_image_region_add(regs, (uint8_t *)vendor,
  526. (uint8_t *)vendor + sizeof(*vendor), 1);
  527. efi_image_region_add(regs, (uint8_t *)&given_attr,
  528. (uint8_t *)&given_attr + sizeof(given_attr), 1);
  529. efi_image_region_add(regs, (uint8_t *)&timestamp,
  530. (uint8_t *)&timestamp + sizeof(timestamp), 1);
  531. efi_image_region_add(regs, (uint8_t *)*data,
  532. (uint8_t *)*data + *data_size, 1);
  533. /* variable's signature list */
  534. if (auth->auth_info.hdr.dwLength < sizeof(auth->auth_info))
  535. goto err;
  536. var_sig = efi_variable_parse_signature(auth->auth_info.cert_data,
  537. auth->auth_info.hdr.dwLength
  538. - sizeof(auth->auth_info));
  539. if (IS_ERR(var_sig)) {
  540. debug("Parsing variable's signature failed\n");
  541. var_sig = NULL;
  542. goto err;
  543. }
  544. /* signature database used for authentication */
  545. if (u16_strcmp(variable, L"PK") == 0 ||
  546. u16_strcmp(variable, L"KEK") == 0) {
  547. /* with PK */
  548. truststore = efi_sigstore_parse_sigdb(L"PK");
  549. if (!truststore)
  550. goto err;
  551. } else if (u16_strcmp(variable, L"db") == 0 ||
  552. u16_strcmp(variable, L"dbx") == 0) {
  553. /* with PK and KEK */
  554. truststore = efi_sigstore_parse_sigdb(L"KEK");
  555. truststore2 = efi_sigstore_parse_sigdb(L"PK");
  556. if (!truststore) {
  557. if (!truststore2)
  558. goto err;
  559. truststore = truststore2;
  560. truststore2 = NULL;
  561. }
  562. } else {
  563. /* TODO: support private authenticated variables */
  564. goto err;
  565. }
  566. /* verify signature */
  567. if (efi_signature_verify_with_sigdb(regs, var_sig, truststore, NULL)) {
  568. debug("Verified\n");
  569. } else {
  570. if (truststore2 &&
  571. efi_signature_verify_with_sigdb(regs, var_sig,
  572. truststore2, NULL)) {
  573. debug("Verified\n");
  574. } else {
  575. debug("Verifying variable's signature failed\n");
  576. goto err;
  577. }
  578. }
  579. /* finished checking */
  580. *time = rtc_mktime(&tm);
  581. ret = EFI_SUCCESS;
  582. err:
  583. efi_sigstore_free(truststore);
  584. efi_sigstore_free(truststore2);
  585. pkcs7_free_message(var_sig);
  586. free(regs);
  587. return ret;
  588. }
  589. #else
  590. static efi_status_t efi_variable_authenticate(u16 *variable,
  591. const efi_guid_t *vendor,
  592. efi_uintn_t *data_size,
  593. const void **data, u32 given_attr,
  594. u32 *env_attr, u64 *time)
  595. {
  596. return EFI_SUCCESS;
  597. }
  598. #endif /* CONFIG_EFI_SECURE_BOOT */
  599. static
  600. efi_status_t EFIAPI efi_get_variable_common(u16 *variable_name,
  601. const efi_guid_t *vendor,
  602. u32 *attributes,
  603. efi_uintn_t *data_size, void *data,
  604. bool is_non_volatile)
  605. {
  606. char *native_name;
  607. efi_status_t ret;
  608. unsigned long in_size;
  609. const char *val = NULL, *s;
  610. u64 time = 0;
  611. u32 attr;
  612. if (!variable_name || !vendor || !data_size)
  613. return EFI_EXIT(EFI_INVALID_PARAMETER);
  614. ret = efi_to_native(&native_name, variable_name, vendor);
  615. if (ret)
  616. return ret;
  617. EFI_PRINT("get '%s'\n", native_name);
  618. val = env_get(native_name);
  619. free(native_name);
  620. if (!val)
  621. return EFI_NOT_FOUND;
  622. val = parse_attr(val, &attr, &time);
  623. in_size = *data_size;
  624. if ((s = prefix(val, "(blob)"))) {
  625. size_t len = strlen(s);
  626. /* number of hexadecimal digits must be even */
  627. if (len & 1)
  628. return EFI_DEVICE_ERROR;
  629. /* two characters per byte: */
  630. len /= 2;
  631. *data_size = len;
  632. if (in_size < len) {
  633. ret = EFI_BUFFER_TOO_SMALL;
  634. goto out;
  635. }
  636. if (!data) {
  637. debug("Variable with no data shouldn't exist.\n");
  638. return EFI_INVALID_PARAMETER;
  639. }
  640. if (hex2bin(data, s, len))
  641. return EFI_DEVICE_ERROR;
  642. EFI_PRINT("got value: \"%s\"\n", s);
  643. } else if ((s = prefix(val, "(utf8)"))) {
  644. unsigned len = strlen(s) + 1;
  645. *data_size = len;
  646. if (in_size < len) {
  647. ret = EFI_BUFFER_TOO_SMALL;
  648. goto out;
  649. }
  650. if (!data) {
  651. debug("Variable with no data shouldn't exist.\n");
  652. return EFI_INVALID_PARAMETER;
  653. }
  654. memcpy(data, s, len);
  655. ((char *)data)[len] = '\0';
  656. EFI_PRINT("got value: \"%s\"\n", (char *)data);
  657. } else {
  658. EFI_PRINT("invalid value: '%s'\n", val);
  659. return EFI_DEVICE_ERROR;
  660. }
  661. out:
  662. if (attributes)
  663. *attributes = attr & EFI_VARIABLE_MASK;
  664. return ret;
  665. }
  666. static
  667. efi_status_t EFIAPI efi_get_volatile_variable(u16 *variable_name,
  668. const efi_guid_t *vendor,
  669. u32 *attributes,
  670. efi_uintn_t *data_size,
  671. void *data)
  672. {
  673. return efi_get_variable_common(variable_name, vendor, attributes,
  674. data_size, data, false);
  675. }
  676. efi_status_t EFIAPI efi_get_nonvolatile_variable(u16 *variable_name,
  677. const efi_guid_t *vendor,
  678. u32 *attributes,
  679. efi_uintn_t *data_size,
  680. void *data)
  681. {
  682. return efi_get_variable_common(variable_name, vendor, attributes,
  683. data_size, data, true);
  684. }
  685. /**
  686. * efi_efi_get_variable() - retrieve value of a UEFI variable
  687. *
  688. * This function implements the GetVariable runtime service.
  689. *
  690. * See the Unified Extensible Firmware Interface (UEFI) specification for
  691. * details.
  692. *
  693. * @variable_name: name of the variable
  694. * @vendor: vendor GUID
  695. * @attributes: attributes of the variable
  696. * @data_size: size of the buffer to which the variable value is copied
  697. * @data: buffer to which the variable value is copied
  698. * Return: status code
  699. */
  700. efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
  701. const efi_guid_t *vendor, u32 *attributes,
  702. efi_uintn_t *data_size, void *data)
  703. {
  704. efi_status_t ret;
  705. EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes,
  706. data_size, data);
  707. ret = efi_get_volatile_variable(variable_name, vendor, attributes,
  708. data_size, data);
  709. if (ret == EFI_NOT_FOUND)
  710. ret = efi_get_nonvolatile_variable(variable_name, vendor,
  711. attributes, data_size, data);
  712. return EFI_EXIT(ret);
  713. }
  714. static char *efi_variables_list;
  715. static char *efi_cur_variable;
  716. /**
  717. * parse_uboot_variable() - parse a u-boot variable and get uefi-related
  718. * information
  719. * @variable: whole data of u-boot variable (ie. name=value)
  720. * @variable_name_size: size of variable_name buffer in byte
  721. * @variable_name: name of uefi variable in u16, null-terminated
  722. * @vendor: vendor's guid
  723. * @attributes: attributes
  724. *
  725. * A uefi variable is encoded into a u-boot variable as described above.
  726. * This function parses such a u-boot variable and retrieve uefi-related
  727. * information into respective parameters. In return, variable_name_size
  728. * is the size of variable name including NULL.
  729. *
  730. * Return: EFI_SUCCESS if parsing is OK, EFI_NOT_FOUND when
  731. * the entire variable list has been returned,
  732. * otherwise non-zero status code
  733. */
  734. static efi_status_t parse_uboot_variable(char *variable,
  735. efi_uintn_t *variable_name_size,
  736. u16 *variable_name,
  737. const efi_guid_t *vendor,
  738. u32 *attributes)
  739. {
  740. char *guid, *name, *end, c;
  741. size_t name_len;
  742. efi_uintn_t old_variable_name_size;
  743. u64 time;
  744. u16 *p;
  745. guid = strchr(variable, '_');
  746. if (!guid)
  747. return EFI_INVALID_PARAMETER;
  748. guid++;
  749. name = strchr(guid, '_');
  750. if (!name)
  751. return EFI_INVALID_PARAMETER;
  752. name++;
  753. end = strchr(name, '=');
  754. if (!end)
  755. return EFI_INVALID_PARAMETER;
  756. name_len = end - name;
  757. old_variable_name_size = *variable_name_size;
  758. *variable_name_size = sizeof(u16) * (name_len + 1);
  759. if (old_variable_name_size < *variable_name_size)
  760. return EFI_BUFFER_TOO_SMALL;
  761. end++; /* point to value */
  762. /* variable name */
  763. p = variable_name;
  764. utf8_utf16_strncpy(&p, name, name_len);
  765. variable_name[name_len] = 0;
  766. /* guid */
  767. c = *(name - 1);
  768. *(name - 1) = '\0'; /* guid need be null-terminated here */
  769. uuid_str_to_bin(guid, (unsigned char *)vendor, UUID_STR_FORMAT_GUID);
  770. *(name - 1) = c;
  771. /* attributes */
  772. parse_attr(end, attributes, &time);
  773. return EFI_SUCCESS;
  774. }
  775. /**
  776. * efi_get_next_variable_name() - enumerate the current variable names
  777. *
  778. * @variable_name_size: size of variable_name buffer in byte
  779. * @variable_name: name of uefi variable's name in u16
  780. * @vendor: vendor's guid
  781. *
  782. * This function implements the GetNextVariableName service.
  783. *
  784. * See the Unified Extensible Firmware Interface (UEFI) specification for
  785. * details.
  786. *
  787. * Return: status code
  788. */
  789. efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
  790. u16 *variable_name,
  791. efi_guid_t *vendor)
  792. {
  793. char *native_name, *variable;
  794. ssize_t name_len, list_len;
  795. char regex[256];
  796. char * const regexlist[] = {regex};
  797. u32 attributes;
  798. int i;
  799. efi_status_t ret;
  800. EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor);
  801. if (!variable_name_size || !variable_name || !vendor)
  802. return EFI_EXIT(EFI_INVALID_PARAMETER);
  803. if (variable_name[0]) {
  804. /* check null-terminated string */
  805. for (i = 0; i < *variable_name_size; i++)
  806. if (!variable_name[i])
  807. break;
  808. if (i >= *variable_name_size)
  809. return EFI_EXIT(EFI_INVALID_PARAMETER);
  810. /* search for the last-returned variable */
  811. ret = efi_to_native(&native_name, variable_name, vendor);
  812. if (ret)
  813. return EFI_EXIT(ret);
  814. name_len = strlen(native_name);
  815. for (variable = efi_variables_list; variable && *variable;) {
  816. if (!strncmp(variable, native_name, name_len) &&
  817. variable[name_len] == '=')
  818. break;
  819. variable = strchr(variable, '\n');
  820. if (variable)
  821. variable++;
  822. }
  823. free(native_name);
  824. if (!(variable && *variable))
  825. return EFI_EXIT(EFI_INVALID_PARAMETER);
  826. /* next variable */
  827. variable = strchr(variable, '\n');
  828. if (variable)
  829. variable++;
  830. if (!(variable && *variable))
  831. return EFI_EXIT(EFI_NOT_FOUND);
  832. } else {
  833. /*
  834. *new search: free a list used in the previous search
  835. */
  836. free(efi_variables_list);
  837. efi_variables_list = NULL;
  838. efi_cur_variable = NULL;
  839. snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_.*");
  840. list_len = hexport_r(&env_htab, '\n',
  841. H_MATCH_REGEX | H_MATCH_KEY,
  842. &efi_variables_list, 0, 1, regexlist);
  843. if (list_len <= 1)
  844. return EFI_EXIT(EFI_NOT_FOUND);
  845. variable = efi_variables_list;
  846. }
  847. ret = parse_uboot_variable(variable, variable_name_size, variable_name,
  848. vendor, &attributes);
  849. return EFI_EXIT(ret);
  850. }
  851. static
  852. efi_status_t EFIAPI efi_set_variable_common(u16 *variable_name,
  853. const efi_guid_t *vendor,
  854. u32 attributes,
  855. efi_uintn_t data_size,
  856. const void *data,
  857. bool ro_check,
  858. bool is_non_volatile)
  859. {
  860. char *native_name = NULL, *old_data = NULL, *val = NULL, *s;
  861. efi_uintn_t old_size;
  862. bool append, delete;
  863. u64 time = 0;
  864. u32 attr;
  865. efi_status_t ret = EFI_SUCCESS;
  866. debug("%s: set '%s'\n", __func__, native_name);
  867. if (!variable_name || !*variable_name || !vendor ||
  868. ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) &&
  869. !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))) {
  870. ret = EFI_INVALID_PARAMETER;
  871. goto err;
  872. }
  873. ret = efi_to_native(&native_name, variable_name, vendor);
  874. if (ret)
  875. goto err;
  876. /* check if a variable exists */
  877. old_size = 0;
  878. attr = 0;
  879. ret = EFI_CALL(efi_get_variable(variable_name, vendor, &attr,
  880. &old_size, NULL));
  881. if (ret == EFI_BUFFER_TOO_SMALL) {
  882. if ((is_non_volatile && !(attr & EFI_VARIABLE_NON_VOLATILE)) ||
  883. (!is_non_volatile && (attr & EFI_VARIABLE_NON_VOLATILE))) {
  884. ret = EFI_INVALID_PARAMETER;
  885. goto err;
  886. }
  887. }
  888. append = !!(attributes & EFI_VARIABLE_APPEND_WRITE);
  889. attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE;
  890. delete = !append && (!data_size || !attributes);
  891. /* check attributes */
  892. if (old_size) {
  893. if (ro_check && (attr & READ_ONLY)) {
  894. ret = EFI_WRITE_PROTECTED;
  895. goto err;
  896. }
  897. /* attributes won't be changed */
  898. if (!delete &&
  899. ((ro_check && attr != attributes) ||
  900. (!ro_check && ((attr & ~(u32)READ_ONLY)
  901. != (attributes & ~(u32)READ_ONLY))))) {
  902. ret = EFI_INVALID_PARAMETER;
  903. goto err;
  904. }
  905. } else {
  906. if (delete || append) {
  907. /*
  908. * Trying to delete or to update a non-existent
  909. * variable.
  910. */
  911. ret = EFI_NOT_FOUND;
  912. goto err;
  913. }
  914. }
  915. if (((!u16_strcmp(variable_name, L"PK") ||
  916. !u16_strcmp(variable_name, L"KEK")) &&
  917. !guidcmp(vendor, &efi_global_variable_guid)) ||
  918. ((!u16_strcmp(variable_name, L"db") ||
  919. !u16_strcmp(variable_name, L"dbx")) &&
  920. !guidcmp(vendor, &efi_guid_image_security_database))) {
  921. /* authentication is mandatory */
  922. if (!(attributes &
  923. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
  924. debug("%ls: AUTHENTICATED_WRITE_ACCESS required\n",
  925. variable_name);
  926. ret = EFI_INVALID_PARAMETER;
  927. goto err;
  928. }
  929. }
  930. /* authenticate a variable */
  931. if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) {
  932. if (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) {
  933. ret = EFI_INVALID_PARAMETER;
  934. goto err;
  935. }
  936. if (attributes &
  937. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
  938. ret = efi_variable_authenticate(variable_name, vendor,
  939. &data_size, &data,
  940. attributes, &attr,
  941. &time);
  942. if (ret != EFI_SUCCESS)
  943. goto err;
  944. /* last chance to check for delete */
  945. if (!data_size)
  946. delete = true;
  947. }
  948. } else {
  949. if (attributes &
  950. (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
  951. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
  952. debug("Secure boot is not configured\n");
  953. ret = EFI_INVALID_PARAMETER;
  954. goto err;
  955. }
  956. }
  957. /* delete a variable */
  958. if (delete) {
  959. /* !old_size case has been handled before */
  960. val = NULL;
  961. ret = EFI_SUCCESS;
  962. goto out;
  963. }
  964. if (append) {
  965. old_data = malloc(old_size);
  966. if (!old_data) {
  967. return EFI_OUT_OF_RESOURCES;
  968. goto err;
  969. }
  970. ret = EFI_CALL(efi_get_variable(variable_name, vendor,
  971. &attr, &old_size, old_data));
  972. if (ret != EFI_SUCCESS)
  973. goto err;
  974. } else {
  975. old_size = 0;
  976. }
  977. val = malloc(2 * old_size + 2 * data_size
  978. + strlen("{ro,run,boot,nv,time=0123456701234567}(blob)")
  979. + 1);
  980. if (!val) {
  981. ret = EFI_OUT_OF_RESOURCES;
  982. goto err;
  983. }
  984. s = val;
  985. /*
  986. * store attributes
  987. */
  988. attributes &= (READ_ONLY |
  989. EFI_VARIABLE_NON_VOLATILE |
  990. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  991. EFI_VARIABLE_RUNTIME_ACCESS |
  992. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS);
  993. s += sprintf(s, "{");
  994. while (attributes) {
  995. attr = 1 << (ffs(attributes) - 1);
  996. if (attr == READ_ONLY) {
  997. s += sprintf(s, "ro");
  998. } else if (attr == EFI_VARIABLE_NON_VOLATILE) {
  999. s += sprintf(s, "nv");
  1000. } else if (attr == EFI_VARIABLE_BOOTSERVICE_ACCESS) {
  1001. s += sprintf(s, "boot");
  1002. } else if (attr == EFI_VARIABLE_RUNTIME_ACCESS) {
  1003. s += sprintf(s, "run");
  1004. } else if (attr ==
  1005. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
  1006. s += sprintf(s, "time=");
  1007. s = bin2hex(s, (u8 *)&time, sizeof(time));
  1008. }
  1009. attributes &= ~attr;
  1010. if (attributes)
  1011. s += sprintf(s, ",");
  1012. }
  1013. s += sprintf(s, "}");
  1014. s += sprintf(s, "(blob)");
  1015. /* store payload: */
  1016. if (append)
  1017. s = bin2hex(s, old_data, old_size);
  1018. s = bin2hex(s, data, data_size);
  1019. *s = '\0';
  1020. EFI_PRINT("setting: %s=%s\n", native_name, val);
  1021. out:
  1022. if (env_set(native_name, val)) {
  1023. ret = EFI_DEVICE_ERROR;
  1024. } else {
  1025. bool vendor_keys_modified = false;
  1026. if ((u16_strcmp(variable_name, L"PK") == 0 &&
  1027. guidcmp(vendor, &efi_global_variable_guid) == 0)) {
  1028. ret = efi_transfer_secure_state(
  1029. (delete ? EFI_MODE_SETUP :
  1030. EFI_MODE_USER));
  1031. if (ret != EFI_SUCCESS)
  1032. goto err;
  1033. if (efi_secure_mode != EFI_MODE_SETUP)
  1034. vendor_keys_modified = true;
  1035. } else if ((u16_strcmp(variable_name, L"KEK") == 0 &&
  1036. guidcmp(vendor, &efi_global_variable_guid) == 0)) {
  1037. if (efi_secure_mode != EFI_MODE_SETUP)
  1038. vendor_keys_modified = true;
  1039. }
  1040. /* update VendorKeys */
  1041. if (vendor_keys_modified & efi_vendor_keys) {
  1042. efi_vendor_keys = 0;
  1043. ret = efi_set_variable_internal(
  1044. L"VendorKeys",
  1045. &efi_global_variable_guid,
  1046. EFI_VARIABLE_BOOTSERVICE_ACCESS
  1047. | EFI_VARIABLE_RUNTIME_ACCESS
  1048. | READ_ONLY,
  1049. sizeof(efi_vendor_keys),
  1050. &efi_vendor_keys,
  1051. false);
  1052. } else {
  1053. ret = EFI_SUCCESS;
  1054. }
  1055. }
  1056. err:
  1057. free(native_name);
  1058. free(old_data);
  1059. free(val);
  1060. return ret;
  1061. }
  1062. static
  1063. efi_status_t EFIAPI efi_set_volatile_variable(u16 *variable_name,
  1064. const efi_guid_t *vendor,
  1065. u32 attributes,
  1066. efi_uintn_t data_size,
  1067. const void *data,
  1068. bool ro_check)
  1069. {
  1070. return efi_set_variable_common(variable_name, vendor, attributes,
  1071. data_size, data, ro_check, false);
  1072. }
  1073. efi_status_t EFIAPI efi_set_nonvolatile_variable(u16 *variable_name,
  1074. const efi_guid_t *vendor,
  1075. u32 attributes,
  1076. efi_uintn_t data_size,
  1077. const void *data,
  1078. bool ro_check)
  1079. {
  1080. efi_status_t ret;
  1081. ret = efi_set_variable_common(variable_name, vendor, attributes,
  1082. data_size, data, ro_check, true);
  1083. return ret;
  1084. }
  1085. static efi_status_t efi_set_variable_internal(u16 *variable_name,
  1086. const efi_guid_t *vendor,
  1087. u32 attributes,
  1088. efi_uintn_t data_size,
  1089. const void *data,
  1090. bool ro_check)
  1091. {
  1092. efi_status_t ret;
  1093. if (attributes & EFI_VARIABLE_NON_VOLATILE)
  1094. ret = efi_set_nonvolatile_variable(variable_name, vendor,
  1095. attributes,
  1096. data_size, data, ro_check);
  1097. else
  1098. ret = efi_set_volatile_variable(variable_name, vendor,
  1099. attributes, data_size, data,
  1100. ro_check);
  1101. return ret;
  1102. }
  1103. /**
  1104. * efi_set_variable() - set value of a UEFI variable
  1105. *
  1106. * This function implements the SetVariable runtime service.
  1107. *
  1108. * See the Unified Extensible Firmware Interface (UEFI) specification for
  1109. * details.
  1110. *
  1111. * @variable_name: name of the variable
  1112. * @vendor: vendor GUID
  1113. * @attributes: attributes of the variable
  1114. * @data_size: size of the buffer with the variable value
  1115. * @data: buffer with the variable value
  1116. * Return: status code
  1117. */
  1118. efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
  1119. const efi_guid_t *vendor, u32 attributes,
  1120. efi_uintn_t data_size, const void *data)
  1121. {
  1122. EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
  1123. data_size, data);
  1124. /* READ_ONLY bit is not part of API */
  1125. attributes &= ~(u32)READ_ONLY;
  1126. return EFI_EXIT(efi_set_variable_internal(variable_name, vendor,
  1127. attributes, data_size, data,
  1128. true));
  1129. }
  1130. /**
  1131. * efi_query_variable_info() - get information about EFI variables
  1132. *
  1133. * This function implements the QueryVariableInfo() runtime service.
  1134. *
  1135. * See the Unified Extensible Firmware Interface (UEFI) specification for
  1136. * details.
  1137. *
  1138. * @attributes: bitmask to select variables to be
  1139. * queried
  1140. * @maximum_variable_storage_size: maximum size of storage area for the
  1141. * selected variable types
  1142. * @remaining_variable_storage_size: remaining size of storage are for the
  1143. * selected variable types
  1144. * @maximum_variable_size: maximum size of a variable of the
  1145. * selected type
  1146. * Returns: status code
  1147. */
  1148. efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
  1149. u32 attributes,
  1150. u64 *maximum_variable_storage_size,
  1151. u64 *remaining_variable_storage_size,
  1152. u64 *maximum_variable_size)
  1153. {
  1154. return EFI_UNSUPPORTED;
  1155. }
  1156. /**
  1157. * efi_get_variable_runtime() - runtime implementation of GetVariable()
  1158. *
  1159. * @variable_name: name of the variable
  1160. * @vendor: vendor GUID
  1161. * @attributes: attributes of the variable
  1162. * @data_size: size of the buffer to which the variable value is copied
  1163. * @data: buffer to which the variable value is copied
  1164. * Return: status code
  1165. */
  1166. static efi_status_t __efi_runtime EFIAPI
  1167. efi_get_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
  1168. u32 *attributes, efi_uintn_t *data_size, void *data)
  1169. {
  1170. return EFI_UNSUPPORTED;
  1171. }
  1172. /**
  1173. * efi_get_next_variable_name_runtime() - runtime implementation of
  1174. * GetNextVariable()
  1175. *
  1176. * @variable_name_size: size of variable_name buffer in byte
  1177. * @variable_name: name of uefi variable's name in u16
  1178. * @vendor: vendor's guid
  1179. * Return: status code
  1180. */
  1181. static efi_status_t __efi_runtime EFIAPI
  1182. efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size,
  1183. u16 *variable_name, efi_guid_t *vendor)
  1184. {
  1185. return EFI_UNSUPPORTED;
  1186. }
  1187. /**
  1188. * efi_set_variable_runtime() - runtime implementation of SetVariable()
  1189. *
  1190. * @variable_name: name of the variable
  1191. * @vendor: vendor GUID
  1192. * @attributes: attributes of the variable
  1193. * @data_size: size of the buffer with the variable value
  1194. * @data: buffer with the variable value
  1195. * Return: status code
  1196. */
  1197. static efi_status_t __efi_runtime EFIAPI
  1198. efi_set_variable_runtime(u16 *variable_name, const efi_guid_t *vendor,
  1199. u32 attributes, efi_uintn_t data_size,
  1200. const void *data)
  1201. {
  1202. return EFI_UNSUPPORTED;
  1203. }
  1204. /**
  1205. * efi_variables_boot_exit_notify() - notify ExitBootServices() is called
  1206. */
  1207. void efi_variables_boot_exit_notify(void)
  1208. {
  1209. efi_runtime_services.get_variable = efi_get_variable_runtime;
  1210. efi_runtime_services.get_next_variable_name =
  1211. efi_get_next_variable_name_runtime;
  1212. efi_runtime_services.set_variable = efi_set_variable_runtime;
  1213. efi_update_table_header_crc32(&efi_runtime_services.hdr);
  1214. }
  1215. /**
  1216. * efi_init_variables() - initialize variable services
  1217. *
  1218. * Return: status code
  1219. */
  1220. efi_status_t efi_init_variables(void)
  1221. {
  1222. efi_status_t ret;
  1223. ret = efi_init_secure_state();
  1224. return ret;
  1225. }