test_flash_encryption.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #include <stdio.h>
  2. #include <freertos/FreeRTOS.h>
  3. #include <freertos/task.h>
  4. #include <freertos/semphr.h>
  5. #include <unity.h>
  6. #include <test_utils.h>
  7. #include <esp_spi_flash.h>
  8. #include <esp_attr.h>
  9. #include <esp_flash_encrypt.h>
  10. #include <string.h>
  11. #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
  12. static void test_encrypted_write(size_t offset, const uint8_t *data, size_t length);
  13. static void test_encrypted_write_new_impl(size_t offset, const uint8_t *data, size_t length);
  14. static void verify_erased_flash(size_t offset, size_t length);
  15. static size_t start;
  16. static void setup_tests(void)
  17. {
  18. if (start == 0) {
  19. const esp_partition_t *part = get_test_data_partition();
  20. start = part->address;
  21. printf("Test data partition @ 0x%x\n", start);
  22. }
  23. }
  24. TEST_CASE("test 16 byte encrypted writes", "[flash_encryption][test_env=UT_T1_FlashEncryption]")
  25. {
  26. setup_tests();
  27. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  28. spi_flash_erase_sector(start / SPI_FLASH_SEC_SIZE));
  29. uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47
  30. for(int i = 0; i < sizeof(fortyeight_bytes); i++) {
  31. fortyeight_bytes[i] = i;
  32. }
  33. /* Verify unaligned start or length fails */
  34. TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG,
  35. spi_flash_write_encrypted(start+1, fortyeight_bytes, 32));
  36. TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE,
  37. spi_flash_write_encrypted(start, fortyeight_bytes, 15));
  38. /* ensure nothing happened to the flash yet */
  39. verify_erased_flash(start, 0x20);
  40. /* Write 32 byte block, this is the "normal" encrypted write */
  41. test_encrypted_write(start, fortyeight_bytes, 0x20);
  42. verify_erased_flash(start + 0x20, 0x20);
  43. /* Slip in an unaligned spi_flash_read_encrypted() test */
  44. uint8_t buf[0x10];
  45. spi_flash_read_encrypted(start+0x10, buf, 0x10);
  46. TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16);
  47. /* Write 16 bytes unaligned */
  48. test_encrypted_write(start + 0x30, fortyeight_bytes, 0x10);
  49. /* the 16 byte regions before and after the 16 bytes we just wrote should still be 0xFF */
  50. verify_erased_flash(start + 0x20, 0x10);
  51. verify_erased_flash(start + 0x40, 0x10);
  52. /* Write 48 bytes starting at a 32-byte aligned offset */
  53. test_encrypted_write(start + 0x40, fortyeight_bytes, 0x30);
  54. /* 16 bytes after this write should still be 0xFF -unencrypted- */
  55. verify_erased_flash(start + 0x70, 0x10);
  56. /* Write 48 bytes starting at a 16-byte aligned offset */
  57. test_encrypted_write(start + 0x90, fortyeight_bytes, 0x30);
  58. /* 16 bytes after this write should still be 0xFF -unencrypted- */
  59. verify_erased_flash(start + 0x120, 0x10);
  60. }
  61. static void test_encrypted_write(size_t offset, const uint8_t *data, size_t length)
  62. {
  63. uint8_t readback[length];
  64. printf("encrypt %d bytes at 0x%x\n", length, offset);
  65. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  66. spi_flash_write_encrypted(offset, data, length));
  67. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  68. spi_flash_read_encrypted(offset, readback, length));
  69. TEST_ASSERT_EQUAL_HEX8_ARRAY(data, readback, length);
  70. }
  71. TEST_CASE("test 16 byte encrypted writes (esp_flash)", "[flash_encryption][esp_flash_enc][test_env=UT_T1_FlashEncryption]")
  72. {
  73. setup_tests();
  74. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  75. spi_flash_erase_sector(start / SPI_FLASH_SEC_SIZE));
  76. uint8_t fortyeight_bytes[0x30]; // 0, 1, 2, 3, 4... 47
  77. for(int i = 0; i < sizeof(fortyeight_bytes); i++) {
  78. fortyeight_bytes[i] = i;
  79. }
  80. /* Verify unaligned start or length fails */
  81. TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG,
  82. esp_flash_write_encrypted(NULL, start+1, fortyeight_bytes, 32));
  83. TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_SIZE,
  84. esp_flash_write_encrypted(NULL, start, fortyeight_bytes, 15));
  85. /* ensure nothing happened to the flash yet */
  86. verify_erased_flash(start, 0x20);
  87. /* Write 32 byte block, this is the "normal" encrypted write */
  88. test_encrypted_write_new_impl(start, fortyeight_bytes, 0x20);
  89. verify_erased_flash(start + 0x20, 0x20);
  90. /* Slip in an unaligned esp_flash_read_encrypted() test */
  91. uint8_t buf[0x10];
  92. esp_flash_read_encrypted(NULL, start+0x10, buf, 0x10);
  93. TEST_ASSERT_EQUAL_HEX8_ARRAY(fortyeight_bytes+0x10, buf, 16);
  94. /* Write 16 bytes unaligned */
  95. test_encrypted_write_new_impl(start + 0x30, fortyeight_bytes, 0x10);
  96. /* the 16 byte regions before and after the 16 bytes we just wrote should still be 0xFF */
  97. verify_erased_flash(start + 0x20, 0x10);
  98. verify_erased_flash(start + 0x40, 0x10);
  99. /* Write 48 bytes starting at a 32-byte aligned offset */
  100. test_encrypted_write_new_impl(start + 0x40, fortyeight_bytes, 0x30);
  101. /* 16 bytes after this write should still be 0xFF -unencrypted- */
  102. verify_erased_flash(start + 0x70, 0x10);
  103. /* Write 48 bytes starting at a 16-byte aligned offset */
  104. test_encrypted_write_new_impl(start + 0x90, fortyeight_bytes, 0x30);
  105. /* 16 bytes after this write should still be 0xFF -unencrypted- */
  106. verify_erased_flash(start + 0x120, 0x10);
  107. }
  108. static void test_encrypted_write_new_impl(size_t offset, const uint8_t *data, size_t length)
  109. {
  110. uint8_t readback[length];
  111. printf("encrypt %d bytes at 0x%x\n", length, offset);
  112. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  113. esp_flash_write_encrypted(NULL, offset, data, length));
  114. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  115. esp_flash_read_encrypted(NULL, offset, readback, length));
  116. TEST_ASSERT_EQUAL_HEX8_ARRAY(data, readback, length);
  117. }
  118. static void verify_erased_flash(size_t offset, size_t length)
  119. {
  120. uint8_t readback[length];
  121. printf("verify erased 0x%x - 0x%x\n", offset, offset + length);
  122. TEST_ASSERT_EQUAL_HEX(ESP_OK,
  123. spi_flash_read(offset, readback, length));
  124. for (int i = 0; i < length; i++) {
  125. char message[32];
  126. sprintf(message, "unerased flash @ 0x%08x", offset + i);
  127. TEST_ASSERT_EQUAL_HEX_MESSAGE(0xFF, readback[i], message);
  128. }
  129. }
  130. TEST_CASE("test read & write random encrypted data", "[flash_encryption][test_env=UT_T1_FlashEncryption]")
  131. {
  132. const int MAX_LEN = 192;
  133. //buffer to hold the read data
  134. WORD_ALIGNED_ATTR uint8_t buffer_to_write[MAX_LEN+4];
  135. //test with unaligned buffer
  136. uint8_t* data_buf = &buffer_to_write[3];
  137. setup_tests();
  138. esp_err_t err = spi_flash_erase_sector(start / SPI_FLASH_SEC_SIZE);
  139. TEST_ESP_OK(err);
  140. //initialize the buffer to compare
  141. uint8_t *cmp_buf = heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
  142. assert(((intptr_t)cmp_buf % 4) == 0);
  143. err = spi_flash_read_encrypted(start, cmp_buf, SPI_FLASH_SEC_SIZE);
  144. TEST_ESP_OK(err);
  145. srand(789);
  146. uint32_t offset = 0;
  147. do {
  148. //the encrypted write only works at 16-byte boundary
  149. int skip = (rand() % 4) * 16;
  150. int len = ((rand() % (MAX_LEN/16)) + 1) * 16;
  151. for (int i = 0; i < MAX_LEN; i++) {
  152. data_buf[i] = rand();
  153. }
  154. offset += skip;
  155. if (offset + len > SPI_FLASH_SEC_SIZE) {
  156. if (offset > SPI_FLASH_SEC_SIZE) {
  157. break;
  158. }
  159. len = SPI_FLASH_SEC_SIZE - offset;
  160. }
  161. printf("write %d bytes to 0x%08x...\n", len, start + offset);
  162. err = spi_flash_write_encrypted(start + offset, data_buf, len);
  163. TEST_ESP_OK(err);
  164. memcpy(cmp_buf + offset, data_buf, len);
  165. offset += len;
  166. } while (offset < SPI_FLASH_SEC_SIZE);
  167. offset = 0;
  168. do {
  169. int len = ((rand() % (MAX_LEN/16)) + 1) * 16;
  170. if (offset + len > SPI_FLASH_SEC_SIZE) {
  171. len = SPI_FLASH_SEC_SIZE - offset;
  172. }
  173. err = spi_flash_read_encrypted(start + offset, data_buf, len);
  174. TEST_ESP_OK(err);
  175. printf("compare %d bytes at 0x%08x...\n", len, start + offset);
  176. TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_buf + offset, data_buf, len);
  177. offset += len;
  178. } while (offset < SPI_FLASH_SEC_SIZE);
  179. free(cmp_buf);
  180. }
  181. #endif // CONFIG_SECURE_FLASH_ENC_ENABLED