1 // Copyright 2020 Espressif Systems (Shanghai) PTE LTD
2 //
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
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
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 
15 #ifndef _ROM_SECURE_BOOT_H_
16 #define _ROM_SECURE_BOOT_H_
17 
18 #include <stdint.h>
19 #include <stdbool.h>
20 #include "ets_sys.h"
21 #include "rsa_pss.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 struct ets_secure_boot_sig_block;
28 struct ets_secure_boot_signature_t;
29 
30 typedef struct ets_secure_boot_sig_block ets_secure_boot_sig_block_t;
31 typedef struct ets_secure_boot_signature ets_secure_boot_signature_t;
32 typedef struct ets_secure_boot_key_digests ets_secure_boot_key_digests_t;
33 
34 /* Anti-FI measure: use full words for success/fail, instead of
35    0/non-zero
36 */
37 typedef enum {
38     SB_SUCCESS = 0x3A5A5AA5,
39     SB_FAILED = 0x7533885E,
40 } ets_secure_boot_status_t;
41 
42 
43 /* Verify and stage-load the bootloader image
44    (reconfigures cache to map, loads trusted key digests from efuse,
45    copies the bootloader into the staging buffer.)
46 
47    If allow_key_revoke is true and aggressive revoke efuse is set,
48    any failed signature has its associated key revoked in efuse.
49 
50    If result is SB_SUCCESS, the "simple hash" of the bootloader
51    is copied into verified_hash.
52 */
53 ets_secure_boot_status_t ets_secure_boot_verify_stage_bootloader(uint8_t *verified_hash, bool allow_key_revoke);
54 
55 /* Verify bootloader image (reconfigures cache to map),
56    with key digests provided as parameters.)
57 
58    Can be used to verify secure boot status before enabling
59    secure boot permanently.
60 
61    If stage_load parameter is true, bootloader is copied into staging
62    buffer in RAM at the same time.
63 
64    If result is SB_SUCCESS, the "simple hash" of the bootloader is
65    copied into verified_hash.
66 */
67 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);
68 
69 /* Read key digests from efuse. Any revoked/missing digests will be
70    marked as NULL
71 */
72 ETS_STATUS ets_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys);
73 
74 /* Verify supplied signature against supplied digest, using
75    supplied trusted key digests.
76 
77    Doesn't reconfigure cache or any other hardware access except for RSA peripheral.
78 
79    If result is SB_SUCCESS, the image_digest value is copied into verified_digest.
80 */
81 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);
82 
83 /* Revoke a public key digest in efuse.
84    @param index Digest to revoke. Must be 0, 1 or 2.
85  */
86 void ets_secure_boot_revoke_public_key_digest(int index);
87 
88 #define CRC_SIGN_BLOCK_LEN 1196
89 #define SIG_BLOCK_PADDING 4096
90 #define ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC 0xE7
91 
92 /* Secure Boot V2 signature block
93 
94    (Up to 3 in a signature sector are appended to the image)
95  */
96 struct ets_secure_boot_sig_block {
97     uint8_t magic_byte;
98     uint8_t version;
99     uint8_t _reserved1;
100     uint8_t _reserved2;
101     uint8_t image_digest[32];
102     ets_rsa_pubkey_t key;
103     uint8_t signature[384];
104     uint32_t block_crc;
105     uint8_t _padding[16];
106 };
107 
108 _Static_assert(sizeof(ets_secure_boot_sig_block_t) == 1216, "invalid sig block size");
109 
110 #define SECURE_BOOT_NUM_BLOCKS 3
111 
112 /* V2 Secure boot signature sector (up to 3 blocks) */
113 struct ets_secure_boot_signature {
114     ets_secure_boot_sig_block_t block[SECURE_BOOT_NUM_BLOCKS];
115     uint8_t _padding[4096 - (sizeof(ets_secure_boot_sig_block_t) * SECURE_BOOT_NUM_BLOCKS)];
116 };
117 
118 _Static_assert(sizeof(ets_secure_boot_signature_t) == 4096, "invalid sig sector size");
119 
120 #define MAX_KEY_DIGESTS 3
121 
122 struct ets_secure_boot_key_digests {
123     const void *key_digests[MAX_KEY_DIGESTS];
124     bool allow_key_revoke;
125 };
126 
127 #ifdef __cplusplus
128 }
129 #endif
130 
131 #endif /* _ROM_SECURE_BOOT_H_ */
132