1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "sdkconfig.h"
16 #include "bootloader_flash.h"
17 #include "bootloader_sha.h"
19 #include "esp_image_format.h"
20 #include "esp_secure_boot.h"
24 #ifdef BOOTLOADER_BUILD
26 typedef SHA_CTX sha_context
;
28 #include "hwcrypto/sha.h"
31 static const char* TAG
= "secure_boot";
33 extern const uint8_t signature_verification_key_start
[] asm("_binary_signature_verification_key_bin_start");
34 extern const uint8_t signature_verification_key_end
[] asm("_binary_signature_verification_key_bin_end");
36 #define SIGNATURE_VERIFICATION_KEYLEN 64
40 esp_err_t
esp_secure_boot_verify_signature(uint32_t src_addr
, uint32_t length
)
42 uint8_t digest
[DIGEST_LEN
];
44 const esp_secure_boot_sig_block_t
*sigblock
;
46 ESP_LOGD(TAG
, "verifying signature src_addr 0x%x length 0x%x", src_addr
, length
);
48 data
= bootloader_mmap(src_addr
, length
+ sizeof(esp_secure_boot_sig_block_t
));
50 ESP_LOGE(TAG
, "bootloader_mmap(0x%x, 0x%x) failed", src_addr
, length
+sizeof(esp_secure_boot_sig_block_t
));
54 // Calculate digest of main image
55 #ifdef BOOTLOADER_BUILD
56 bootloader_sha256_handle_t handle
= bootloader_sha256_start();
57 bootloader_sha256_data(handle
, data
, length
);
58 bootloader_sha256_finish(handle
, digest
);
60 /* Use thread-safe esp-idf SHA function */
61 esp_sha(SHA2_256
, data
, length
, digest
);
64 // Map the signature block and verify the signature
65 sigblock
= (const esp_secure_boot_sig_block_t
*)(data
+ length
);
66 esp_err_t err
= esp_secure_boot_verify_signature_block(sigblock
, digest
);
67 bootloader_munmap(data
);
71 esp_err_t
esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block_t
*sig_block
, const uint8_t *image_digest
)
76 keylen
= signature_verification_key_end
- signature_verification_key_start
;
77 if(keylen
!= SIGNATURE_VERIFICATION_KEYLEN
) {
78 ESP_LOGE(TAG
, "Embedded public verification key has wrong length %d", keylen
);
82 if (sig_block
->version
!= 0) {
83 ESP_LOGE(TAG
, "image has invalid signature version field 0x%08x", sig_block
->version
);
87 is_valid
= uECC_verify(signature_verification_key_start
,
92 return is_valid
? ESP_OK
: ESP_ERR_IMAGE_INVALID
;