1 /*
2  * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "ets_sys.h"
12 #include "ecdsa.h"
13 #include "esp_assert.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 typedef struct ets_secure_boot_sig_block ets_secure_boot_sig_block_t;
20 typedef struct ets_secure_boot_signature ets_secure_boot_signature_t;
21 typedef struct ets_secure_boot_key_digests ets_secure_boot_key_digests_t;
22 
23 /* Anti-FI measure: use full words for success/fail, instead of
24    0/non-zero
25 */
26 typedef enum {
27     SB_SUCCESS = 0x3A5A5AA5,
28     SB_FAILED = 0x7533885E,
29 } ets_secure_boot_status_t;
30 
31 
32 /* Verify bootloader image (reconfigures cache to map),
33    with key digests provided as parameters.)
34 
35    Can be used to verify secure boot status before enabling
36    secure boot permanently.
37 
38    If stage_load parameter is true, bootloader is copied into staging
39    buffer in RAM at the same time.
40 
41    If result is SB_SUCCESS, the "simple hash" of the bootloader is
42    copied into verified_hash.
43 */
44 ets_secure_boot_status_t ets_secure_boot_verify_bootloader_with_keys(uint8_t *verified_hash, const ets_secure_boot_key_digests_t *trusted_keys, bool stage_load);
45 
46 /* Read key digests from efuse. Any revoked/missing digests will be
47    marked as NULL
48 */
49 ETS_STATUS ets_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys);
50 
51 /* Verify supplied signature against supplied digest, using
52    supplied trusted key digests.
53 
54    Doesn't reconfigure cache or any other hardware access except for RSA peripheral.
55 
56    If result is SB_SUCCESS, the image_digest value is copied into verified_digest.
57 */
58 ets_secure_boot_status_t ets_secure_boot_verify_signature(const ets_secure_boot_signature_t *sig, const uint8_t *image_digest, const ets_secure_boot_key_digests_t *trusted_keys, uint8_t *verified_digest);
59 
60 #define CRC_SIGN_BLOCK_LEN 1196
61 #define SIG_BLOCK_PADDING 4096
62 #define ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC 0xE7
63 
64 /* Secure Boot V2 signature block (extended to support ECDSA)
65 
66    (Up to 3 in a signature sector are appended to the image)
67  */
68 struct __attribute((packed)) ets_secure_boot_sig_block {
69     uint8_t magic_byte;
70     uint8_t version;
71     uint8_t _reserved1;
72     uint8_t _reserved2;
73     uint8_t image_digest[32];
74     struct {
75         struct {
76             uint8_t curve_id; /* ETS_ECDSA_CURVE_P192 / ETS_ECDSA_CURVE_P256 */
77             uint8_t point[64]; /* X followed by Y (both little-endian), plus zero bytes if P192 */
78         } key;
79         uint8_t signature[64]; /* r followed by s (both little-endian) */
80         uint8_t padding[1031];
81     } ecdsa;
82     uint32_t block_crc; /* note: crc covers all bytes in the structure before it, regardless of version field */
83     uint8_t _padding[16];
84 };
85 
86 ESP_STATIC_ASSERT(sizeof(ets_secure_boot_sig_block_t) == 1216, "invalid sig block size");
87 
88 #define SECURE_BOOT_NUM_BLOCKS 1
89 
90 /* V2 Secure boot signature sector (up to 3 blocks) */
91 struct ets_secure_boot_signature {
92     ets_secure_boot_sig_block_t block[SECURE_BOOT_NUM_BLOCKS];
93     uint8_t _padding[4096 - (sizeof(ets_secure_boot_sig_block_t) * SECURE_BOOT_NUM_BLOCKS)];
94 };
95 
96 ESP_STATIC_ASSERT(sizeof(ets_secure_boot_signature_t) == 4096, "invalid sig sector size");
97 
98 #define MAX_KEY_DIGESTS 1
99 
100 struct ets_secure_boot_key_digests {
101     const void *key_digests[MAX_KEY_DIGESTS];
102     bool allow_key_revoke;
103 };
104 
105 #ifdef __cplusplus
106 }
107 #endif
108