conftest.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. # SPDX-License-Identifier: GPL-2.0+
  2. # Copyright (c) 2020, Linaro Limited
  3. # Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  4. """Fixture for UEFI capsule test."""
  5. from subprocess import call, check_call, CalledProcessError
  6. import pytest
  7. from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR, EFITOOLS_PATH
  8. @pytest.fixture(scope='session')
  9. def efi_capsule_data(request, u_boot_config):
  10. """Set up a file system and return path to image.
  11. The function sets up a file system to be used in UEFI capsule and
  12. authentication test and returns a path to disk image to be used
  13. for testing.
  14. request -- Pytest request object.
  15. u_boot_config -- U-Boot configuration.
  16. """
  17. mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule'
  18. data_dir = mnt_point + CAPSULE_DATA_DIR
  19. install_dir = mnt_point + CAPSULE_INSTALL_DIR
  20. image_path = u_boot_config.persistent_data_dir + '/test_efi_capsule.img'
  21. try:
  22. # Create a target device
  23. check_call('dd if=/dev/zero of=./spi.bin bs=1MiB count=16', shell=True)
  24. check_call('rm -rf %s' % mnt_point, shell=True)
  25. check_call('mkdir -p %s' % data_dir, shell=True)
  26. check_call('mkdir -p %s' % install_dir, shell=True)
  27. capsule_auth_enabled = u_boot_config.buildconfig.get(
  28. 'config_efi_capsule_authenticate')
  29. if capsule_auth_enabled:
  30. # Create private key (SIGNER.key) and certificate (SIGNER.crt)
  31. check_call('cd %s; '
  32. 'openssl req -x509 -sha256 -newkey rsa:2048 '
  33. '-subj /CN=TEST_SIGNER/ -keyout SIGNER.key '
  34. '-out SIGNER.crt -nodes -days 365'
  35. % data_dir, shell=True)
  36. check_call('cd %s; %scert-to-efi-sig-list SIGNER.crt SIGNER.esl'
  37. % (data_dir, EFITOOLS_PATH), shell=True)
  38. # Update dtb adding capsule certificate
  39. check_call('cd %s; '
  40. 'cp %s/test/py/tests/test_efi_capsule/signature.dts .'
  41. % (data_dir, u_boot_config.source_dir), shell=True)
  42. check_call('cd %s; '
  43. 'dtc -@ -I dts -O dtb -o signature.dtbo signature.dts; '
  44. 'fdtoverlay -i %s/arch/sandbox/dts/test.dtb '
  45. '-o test_sig.dtb signature.dtbo'
  46. % (data_dir, u_boot_config.build_dir), shell=True)
  47. # Create *malicious* private key (SIGNER2.key) and certificate
  48. # (SIGNER2.crt)
  49. check_call('cd %s; '
  50. 'openssl req -x509 -sha256 -newkey rsa:2048 '
  51. '-subj /CN=TEST_SIGNER/ -keyout SIGNER2.key '
  52. '-out SIGNER2.crt -nodes -days 365'
  53. % data_dir, shell=True)
  54. # Update dtb to add the version information
  55. check_call('cd %s; '
  56. 'cp %s/test/py/tests/test_efi_capsule/version.dts .'
  57. % (data_dir, u_boot_config.source_dir), shell=True)
  58. if capsule_auth_enabled:
  59. check_call('cd %s; '
  60. 'dtc -@ -I dts -O dtb -o version.dtbo version.dts; '
  61. 'fdtoverlay -i test_sig.dtb '
  62. '-o test_ver.dtb version.dtbo'
  63. % (data_dir), shell=True)
  64. else:
  65. check_call('cd %s; '
  66. 'dtc -@ -I dts -O dtb -o version.dtbo version.dts; '
  67. 'fdtoverlay -i %s/arch/sandbox/dts/test.dtb '
  68. '-o test_ver.dtb version.dtbo'
  69. % (data_dir, u_boot_config.build_dir), shell=True)
  70. # Create capsule files
  71. # two regions: one for u-boot.bin and the other for u-boot.env
  72. check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir,
  73. shell=True)
  74. check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' %
  75. (u_boot_config.source_dir, data_dir),
  76. shell=True)
  77. check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' %
  78. (data_dir, u_boot_config.build_dir),
  79. shell=True)
  80. check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test01' %
  81. (data_dir, u_boot_config.build_dir),
  82. shell=True)
  83. check_call('cd %s; %s/tools/mkeficapsule --index 2 --guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test02' %
  84. (data_dir, u_boot_config.build_dir),
  85. shell=True)
  86. check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 u-boot.bin.new Test03' %
  87. (data_dir, u_boot_config.build_dir),
  88. shell=True)
  89. check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test04' %
  90. (data_dir, u_boot_config.build_dir),
  91. shell=True)
  92. check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 uboot_bin_env.itb Test05' %
  93. (data_dir, u_boot_config.build_dir),
  94. shell=True)
  95. check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 '
  96. '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test101' %
  97. (data_dir, u_boot_config.build_dir),
  98. shell=True)
  99. check_call('cd %s; %s/tools/mkeficapsule --index 2 --fw-version 10 '
  100. '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test102' %
  101. (data_dir, u_boot_config.build_dir),
  102. shell=True)
  103. check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 '
  104. '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test103' %
  105. (data_dir, u_boot_config.build_dir),
  106. shell=True)
  107. check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 '
  108. '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test104' %
  109. (data_dir, u_boot_config.build_dir),
  110. shell=True)
  111. check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 '
  112. '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test105' %
  113. (data_dir, u_boot_config.build_dir),
  114. shell=True)
  115. if capsule_auth_enabled:
  116. # raw firmware signed with proper key
  117. check_call('cd %s; '
  118. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  119. '--private-key SIGNER.key --certificate SIGNER.crt '
  120. '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
  121. 'u-boot.bin.new Test11'
  122. % (data_dir, u_boot_config.build_dir),
  123. shell=True)
  124. # raw firmware signed with *mal* key
  125. check_call('cd %s; '
  126. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  127. '--private-key SIGNER2.key '
  128. '--certificate SIGNER2.crt '
  129. '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
  130. 'u-boot.bin.new Test12'
  131. % (data_dir, u_boot_config.build_dir),
  132. shell=True)
  133. # FIT firmware signed with proper key
  134. check_call('cd %s; '
  135. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  136. '--private-key SIGNER.key --certificate SIGNER.crt '
  137. '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
  138. 'uboot_bin_env.itb Test13'
  139. % (data_dir, u_boot_config.build_dir),
  140. shell=True)
  141. # FIT firmware signed with *mal* key
  142. check_call('cd %s; '
  143. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  144. '--private-key SIGNER2.key '
  145. '--certificate SIGNER2.crt '
  146. '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
  147. 'uboot_bin_env.itb Test14'
  148. % (data_dir, u_boot_config.build_dir),
  149. shell=True)
  150. # raw firmware signed with proper key with version information
  151. check_call('cd %s; '
  152. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  153. '--fw-version 5 '
  154. '--private-key SIGNER.key --certificate SIGNER.crt '
  155. '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
  156. 'u-boot.bin.new Test111'
  157. % (data_dir, u_boot_config.build_dir),
  158. shell=True)
  159. # raw firmware signed with proper key with version information
  160. check_call('cd %s; '
  161. '%s/tools/mkeficapsule --index 2 --monotonic-count 1 '
  162. '--fw-version 10 '
  163. '--private-key SIGNER.key --certificate SIGNER.crt '
  164. '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 '
  165. 'u-boot.env.new Test112'
  166. % (data_dir, u_boot_config.build_dir),
  167. shell=True)
  168. # raw firmware signed with proper key with lower version information
  169. check_call('cd %s; '
  170. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  171. '--fw-version 2 '
  172. '--private-key SIGNER.key --certificate SIGNER.crt '
  173. '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 '
  174. 'u-boot.bin.new Test113'
  175. % (data_dir, u_boot_config.build_dir),
  176. shell=True)
  177. # FIT firmware signed with proper key with version information
  178. check_call('cd %s; '
  179. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  180. '--fw-version 5 '
  181. '--private-key SIGNER.key --certificate SIGNER.crt '
  182. '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
  183. 'uboot_bin_env.itb Test114'
  184. % (data_dir, u_boot_config.build_dir),
  185. shell=True)
  186. # FIT firmware signed with proper key with lower version information
  187. check_call('cd %s; '
  188. '%s/tools/mkeficapsule --index 1 --monotonic-count 1 '
  189. '--fw-version 2 '
  190. '--private-key SIGNER.key --certificate SIGNER.crt '
  191. '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 '
  192. 'uboot_bin_env.itb Test115'
  193. % (data_dir, u_boot_config.build_dir),
  194. shell=True)
  195. # Create a disk image with EFI system partition
  196. check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' %
  197. (mnt_point, image_path), shell=True)
  198. check_call('sgdisk %s -A 1:set:0 -t 1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B' %
  199. image_path, shell=True)
  200. except CalledProcessError as exception:
  201. pytest.skip('Setup failed: %s' % exception.cmd)
  202. return
  203. else:
  204. yield image_path
  205. finally:
  206. call('rm -rf %s' % mnt_point, shell=True)
  207. call('rm -f %s' % image_path, shell=True)
  208. call('rm -f ./spi.bin', shell=True)