nvs_encrypted_partition.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <cstring>
  7. #include "nvs_encrypted_partition.hpp"
  8. #include "nvs_types.hpp"
  9. namespace nvs {
  10. NVSEncryptedPartition::NVSEncryptedPartition(const esp_partition_t *partition)
  11. : NVSPartition(partition) { }
  12. esp_err_t NVSEncryptedPartition::init(nvs_sec_cfg_t* cfg)
  13. {
  14. uint8_t* eky = reinterpret_cast<uint8_t*>(cfg);
  15. mbedtls_aes_xts_init(&mEctxt);
  16. mbedtls_aes_xts_init(&mDctxt);
  17. if (mbedtls_aes_xts_setkey_enc(&mEctxt, eky, 2 * NVS_KEY_SIZE * 8) != 0) {
  18. return ESP_ERR_NVS_XTS_CFG_FAILED;
  19. }
  20. if (mbedtls_aes_xts_setkey_dec(&mDctxt, eky, 2 * NVS_KEY_SIZE * 8) != 0) {
  21. return ESP_ERR_NVS_XTS_CFG_FAILED;
  22. }
  23. return ESP_OK;
  24. }
  25. esp_err_t NVSEncryptedPartition::read(size_t src_offset, void* dst, size_t size)
  26. {
  27. /** Currently upper layer of NVS reads entries one by one even for variable size
  28. * multi-entry data types. So length should always be equal to size of an entry.*/
  29. if (size != sizeof(Item)) return ESP_ERR_INVALID_SIZE;
  30. // read data
  31. esp_err_t read_result = esp_partition_read(mESPPartition, src_offset, dst, size);
  32. if (read_result != ESP_OK) {
  33. return read_result;
  34. }
  35. // decrypt data
  36. //sector num required as an arr by mbedtls. Should have been just uint64/32.
  37. uint8_t data_unit[16];
  38. uint32_t relAddr = src_offset;
  39. memset(data_unit, 0, sizeof(data_unit));
  40. memcpy(data_unit, &relAddr, sizeof(relAddr));
  41. uint8_t *destination = reinterpret_cast<uint8_t*>(dst);
  42. if (mbedtls_aes_crypt_xts(&mDctxt, MBEDTLS_AES_DECRYPT, size, data_unit, destination, destination) != 0) {
  43. return ESP_ERR_NVS_XTS_DECR_FAILED;
  44. }
  45. return ESP_OK;
  46. }
  47. esp_err_t NVSEncryptedPartition::write(size_t addr, const void* src, size_t size)
  48. {
  49. if (size % ESP_ENCRYPT_BLOCK_SIZE != 0) return ESP_ERR_INVALID_SIZE;
  50. // copy data to buffer for encryption
  51. uint8_t* buf = new (std::nothrow) uint8_t [size];
  52. if (!buf) return ESP_ERR_NO_MEM;
  53. memcpy(buf, src, size);
  54. // encrypt data
  55. uint8_t entrySize = sizeof(Item);
  56. //sector num required as an arr by mbedtls. Should have been just uint64/32.
  57. uint8_t data_unit[16];
  58. /* Use relative address instead of absolute address (relocatable), so that host-generated
  59. * encrypted nvs images can be used*/
  60. uint32_t relAddr = addr;
  61. memset(data_unit, 0, sizeof(data_unit));
  62. for(uint8_t entry = 0; entry < (size/entrySize); entry++)
  63. {
  64. uint32_t offset = entry * entrySize;
  65. uint32_t *addr_loc = (uint32_t*) &data_unit[0];
  66. *addr_loc = relAddr + offset;
  67. if (mbedtls_aes_crypt_xts(&mEctxt,
  68. MBEDTLS_AES_ENCRYPT,
  69. entrySize,
  70. data_unit,
  71. buf + offset,
  72. buf + offset) != 0) {
  73. delete [] buf;
  74. return ESP_ERR_NVS_XTS_ENCR_FAILED;
  75. }
  76. }
  77. // write data
  78. esp_err_t result = esp_partition_write(mESPPartition, addr, buf, size);
  79. delete [] buf;
  80. return result;
  81. }
  82. } // nvs