pytest_flash_encryption.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. from collections import namedtuple
  6. from io import BytesIO
  7. import espsecure
  8. import pytest
  9. from pytest_embedded import Dut
  10. # To prepare a test runner for this example:
  11. # 1. Generate zero flash encryption key:
  12. # dd if=/dev/zero of=key.bin bs=1 count=32
  13. # 2.Burn Efuses:
  14. # espefuse.py --do-not-confirm -p $ESPPORT burn_efuse FLASH_CRYPT_CONFIG 0xf
  15. # espefuse.py --do-not-confirm -p $ESPPORT burn_efuse FLASH_CRYPT_CNT 0x1
  16. # espefuse.py --do-not-confirm -p $ESPPORT burn_key flash_encryption key.bin
  17. @pytest.mark.esp32
  18. @pytest.mark.esp32c3
  19. @pytest.mark.flash_encryption
  20. def test_examples_security_flash_encryption(dut: Dut) -> None:
  21. # Erase the nvs_key partition
  22. dut.serial.erase_partition('nvs_key')
  23. # calculate the expected ciphertext
  24. flash_addr = dut.app.partition_table['storage']['offset']
  25. plain_hex_str = '00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f'
  26. plain_data = binascii.unhexlify(plain_hex_str.replace(' ', ''))
  27. # espsecure uses the cryptography package for encrypting
  28. # with aes-xts, but does not allow for a symmetric key
  29. # so the key for later chips are not all zeros
  30. if dut.target == 'esp32':
  31. key_bytes = b'\x00' * 32
  32. aes_xts = False
  33. else:
  34. key_bytes = b'\xff' + b'\x00' * 31
  35. aes_xts = True
  36. # Emulate espsecure encrypt_flash_data command
  37. EncryptFlashDataArgs = namedtuple('EncryptFlashDataArgs', ['output', 'plaintext_file', 'address', 'keyfile', 'flash_crypt_conf', 'aes_xts'])
  38. args = EncryptFlashDataArgs(BytesIO(), BytesIO(plain_data), flash_addr, BytesIO(key_bytes), 0xF, aes_xts)
  39. espsecure.encrypt_flash_data(args)
  40. expected_ciphertext = args.output.getvalue()
  41. hex_ciphertext = binascii.hexlify(expected_ciphertext).decode('ascii')
  42. expected_str = (' '.join(hex_ciphertext[i:i + 2] for i in range(0, 16, 2)) + ' ' +
  43. ' '.join(hex_ciphertext[i:i + 2] for i in range(16, 32, 2)))
  44. lines = [
  45. 'FLASH_CRYPT_CNT eFuse value is 1',
  46. 'Flash encryption feature is enabled in DEVELOPMENT mode',
  47. 'with esp_partition_write',
  48. plain_hex_str,
  49. 'with esp_partition_read',
  50. plain_hex_str,
  51. 'with esp_flash_read',
  52. expected_str,
  53. # The status of NVS encryption for the "nvs" partition
  54. 'NVS partition "nvs" is encrypted.',
  55. # The status of NVS encryption for the "custom_nvs" partition
  56. 'NVS partition "custom_nvs" is encrypted.'
  57. ]
  58. for line in lines:
  59. dut.expect(line, timeout=20)