| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include <string.h>
- #include "esp_types.h"
- #include "esp_attr.h"
- #include "esp_log.h"
- #include "esp_err.h"
- #include "rom/cache.h"
- #include "rom/ets_sys.h"
- #include "rom/spi_flash.h"
- #include "soc/dport_reg.h"
- #include "soc/io_mux_reg.h"
- #include "soc/efuse_reg.h"
- #include "soc/rtc_cntl_reg.h"
- #include "sdkconfig.h"
- #include "bootloader_config.h"
- #include "esp_image_format.h"
- static const char* TAG = "flash_encrypt";
- /**
- * @function : bitcount
- * @description: calculate bit 1 in flash_crypt_cnt
- * if it's even number, need encrypt flash data, and burn efuse
- *
- * @inputs: n flash_crypt_cnt
- * @return: number of 1 in flash_crypt_cnt
- *
- */
- int bitcount(int n){
- int count = 0;
- while (n > 0) {
- count += n & 1;
- n >>= 1;
- }
- return count;
- }
- /**
- * @function : flash_encrypt_write
- * @description: write encrypted data in flash
- *
- * @inputs: pos address in flash
- * len size of data need encrypt
- * @return: return true, if the write flash success
- *
- */
- bool flash_encrypt_write(uint32_t pos, uint32_t len)
- {
- SpiFlashOpResult spiRet;
- uint32_t buf[1024];
- int i = 0;
- Cache_Read_Disable(0);
- for (i = 0;i<((len-1)/0x1000 + 1);i++) {
- spiRet = SPIRead(pos, buf, SPI_SEC_SIZE);
- if (spiRet != SPI_FLASH_RESULT_OK) {
- Cache_Read_Enable(0);
- ESP_LOGE(TAG, SPI_ERROR_LOG);
- return false;
- }
- spiRet = SPIEraseSector(pos/SPI_SEC_SIZE);
- if (spiRet != SPI_FLASH_RESULT_OK) {
- Cache_Read_Enable(0);
- ESP_LOGE(TAG, SPI_ERROR_LOG);
- return false;
- }
- spiRet = SPI_Encrypt_Write(pos, buf, SPI_SEC_SIZE);
- if (spiRet != SPI_FLASH_RESULT_OK) {
- Cache_Read_Enable(0);
- ESP_LOGE(TAG, SPI_ERROR_LOG);
- return false;
- }
- pos += SPI_SEC_SIZE;
- }
- Cache_Read_Enable(0);
- return true;
- }
- /**
- * @function : flash_encrypt
- * @description: encrypt 2nd boot ,partition table ,factory bin ��test bin (if use)��ota bin
- * ��OTA info sector.
- *
- * @inputs: bs bootloader state structure used to save the data
- *
- * @return: return true, if the encrypt flash success
- *
- */
- bool flash_encrypt(bootloader_state_t *bs)
- {
- esp_err_t err;
- uint32_t image_len = 0;
- uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_FLASH_CRYPT_CNT);
- uint8_t count = bitcount(flash_crypt_cnt);
- ESP_LOGD(TAG, "flash encrypt cnt %x, bitcount %d", flash_crypt_cnt, count);
- if ((count % 2) == 0) {
- /* encrypt iv and abstract */
- if (false == flash_encrypt_write(0, SPI_SEC_SIZE)) {
- ESP_LOGE(TAG, "encrypt iv and abstract error");
- return false;
- }
- /* encrypt bootloader image */
- err = esp_image_basic_verify(0x1000, &image_len);
- if(err == ESP_OK && image_len != 0) {
- if (false == flash_encrypt_write(0x1000, image_len)) {
- ESP_LOGE(TAG, "encrypt 2nd boot error");
- return false;
- }
- } else {
- ESP_LOGE(TAG, "2nd boot len error");
- return false;
- }
- /* encrypt partition table */
- if (false == flash_encrypt_write(ESP_PARTITION_TABLE_ADDR, SPI_SEC_SIZE)) {
- ESP_LOGE(TAG, "encrypt partition table error");
- return false;
- }
- /* encrypt write factory bin */
- if(bs->factory.offset != 0 && bs->factory.size != 0) {
- ESP_LOGD(TAG, "have factory bin");
- if (false == flash_encrypt_write(bs->factory.offset, bs->factory.size)) {
- ESP_LOGE(TAG, "encrypt factory bin error");
- return false;
- }
- }
- /* encrypt write test bin */
- if(bs->test.offset != 0 && bs->test.size != 0) {
- ESP_LOGD(TAG, "have test bin");
- if (false == flash_encrypt_write(bs->test.offset, bs->test.size)) {
- ESP_LOGE(TAG, "encrypt test bin error");
- return false;
- }
- }
- /* encrypt write ota bin */
- for (int i = 0; i < 16; i++) {
- if(bs->ota[i].offset != 0 && bs->ota[i].size != 0) {
- ESP_LOGD(TAG, "have ota[%d] bin",i);
- if (false == flash_encrypt_write(bs->ota[i].offset, bs->ota[i].size)) {
- ESP_LOGE(TAG, "encrypt ota bin error");
- return false;
- }
- }
- }
- /* encrypt write ota info bin */
- if (false == flash_encrypt_write(bs->ota_info.offset, 2*SPI_SEC_SIZE)) {
- ESP_LOGE(TAG, "encrypt ota info error");
- return false;
- }
- REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, 0x04);
- REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
- REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
- while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
- ESP_LOGW(TAG, "burn flash_crypt_cnt");
- REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
- REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
- while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
- return true;
- } else {
- ESP_LOGI(TAG, "flash already encrypted.");
- return true;
- }
- }
|