Esempio n. 1
0
bool esp32_fs_crypt_init(void) {
  uint8_t tmp[32];
  uint32_t addr = 0;
  for (addr = 0; addr < spi_flash_get_chip_size(); addr += 32) {
    mgos_wdt_feed();
    if (spi_flash_read(addr, tmp, sizeof(tmp)) != ESP_OK) {
      LOG(LL_ERROR, ("SPI read error at 0x%x", addr));
      return false;
    }
    int j;
    for (j = 0; j < sizeof(tmp); j++) {
      if (tmp[j] != 0xff) break;
    }
    if (j < sizeof(tmp)) continue;
    /* Found a suitably empty location, now decrypt it. */
    if (spi_flash_read_encrypted(addr, tmp, sizeof(tmp)) != ESP_OK) {
      LOG(LL_ERROR, ("SPI encrypted read error at 0x%x", addr));
      return false;
    }
    /* Now in tmp we have 32 x 0xff processed with the flash encryption key. */
    mbedtls_aes_init(&s_aes_ctx_enc);
    mbedtls_aes_setkey_enc(&s_aes_ctx_enc, tmp, 256);
    mbedtls_aes_init(&s_aes_ctx_dec);
    mbedtls_aes_setkey_dec(&s_aes_ctx_dec, tmp, 256);
    LOG(LL_INFO, ("FS encryption key set up, seed @ 0x%x", addr));
    return true;
  }
  LOG(LL_ERROR, ("Could not a suitable seed area for FS encryption"));
  return false;
}
Esempio n. 2
0
esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size)
{
    CHECK_WRITE_ADDRESS(dest_addr, size);
    const uint8_t *ssrc = (const uint8_t *)src;
    if ((dest_addr % 16) != 0) {
        return ESP_ERR_INVALID_ARG;
    }
    if ((size % 16) != 0) {
        return ESP_ERR_INVALID_SIZE;
    }

    COUNTER_START();
    esp_rom_spiflash_result_t rc;
    rc = spi_flash_unlock();
    if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
        /* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes,
           so copy to a temporary buffer - 32 bytes at a time.

           Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of
           data to encrypt, and each row is two 16 byte AES blocks
           that share a key (as derived from flash address).
        */
        uint8_t encrypt_buf[32] __attribute__((aligned(4)));
        uint32_t row_size;
        for (size_t i = 0; i < size; i += row_size) {
            uint32_t row_addr = dest_addr + i;
            if (i == 0 && (row_addr % 32) != 0) {
                /* writing to second block of a 32 byte row */
                row_size = 16;
                row_addr -= 16;
                /* copy to second block in buffer */
                memcpy(encrypt_buf + 16, ssrc + i, 16);
                /* decrypt the first block from flash, will reencrypt to same bytes */
                spi_flash_read_encrypted(row_addr, encrypt_buf, 16);
            } else if (size - i == 16) {
                /* 16 bytes left, is first block of a 32 byte row */
                row_size = 16;
                /* copy to first block in buffer */
                memcpy(encrypt_buf, ssrc + i, 16);
                /* decrypt the second block from flash, will reencrypt to same bytes */
                spi_flash_read_encrypted(row_addr + 16, encrypt_buf + 16, 16);
            } else {
                /* Writing a full 32 byte row (2 blocks) */
                row_size = 32;
                memcpy(encrypt_buf, ssrc + i, 32);
            }

            spi_flash_guard_start();
            rc = esp_rom_spiflash_write_encrypted(row_addr, (uint32_t *)encrypt_buf, 32);
            spi_flash_guard_end();
            if (rc != ESP_ROM_SPIFLASH_RESULT_OK) {
                break;
            }
        }
        bzero(encrypt_buf, sizeof(encrypt_buf));
    }
    COUNTER_ADD_BYTES(write, size);
    COUNTER_STOP(write);

    spi_flash_guard_op_lock();
    spi_flash_mark_modified_region(dest_addr, size);
    spi_flash_guard_op_unlock();

    return spi_flash_translate_rc(rc);
}