5
5
//! device.
6
6
7
7
use std:: {
8
- collections:: HashMap ,
9
- fmt,
10
8
io:: { BufWriter , Read , Write } ,
11
9
iter:: zip,
12
10
thread:: sleep,
@@ -15,7 +13,6 @@ use std::{
15
13
16
14
use log:: { debug, info} ;
17
15
use regex:: Regex ;
18
- use serde:: { Deserialize , Serialize } ;
19
16
use serialport:: { SerialPort , UsbPortInfo } ;
20
17
use slip_codec:: SlipDecoder ;
21
18
@@ -36,184 +33,14 @@ use self::{
36
33
use crate :: {
37
34
command:: { Command , CommandResponse , CommandResponseValue , CommandType } ,
38
35
error:: { ConnectionError , Error , ResultExt , RomError , RomErrorKind } ,
39
- flasher:: stubs:: CHIP_DETECT_MAGIC_REG_ADDR ,
36
+ flasher:: { SecurityInfo , stubs:: CHIP_DETECT_MAGIC_REG_ADDR } ,
40
37
target:: Chip ,
41
38
} ;
42
39
43
40
pub ( crate ) mod reset;
44
41
45
42
pub use reset:: { ResetAfterOperation , ResetBeforeOperation } ;
46
43
47
- /// Security Info Response containing chip security information
48
- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Deserialize , Serialize ) ]
49
- pub struct SecurityInfo {
50
- /// 32 bits flags
51
- pub flags : u32 ,
52
- /// 1 byte flash_crypt_cnt
53
- pub flash_crypt_cnt : u8 ,
54
- /// 7 bytes key purposes
55
- pub key_purposes : [ u8 ; 7 ] ,
56
- /// 32-bit word chip id
57
- pub chip_id : Option < u32 > ,
58
- /// 32-bit word eco version
59
- pub eco_version : Option < u32 > ,
60
- }
61
-
62
- impl SecurityInfo {
63
- fn security_flag_map ( ) -> HashMap < & ' static str , u32 > {
64
- HashMap :: from ( [
65
- ( "SECURE_BOOT_EN" , 1 << 0 ) ,
66
- ( "SECURE_BOOT_AGGRESSIVE_REVOKE" , 1 << 1 ) ,
67
- ( "SECURE_DOWNLOAD_ENABLE" , 1 << 2 ) ,
68
- ( "SECURE_BOOT_KEY_REVOKE0" , 1 << 3 ) ,
69
- ( "SECURE_BOOT_KEY_REVOKE1" , 1 << 4 ) ,
70
- ( "SECURE_BOOT_KEY_REVOKE2" , 1 << 5 ) ,
71
- ( "SOFT_DIS_JTAG" , 1 << 6 ) ,
72
- ( "HARD_DIS_JTAG" , 1 << 7 ) ,
73
- ( "DIS_USB" , 1 << 8 ) ,
74
- ( "DIS_DOWNLOAD_DCACHE" , 1 << 9 ) ,
75
- ( "DIS_DOWNLOAD_ICACHE" , 1 << 10 ) ,
76
- ] )
77
- }
78
-
79
- fn security_flag_status ( & self , flag_name : & str ) -> bool {
80
- if let Some ( & flag) = Self :: security_flag_map ( ) . get ( flag_name) {
81
- ( self . flags & flag) != 0
82
- } else {
83
- false
84
- }
85
- }
86
- }
87
-
88
- impl TryFrom < & [ u8 ] > for SecurityInfo {
89
- type Error = Error ;
90
-
91
- fn try_from ( bytes : & [ u8 ] ) -> Result < Self , Self :: Error > {
92
- let esp32s2 = bytes. len ( ) == 12 ;
93
-
94
- if bytes. len ( ) < 12 {
95
- return Err ( Error :: InvalidResponse ( format ! (
96
- "expected response of at least 12 bytes, received {} bytes" ,
97
- bytes. len( )
98
- ) ) ) ;
99
- }
100
-
101
- // Parse response bytes
102
- let flags = u32:: from_le_bytes ( bytes[ 0 ..4 ] . try_into ( ) ?) ;
103
- let flash_crypt_cnt = bytes[ 4 ] ;
104
- let key_purposes: [ u8 ; 7 ] = bytes[ 5 ..12 ] . try_into ( ) ?;
105
-
106
- let ( chip_id, eco_version) = if esp32s2 {
107
- ( None , None ) // ESP32-S2 doesn't have these values
108
- } else {
109
- if bytes. len ( ) < 20 {
110
- return Err ( Error :: InvalidResponse ( format ! (
111
- "expected response of at least 20 bytes, received {} bytes" ,
112
- bytes. len( )
113
- ) ) ) ;
114
- }
115
- let chip_id = u32:: from_le_bytes ( bytes[ 12 ..16 ] . try_into ( ) ?) ;
116
- let eco_version = u32:: from_le_bytes ( bytes[ 16 ..20 ] . try_into ( ) ?) ;
117
- ( Some ( chip_id) , Some ( eco_version) )
118
- } ;
119
-
120
- Ok ( SecurityInfo {
121
- flags,
122
- flash_crypt_cnt,
123
- key_purposes,
124
- chip_id,
125
- eco_version,
126
- } )
127
- }
128
- }
129
-
130
- impl fmt:: Display for SecurityInfo {
131
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
132
- let key_purposes_str = self
133
- . key_purposes
134
- . iter ( )
135
- . map ( |b| format ! ( "{b}" ) )
136
- . collect :: < Vec < _ > > ( )
137
- . join ( ", " ) ;
138
-
139
- writeln ! ( f, "\n Security Information:" ) ?;
140
- writeln ! ( f, "=====================" ) ?;
141
- writeln ! ( f, "Flags: {:#010x} ({:b})" , self . flags, self . flags) ?;
142
- writeln ! ( f, "Key Purposes: [{key_purposes_str}]" ) ?;
143
-
144
- // Only print Chip ID if it's Some(value)
145
- if let Some ( chip_id) = self . chip_id {
146
- writeln ! ( f, "Chip ID: {chip_id}" ) ?;
147
- }
148
-
149
- // Only print API Version if it's Some(value)
150
- if let Some ( api_version) = self . eco_version {
151
- writeln ! ( f, "API Version: {api_version}" ) ?;
152
- }
153
-
154
- // Secure Boot
155
- if self . security_flag_status ( "SECURE_BOOT_EN" ) {
156
- writeln ! ( f, "Secure Boot: Enabled" ) ?;
157
- if self . security_flag_status ( "SECURE_BOOT_AGGRESSIVE_REVOKE" ) {
158
- writeln ! ( f, "Secure Boot Aggressive key revocation: Enabled" ) ?;
159
- }
160
-
161
- let revoked_keys: Vec < _ > = [
162
- "SECURE_BOOT_KEY_REVOKE0" ,
163
- "SECURE_BOOT_KEY_REVOKE1" ,
164
- "SECURE_BOOT_KEY_REVOKE2" ,
165
- ]
166
- . iter ( )
167
- . enumerate ( )
168
- . filter ( |( _, key) | self . security_flag_status ( key) )
169
- . map ( |( i, _) | format ! ( "Secure Boot Key{i} is Revoked" ) )
170
- . collect ( ) ;
171
-
172
- if !revoked_keys. is_empty ( ) {
173
- writeln ! (
174
- f,
175
- "Secure Boot Key Revocation Status:\n {}" ,
176
- revoked_keys. join( "\n " )
177
- ) ?;
178
- }
179
- } else {
180
- writeln ! ( f, "Secure Boot: Disabled" ) ?;
181
- }
182
-
183
- // Flash Encryption
184
- if self . flash_crypt_cnt . count_ones ( ) % 2 != 0 {
185
- writeln ! ( f, "Flash Encryption: Enabled" ) ?;
186
- } else {
187
- writeln ! ( f, "Flash Encryption: Disabled" ) ?;
188
- }
189
-
190
- let crypt_cnt_str = "SPI Boot Crypt Count (SPI_BOOT_CRYPT_CNT)" ;
191
- writeln ! ( f, "{}: 0x{:x}" , crypt_cnt_str, self . flash_crypt_cnt) ?;
192
-
193
- // Cache Disabling
194
- if self . security_flag_status ( "DIS_DOWNLOAD_DCACHE" ) {
195
- writeln ! ( f, "Dcache in UART download mode: Disabled" ) ?;
196
- }
197
- if self . security_flag_status ( "DIS_DOWNLOAD_ICACHE" ) {
198
- writeln ! ( f, "Icache in UART download mode: Disabled" ) ?;
199
- }
200
-
201
- // JTAG Status
202
- if self . security_flag_status ( "HARD_DIS_JTAG" ) {
203
- writeln ! ( f, "JTAG: Permanently Disabled" ) ?;
204
- } else if self . security_flag_status ( "SOFT_DIS_JTAG" ) {
205
- writeln ! ( f, "JTAG: Software Access Disabled" ) ?;
206
- }
207
-
208
- // USB Access
209
- if self . security_flag_status ( "DIS_USB" ) {
210
- writeln ! ( f, "USB Access: Disabled" ) ?;
211
- }
212
-
213
- Ok ( ( ) )
214
- }
215
- }
216
-
217
44
const MAX_CONNECT_ATTEMPTS : usize = 7 ;
218
45
const MAX_SYNC_ATTEMPTS : usize = 5 ;
219
46
const USB_SERIAL_JTAG_PID : u16 = 0x1001 ;
0 commit comments