pytest_flash_encryption.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. # SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Apache-2.0
  3. from __future__ import print_function
  4. import binascii
  5. import os
  6. import sys
  7. from collections import namedtuple
  8. from io import BytesIO
  9. import pytest
  10. from pytest_embedded import Dut
  11. try:
  12. import espsecure
  13. except ImportError:
  14. idf_path = os.getenv('IDF_PATH')
  15. if not idf_path or not os.path.exists(idf_path):
  16. raise
  17. sys.path.insert(0, os.path.join(idf_path, 'components', 'esptool_py', 'esptool'))
  18. import espsecure
  19. # To prepare a test runner for this example:
  20. # 1. Generate zero flash encryption key:
  21. # dd if=/dev/zero of=key.bin bs=1 count=32
  22. # 2.Burn Efuses:
  23. # espefuse.py --do-not-confirm -p $ESPPORT burn_efuse FLASH_CRYPT_CONFIG 0xf
  24. # espefuse.py --do-not-confirm -p $ESPPORT burn_efuse FLASH_CRYPT_CNT 0x1
  25. # espefuse.py --do-not-confirm -p $ESPPORT burn_key flash_encryption key.bin
  26. @pytest.mark.esp32
  27. @pytest.mark.esp32c3
  28. @pytest.mark.flash_encryption
  29. def test_examples_security_flash_encryption(dut: Dut) -> None:
  30. # calculate the expected ciphertext
  31. flash_addr = dut.app.partition_table['storage']['offset']
  32. plain_hex_str = '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f'
  33. plain_data = binascii.unhexlify(plain_hex_str.replace(' ', ''))
  34. # espsecure uses the cryptography package for encrypting
  35. # with aes-xts, but does not allow for a symmetric key
  36. # so the key for later chips are not all zeros
  37. if dut.target == 'esp32':
  38. key_bytes = b'\x00' * 32
  39. aes_xts = False
  40. else:
  41. key_bytes = b'\xff' + b'\x00' * 31
  42. aes_xts = True
  43. # Emulate espsecure encrypt_flash_data command
  44. EncryptFlashDataArgs = namedtuple('EncryptFlashDataArgs', ['output', 'plaintext_file', 'address', 'keyfile', 'flash_crypt_conf', 'aes_xts'])
  45. args = EncryptFlashDataArgs(BytesIO(), BytesIO(plain_data), flash_addr, BytesIO(key_bytes), 0xF, aes_xts)
  46. espsecure.encrypt_flash_data(args)
  47. expected_ciphertext = args.output.getvalue()
  48. hex_ciphertext = binascii.hexlify(expected_ciphertext).decode('ascii')
  49. expected_str = (' '.join(hex_ciphertext[i:i + 2] for i in range(0, 16, 2)) + ' ' +
  50. ' '.join(hex_ciphertext[i:i + 2] for i in range(16, 32, 2)))
  51. lines = [
  52. 'FLASH_CRYPT_CNT eFuse value is 1',
  53. 'Flash encryption feature is enabled in DEVELOPMENT mode',
  54. 'with esp_partition_write',
  55. plain_hex_str,
  56. 'with esp_partition_read',
  57. plain_hex_str,
  58. 'with spi_flash_read',
  59. expected_str,
  60. # The status of NVS encryption for the "nvs" partition
  61. 'NVS partition "nvs" is encrypted.'
  62. ]
  63. for line in lines:
  64. dut.expect(line, timeout=2)
  65. if __name__ == '__main__':
  66. test_examples_security_flash_encryption()