2
0

var-service-auth.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * SPDX-License-Identifier: GPL-2.0-or-later
  3. *
  4. * uefi vars device - AuthVariableLib
  5. */
  6. #include "qemu/osdep.h"
  7. #include "qemu/error-report.h"
  8. #include "system/dma.h"
  9. #include "hw/uefi/var-service.h"
  10. static const uint16_t name_pk[] = u"PK";
  11. static const uint16_t name_kek[] = u"KEK";
  12. static const uint16_t name_db[] = u"db";
  13. static const uint16_t name_dbx[] = u"dbx";
  14. static const uint16_t name_setup_mode[] = u"SetupMode";
  15. static const uint16_t name_sigs_support[] = u"SignatureSupport";
  16. static const uint16_t name_sb[] = u"SecureBoot";
  17. static const uint16_t name_sb_enable[] = u"SecureBootEnable";
  18. static const uint16_t name_custom_mode[] = u"CustomMode";
  19. static const uint16_t name_vk[] = u"VendorKeys";
  20. static const uint16_t name_vk_nv[] = u"VendorKeysNv";
  21. static const uint32_t sigdb_attrs =
  22. EFI_VARIABLE_NON_VOLATILE |
  23. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  24. EFI_VARIABLE_RUNTIME_ACCESS |
  25. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  26. static void set_secure_boot(uefi_vars_state *uv, uint8_t sb)
  27. {
  28. uefi_vars_set_variable(uv, EfiGlobalVariable,
  29. name_sb, sizeof(name_sb),
  30. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  31. EFI_VARIABLE_RUNTIME_ACCESS,
  32. &sb, sizeof(sb));
  33. }
  34. static void set_secure_boot_enable(uefi_vars_state *uv, uint8_t sbe)
  35. {
  36. uefi_vars_set_variable(uv, EfiSecureBootEnableDisable,
  37. name_sb_enable, sizeof(name_sb_enable),
  38. EFI_VARIABLE_NON_VOLATILE |
  39. EFI_VARIABLE_BOOTSERVICE_ACCESS,
  40. &sbe, sizeof(sbe));
  41. }
  42. static void set_setup_mode(uefi_vars_state *uv, uint8_t sm)
  43. {
  44. uefi_vars_set_variable(uv, EfiGlobalVariable,
  45. name_setup_mode, sizeof(name_setup_mode),
  46. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  47. EFI_VARIABLE_RUNTIME_ACCESS,
  48. &sm, sizeof(sm));
  49. }
  50. static void set_custom_mode(uefi_vars_state *uv, uint8_t cm)
  51. {
  52. uefi_vars_set_variable(uv, EfiCustomModeEnable,
  53. name_custom_mode, sizeof(name_custom_mode),
  54. EFI_VARIABLE_NON_VOLATILE |
  55. EFI_VARIABLE_BOOTSERVICE_ACCESS,
  56. &cm, sizeof(cm));
  57. }
  58. static void set_signature_support(uefi_vars_state *uv)
  59. {
  60. QemuUUID sigs_support[5];
  61. sigs_support[0] = EfiCertSha256Guid;
  62. sigs_support[1] = EfiCertSha384Guid;
  63. sigs_support[2] = EfiCertSha512Guid;
  64. sigs_support[3] = EfiCertRsa2048Guid;
  65. sigs_support[4] = EfiCertX509Guid;
  66. uefi_vars_set_variable(uv, EfiGlobalVariable,
  67. name_sigs_support, sizeof(name_sigs_support),
  68. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  69. EFI_VARIABLE_RUNTIME_ACCESS,
  70. sigs_support, sizeof(sigs_support));
  71. }
  72. static bool setup_mode_is_active(uefi_vars_state *uv)
  73. {
  74. uefi_variable *var;
  75. uint8_t *value;
  76. var = uefi_vars_find_variable(uv, EfiGlobalVariable,
  77. name_setup_mode, sizeof(name_setup_mode));
  78. if (var) {
  79. value = var->data;
  80. if (value[0] == SETUP_MODE) {
  81. return true;
  82. }
  83. }
  84. return false;
  85. }
  86. static bool custom_mode_is_active(uefi_vars_state *uv)
  87. {
  88. uefi_variable *var;
  89. uint8_t *value;
  90. var = uefi_vars_find_variable(uv, EfiCustomModeEnable,
  91. name_custom_mode, sizeof(name_custom_mode));
  92. if (var) {
  93. value = var->data;
  94. if (value[0] == CUSTOM_SECURE_BOOT_MODE) {
  95. return true;
  96. }
  97. }
  98. return false;
  99. }
  100. bool uefi_vars_is_sb_pk(uefi_variable *var)
  101. {
  102. if (qemu_uuid_is_equal(&var->guid, &EfiGlobalVariable) &&
  103. uefi_str_equal(var->name, var->name_size, name_pk, sizeof(name_pk))) {
  104. return true;
  105. }
  106. return false;
  107. }
  108. static bool uefi_vars_is_sb_kek(uefi_variable *var)
  109. {
  110. if (qemu_uuid_is_equal(&var->guid, &EfiGlobalVariable) &&
  111. uefi_str_equal(var->name, var->name_size, name_kek, sizeof(name_kek))) {
  112. return true;
  113. }
  114. return false;
  115. }
  116. static bool uefi_vars_is_sb_db(uefi_variable *var)
  117. {
  118. if (!qemu_uuid_is_equal(&var->guid, &EfiImageSecurityDatabase)) {
  119. return false;
  120. }
  121. if (uefi_str_equal(var->name, var->name_size, name_db, sizeof(name_db))) {
  122. return true;
  123. }
  124. if (uefi_str_equal(var->name, var->name_size, name_dbx, sizeof(name_dbx))) {
  125. return true;
  126. }
  127. return false;
  128. }
  129. bool uefi_vars_is_sb_any(uefi_variable *var)
  130. {
  131. if (uefi_vars_is_sb_pk(var) ||
  132. uefi_vars_is_sb_kek(var) ||
  133. uefi_vars_is_sb_db(var)) {
  134. return true;
  135. }
  136. return false;
  137. }
  138. static uefi_variable *uefi_vars_find_siglist(uefi_vars_state *uv,
  139. uefi_variable *var)
  140. {
  141. if (uefi_vars_is_sb_pk(var)) {
  142. return uefi_vars_find_variable(uv, EfiGlobalVariable,
  143. name_pk, sizeof(name_pk));
  144. }
  145. if (uefi_vars_is_sb_kek(var)) {
  146. return uefi_vars_find_variable(uv, EfiGlobalVariable,
  147. name_pk, sizeof(name_pk));
  148. }
  149. if (uefi_vars_is_sb_db(var)) {
  150. return uefi_vars_find_variable(uv, EfiGlobalVariable,
  151. name_kek, sizeof(name_kek));
  152. }
  153. return NULL;
  154. }
  155. static efi_status uefi_vars_check_auth_2_sb(uefi_vars_state *uv,
  156. uefi_variable *var,
  157. mm_variable_access *va,
  158. void *data,
  159. uint64_t data_offset)
  160. {
  161. variable_auth_2 *auth = data;
  162. uefi_variable *siglist;
  163. if (custom_mode_is_active(uv)) {
  164. /* no authentication in custom mode */
  165. return EFI_SUCCESS;
  166. }
  167. if (setup_mode_is_active(uv) && !uefi_vars_is_sb_pk(var)) {
  168. /* no authentication in setup mode (except PK) */
  169. return EFI_SUCCESS;
  170. }
  171. if (auth->hdr_length == 24) {
  172. /* no signature (auth->cert_data is empty) */
  173. return EFI_SECURITY_VIOLATION;
  174. }
  175. siglist = uefi_vars_find_siglist(uv, var);
  176. if (!siglist && setup_mode_is_active(uv) && uefi_vars_is_sb_pk(var)) {
  177. /* check PK is self-signed */
  178. uefi_variable tmp = {
  179. .guid = EfiGlobalVariable,
  180. .name = (uint16_t *)name_pk,
  181. .name_size = sizeof(name_pk),
  182. .attributes = sigdb_attrs,
  183. .data = data + data_offset,
  184. .data_size = va->data_size - data_offset,
  185. };
  186. return uefi_vars_check_pkcs7_2(&tmp, NULL, NULL, va, data);
  187. }
  188. return uefi_vars_check_pkcs7_2(siglist, NULL, NULL, va, data);
  189. }
  190. efi_status uefi_vars_check_auth_2(uefi_vars_state *uv, uefi_variable *var,
  191. mm_variable_access *va, void *data)
  192. {
  193. variable_auth_2 *auth = data;
  194. uint64_t data_offset;
  195. efi_status status;
  196. if (va->data_size < sizeof(*auth)) {
  197. return EFI_SECURITY_VIOLATION;
  198. }
  199. if (uadd64_overflow(sizeof(efi_time), auth->hdr_length, &data_offset)) {
  200. return EFI_SECURITY_VIOLATION;
  201. }
  202. if (va->data_size < data_offset) {
  203. return EFI_SECURITY_VIOLATION;
  204. }
  205. if (auth->hdr_revision != 0x0200 ||
  206. auth->hdr_cert_type != WIN_CERT_TYPE_EFI_GUID ||
  207. !qemu_uuid_is_equal(&auth->guid_cert_type, &EfiCertTypePkcs7Guid)) {
  208. return EFI_UNSUPPORTED;
  209. }
  210. if (uefi_vars_is_sb_any(var)) {
  211. /* secure boot variables */
  212. status = uefi_vars_check_auth_2_sb(uv, var, va, data, data_offset);
  213. if (status != EFI_SUCCESS) {
  214. return status;
  215. }
  216. } else {
  217. /* other authenticated variables */
  218. status = uefi_vars_check_pkcs7_2(NULL,
  219. &var->digest, &var->digest_size,
  220. va, data);
  221. if (status != EFI_SUCCESS) {
  222. return status;
  223. }
  224. }
  225. /* checks passed, set variable data */
  226. var->time = auth->timestamp;
  227. if (va->data_size - data_offset > 0) {
  228. var->data = g_malloc(va->data_size - data_offset);
  229. memcpy(var->data, data + data_offset, va->data_size - data_offset);
  230. var->data_size = va->data_size - data_offset;
  231. }
  232. return EFI_SUCCESS;
  233. }
  234. efi_status uefi_vars_check_secure_boot(uefi_vars_state *uv, uefi_variable *var)
  235. {
  236. uint8_t *value = var->data;
  237. if (uefi_vars_is_sb_any(var)) {
  238. if (var->attributes != sigdb_attrs) {
  239. return EFI_INVALID_PARAMETER;
  240. }
  241. }
  242. /* reject SecureBootEnable updates if force_secure_boot is set */
  243. if (qemu_uuid_is_equal(&var->guid, &EfiSecureBootEnableDisable) &&
  244. uefi_str_equal(var->name, var->name_size,
  245. name_sb_enable, sizeof(name_sb_enable)) &&
  246. uv->force_secure_boot &&
  247. value[0] != SECURE_BOOT_ENABLE) {
  248. return EFI_WRITE_PROTECTED;
  249. }
  250. /* reject CustomMode updates if disable_custom_mode is set */
  251. if (qemu_uuid_is_equal(&var->guid, &EfiCustomModeEnable) &&
  252. uefi_str_equal(var->name, var->name_size,
  253. name_custom_mode, sizeof(name_custom_mode)) &&
  254. uv->disable_custom_mode) {
  255. return EFI_WRITE_PROTECTED;
  256. }
  257. return EFI_SUCCESS;
  258. }
  259. /* AuthVariableLibInitialize */
  260. void uefi_vars_auth_init(uefi_vars_state *uv)
  261. {
  262. uefi_variable *pk_var, *sbe_var;
  263. uint8_t platform_mode, sb, sbe, vk;
  264. /* SetupMode */
  265. pk_var = uefi_vars_find_variable(uv, EfiGlobalVariable,
  266. name_pk, sizeof(name_pk));
  267. if (!pk_var) {
  268. platform_mode = SETUP_MODE;
  269. } else {
  270. platform_mode = USER_MODE;
  271. }
  272. set_setup_mode(uv, platform_mode);
  273. /* SignatureSupport */
  274. set_signature_support(uv);
  275. /* SecureBootEnable */
  276. sbe = SECURE_BOOT_DISABLE;
  277. sbe_var = uefi_vars_find_variable(uv, EfiSecureBootEnableDisable,
  278. name_sb_enable, sizeof(name_sb_enable));
  279. if (sbe_var) {
  280. if (platform_mode == USER_MODE) {
  281. sbe = ((uint8_t *)sbe_var->data)[0];
  282. }
  283. } else if (platform_mode == USER_MODE) {
  284. sbe = SECURE_BOOT_ENABLE;
  285. set_secure_boot_enable(uv, sbe);
  286. }
  287. if (uv->force_secure_boot && sbe != SECURE_BOOT_ENABLE) {
  288. sbe = SECURE_BOOT_ENABLE;
  289. set_secure_boot_enable(uv, sbe);
  290. }
  291. /* SecureBoot */
  292. if ((sbe == SECURE_BOOT_ENABLE) && (platform_mode == USER_MODE)) {
  293. sb = SECURE_BOOT_MODE_ENABLE;
  294. } else {
  295. sb = SECURE_BOOT_MODE_DISABLE;
  296. }
  297. set_secure_boot(uv, sb);
  298. /* CustomMode */
  299. set_custom_mode(uv, STANDARD_SECURE_BOOT_MODE);
  300. vk = 0;
  301. uefi_vars_set_variable(uv, EfiGlobalVariable,
  302. name_vk_nv, sizeof(name_vk_nv),
  303. EFI_VARIABLE_NON_VOLATILE |
  304. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  305. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
  306. &vk, sizeof(vk));
  307. uefi_vars_set_variable(uv, EfiGlobalVariable,
  308. name_vk, sizeof(name_vk),
  309. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  310. EFI_VARIABLE_RUNTIME_ACCESS,
  311. &vk, sizeof(vk));
  312. /* flush to disk */
  313. uefi_vars_json_save(uv);
  314. }