test_capsule_firmware_signed.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. # SPDX-License-Identifier: GPL-2.0+
  2. # Copyright (c) 2021, Linaro Limited
  3. # Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  4. #
  5. # U-Boot UEFI: Firmware Update (Signed capsule) Test
  6. """
  7. This test verifies capsule-on-disk firmware update
  8. with signed capsule files
  9. """
  10. import pytest
  11. from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR
  12. @pytest.mark.boardspec('sandbox')
  13. @pytest.mark.buildconfigspec('efi_capsule_firmware_raw')
  14. @pytest.mark.buildconfigspec('efi_capsule_authenticate')
  15. @pytest.mark.buildconfigspec('dfu')
  16. @pytest.mark.buildconfigspec('dfu_sf')
  17. @pytest.mark.buildconfigspec('cmd_efidebug')
  18. @pytest.mark.buildconfigspec('cmd_fat')
  19. @pytest.mark.buildconfigspec('cmd_memory')
  20. @pytest.mark.buildconfigspec('cmd_nvedit_efi')
  21. @pytest.mark.buildconfigspec('cmd_sf')
  22. @pytest.mark.slow
  23. class TestEfiCapsuleFirmwareSigned(object):
  24. def test_efi_capsule_auth1(
  25. self, u_boot_config, u_boot_console, efi_capsule_data):
  26. """
  27. Test Case 1 - Update U-Boot on SPI Flash, raw image format
  28. 0x100000-0x150000: U-Boot binary (but dummy)
  29. If the capsule is properly signed, the authentication
  30. should pass and the firmware be updated.
  31. """
  32. disk_img = efi_capsule_data
  33. with u_boot_console.log.section('Test Case 1-a, before reboot'):
  34. output = u_boot_console.run_command_list([
  35. 'host bind 0 %s' % disk_img,
  36. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi',
  37. 'efidebug boot order 1',
  38. 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
  39. 'env set dfu_alt_info '
  40. '"sf 0:0=u-boot-bin raw 0x100000 '
  41. '0x50000;u-boot-env raw 0x150000 0x200000"',
  42. 'env save'])
  43. # initialize content
  44. output = u_boot_console.run_command_list([
  45. 'sf probe 0:0',
  46. 'fatload host 0:1 4000000 %s/u-boot.bin.old'
  47. % CAPSULE_DATA_DIR,
  48. 'sf write 4000000 100000 10',
  49. 'sf read 5000000 100000 10',
  50. 'md.b 5000000 10'])
  51. assert 'Old' in ''.join(output)
  52. # place a capsule file
  53. output = u_boot_console.run_command_list([
  54. 'fatload host 0:1 4000000 %s/Test11' % CAPSULE_DATA_DIR,
  55. 'fatwrite host 0:1 4000000 %s/Test11 $filesize'
  56. % CAPSULE_INSTALL_DIR,
  57. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  58. assert 'Test11' in ''.join(output)
  59. # reboot
  60. mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
  61. u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \
  62. + '/test_sig.dtb'
  63. u_boot_console.restart_uboot()
  64. capsule_early = u_boot_config.buildconfig.get(
  65. 'config_efi_capsule_on_disk_early')
  66. with u_boot_console.log.section('Test Case 1-b, after reboot'):
  67. if not capsule_early:
  68. # make sure that dfu_alt_info exists even persistent variables
  69. # are not available.
  70. output = u_boot_console.run_command_list([
  71. 'env set dfu_alt_info '
  72. '"sf 0:0=u-boot-bin raw 0x100000 '
  73. '0x50000;u-boot-env raw 0x150000 0x200000"',
  74. 'host bind 0 %s' % disk_img,
  75. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  76. assert 'Test11' in ''.join(output)
  77. # need to run uefi command to initiate capsule handling
  78. output = u_boot_console.run_command(
  79. 'env print -e Capsule0000')
  80. output = u_boot_console.run_command_list([
  81. 'host bind 0 %s' % disk_img,
  82. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  83. assert 'Test11' not in ''.join(output)
  84. output = u_boot_console.run_command_list([
  85. 'sf probe 0:0',
  86. 'sf read 4000000 100000 10',
  87. 'md.b 4000000 10'])
  88. assert 'u-boot:New' in ''.join(output)
  89. def test_efi_capsule_auth2(
  90. self, u_boot_config, u_boot_console, efi_capsule_data):
  91. """
  92. Test Case 2 - Update U-Boot on SPI Flash, raw image format
  93. 0x100000-0x150000: U-Boot binary (but dummy)
  94. If the capsule is signed but with an invalid key,
  95. the authentication should fail and the firmware
  96. not be updated.
  97. """
  98. disk_img = efi_capsule_data
  99. with u_boot_console.log.section('Test Case 2-a, before reboot'):
  100. output = u_boot_console.run_command_list([
  101. 'host bind 0 %s' % disk_img,
  102. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi',
  103. 'efidebug boot order 1',
  104. 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
  105. 'env set dfu_alt_info '
  106. '"sf 0:0=u-boot-bin raw 0x100000 '
  107. '0x50000;u-boot-env raw 0x150000 0x200000"',
  108. 'env save'])
  109. # initialize content
  110. output = u_boot_console.run_command_list([
  111. 'sf probe 0:0',
  112. 'fatload host 0:1 4000000 %s/u-boot.bin.old'
  113. % CAPSULE_DATA_DIR,
  114. 'sf write 4000000 100000 10',
  115. 'sf read 5000000 100000 10',
  116. 'md.b 5000000 10'])
  117. assert 'Old' in ''.join(output)
  118. # place a capsule file
  119. output = u_boot_console.run_command_list([
  120. 'fatload host 0:1 4000000 %s/Test12' % CAPSULE_DATA_DIR,
  121. 'fatwrite host 0:1 4000000 %s/Test12 $filesize'
  122. % CAPSULE_INSTALL_DIR,
  123. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  124. assert 'Test12' in ''.join(output)
  125. # reboot
  126. mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
  127. u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \
  128. + '/test_sig.dtb'
  129. u_boot_console.restart_uboot()
  130. capsule_early = u_boot_config.buildconfig.get(
  131. 'config_efi_capsule_on_disk_early')
  132. with u_boot_console.log.section('Test Case 2-b, after reboot'):
  133. if not capsule_early:
  134. # make sure that dfu_alt_info exists even persistent variables
  135. # are not available.
  136. output = u_boot_console.run_command_list([
  137. 'env set dfu_alt_info '
  138. '"sf 0:0=u-boot-bin raw 0x100000 '
  139. '0x50000;u-boot-env raw 0x150000 0x200000"',
  140. 'host bind 0 %s' % disk_img,
  141. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  142. assert 'Test12' in ''.join(output)
  143. # need to run uefi command to initiate capsule handling
  144. output = u_boot_console.run_command(
  145. 'env print -e Capsule0000')
  146. # deleted any way
  147. output = u_boot_console.run_command_list([
  148. 'host bind 0 %s' % disk_img,
  149. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  150. assert 'Test12' not in ''.join(output)
  151. # TODO: check CapsuleStatus in CapsuleXXXX
  152. output = u_boot_console.run_command_list([
  153. 'sf probe 0:0',
  154. 'sf read 4000000 100000 10',
  155. 'md.b 4000000 10'])
  156. assert 'u-boot:Old' in ''.join(output)
  157. def test_efi_capsule_auth3(
  158. self, u_boot_config, u_boot_console, efi_capsule_data):
  159. """
  160. Test Case 3 - Update U-Boot on SPI Flash, raw image format
  161. 0x100000-0x150000: U-Boot binary (but dummy)
  162. If the capsule is not signed, the authentication
  163. should fail and the firmware not be updated.
  164. """
  165. disk_img = efi_capsule_data
  166. with u_boot_console.log.section('Test Case 3-a, before reboot'):
  167. output = u_boot_console.run_command_list([
  168. 'host bind 0 %s' % disk_img,
  169. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi',
  170. 'efidebug boot order 1',
  171. 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
  172. 'env set dfu_alt_info '
  173. '"sf 0:0=u-boot-bin raw 0x100000 '
  174. '0x50000;u-boot-env raw 0x150000 0x200000"',
  175. 'env save'])
  176. # initialize content
  177. output = u_boot_console.run_command_list([
  178. 'sf probe 0:0',
  179. 'fatload host 0:1 4000000 %s/u-boot.bin.old'
  180. % CAPSULE_DATA_DIR,
  181. 'sf write 4000000 100000 10',
  182. 'sf read 5000000 100000 10',
  183. 'md.b 5000000 10'])
  184. assert 'Old' in ''.join(output)
  185. # place a capsule file
  186. output = u_boot_console.run_command_list([
  187. 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR,
  188. 'fatwrite host 0:1 4000000 %s/Test02 $filesize'
  189. % CAPSULE_INSTALL_DIR,
  190. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  191. assert 'Test02' in ''.join(output)
  192. # reboot
  193. mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
  194. u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \
  195. + '/test_sig.dtb'
  196. u_boot_console.restart_uboot()
  197. capsule_early = u_boot_config.buildconfig.get(
  198. 'config_efi_capsule_on_disk_early')
  199. with u_boot_console.log.section('Test Case 3-b, after reboot'):
  200. if not capsule_early:
  201. # make sure that dfu_alt_info exists even persistent variables
  202. # are not available.
  203. output = u_boot_console.run_command_list([
  204. 'env set dfu_alt_info '
  205. '"sf 0:0=u-boot-bin raw 0x100000 '
  206. '0x50000;u-boot-env raw 0x150000 0x200000"',
  207. 'host bind 0 %s' % disk_img,
  208. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  209. assert 'Test02' in ''.join(output)
  210. # need to run uefi command to initiate capsule handling
  211. output = u_boot_console.run_command(
  212. 'env print -e Capsule0000')
  213. # deleted any way
  214. output = u_boot_console.run_command_list([
  215. 'host bind 0 %s' % disk_img,
  216. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  217. assert 'Test02' not in ''.join(output)
  218. # TODO: check CapsuleStatus in CapsuleXXXX
  219. output = u_boot_console.run_command_list([
  220. 'sf probe 0:0',
  221. 'sf read 4000000 100000 10',
  222. 'md.b 4000000 10'])
  223. assert 'u-boot:Old' in ''.join(output)