@@ -12,8 +12,6 @@ Abstract:
1212
1313--*/
1414
15- use core:: mem:: ManuallyDrop ;
16-
1715use crate :: flow:: cold_reset:: fw_processor:: FirmwareProcessor ;
1816use crate :: CaliptraResult ;
1917use caliptra_api:: mailbox:: {
@@ -58,11 +56,24 @@ pub fn debug_unlock(env: &mut RomEnv) -> CaliptraResult<()> {
5856 }
5957}
6058
59+ fn start_debug_unlock ( env : & mut RomEnv ) {
60+ env. soc_ifc . set_ss_dbg_unlock_tap_mailbox_available ( true ) ;
61+ env. soc_ifc . set_ss_dbg_unlock_in_progress ( true ) ;
62+ }
63+
64+ fn finish_debug_unlock ( env : & mut RomEnv , response_sent : bool ) {
65+ env. soc_ifc . set_ss_dbg_unlock_in_progress ( false ) ;
66+ if response_sent {
67+ env. mbox . wait_until_idle ( ) ;
68+ env. soc_ifc . set_ss_dbg_unlock_tap_mailbox_available ( false ) ;
69+ }
70+ }
71+
6172fn handle_manufacturing ( env : & mut RomEnv ) -> CaliptraResult < ( ) > {
6273 cprintln ! ( "[dbg_manuf] ++" ) ;
6374
6475 // Set debug unlock in progress and unlock the mailbox for tap access.
65- env . soc_ifc . set_ss_dbg_unlock_in_progress ( true ) ;
76+ start_debug_unlock ( env ) ;
6677
6778 let mbox = & mut env. mbox ;
6879 let txn = loop {
@@ -81,7 +92,7 @@ fn handle_manufacturing(env: &mut RomEnv) -> CaliptraResult<()> {
8192 Err ( CaliptraError :: SS_DBG_UNLOCK_MANUF_INVALID_MBOX_CMD ) ?;
8293 }
8394
84- let mut txn = ManuallyDrop :: new ( txn. start_txn ( ) ) ;
95+ let mut txn = txn. start_txn ( ) ;
8596
8697 let result = ( || {
8798 let mut request = ManufDebugUnlockTokenReq :: default ( ) ;
@@ -115,124 +126,139 @@ fn handle_manufacturing(env: &mut RomEnv) -> CaliptraResult<()> {
115126 }
116127 }
117128
118- env. soc_ifc . set_ss_dbg_unlock_in_progress ( false ) ;
129+ drop ( txn) ;
130+ finish_debug_unlock ( env, true ) ;
119131
120132 cprintln ! ( "[dbg_manuf] --" ) ;
121133 result
122134}
123135
124136fn handle_auth_debug_unlock_request (
125137 env : & mut RomEnv ,
126- ) -> CaliptraResult < (
127- ProductionAuthDebugUnlockReq ,
128- ProductionAuthDebugUnlockChallenge ,
129- ) > {
130- let mbox = & mut env. mbox ;
131- let txn = loop {
132- // Random delay for CFI glitch protection.
133- CfiCounter :: delay ( ) ;
134-
135- match mbox. peek_recv ( ) {
136- Some ( txn) => break txn,
137- None => continue ,
138+ ) -> (
139+ CaliptraResult < (
140+ ProductionAuthDebugUnlockReq ,
141+ ProductionAuthDebugUnlockChallenge ,
142+ ) > ,
143+ bool ,
144+ ) {
145+ let mut response_sent = false ;
146+ let result = ( || {
147+ let mbox = & mut env. mbox ;
148+ let txn = loop {
149+ // Random delay for CFI glitch protection.
150+ CfiCounter :: delay ( ) ;
151+
152+ match mbox. peek_recv ( ) {
153+ Some ( txn) => break txn,
154+ None => continue ,
155+ }
156+ } ;
157+
158+ if CommandId :: from ( txn. cmd ( ) ) != CommandId :: PRODUCTION_AUTH_DEBUG_UNLOCK_REQ {
159+ Err ( CaliptraError :: SS_DBG_UNLOCK_PROD_INVALID_REQ_MBOX_CMD ) ?
138160 }
139- } ;
140161
141- if CommandId :: from ( txn. cmd ( ) ) != CommandId :: PRODUCTION_AUTH_DEBUG_UNLOCK_REQ {
142- cprintln ! (
143- "Invalid command: {:?}, was expecting PRODUCTION_AUTH_DEBUG_UNLOCK_REQ" ,
144- txn. cmd( )
162+ let mut txn = txn. start_txn ( ) ;
163+
164+ // Copy request data since it needs to persist
165+ let mut request = ProductionAuthDebugUnlockReq :: default ( ) ;
166+ FirmwareProcessor :: copy_req_verify_chksum ( & mut txn, request. as_mut_bytes ( ) , false ) ?;
167+
168+ // Use common function to create challenge
169+ let challenge = debug_unlock:: create_debug_unlock_challenge (
170+ & mut env. trng ,
171+ & env. soc_ifc ,
172+ & mut env. dma ,
173+ & request,
145174 ) ;
146- Err ( CaliptraError :: SS_DBG_UNLOCK_PROD_INVALID_REQ_MBOX_CMD ) ?
147- }
148175
149- let mut txn = ManuallyDrop :: new ( txn. start_txn ( ) ) ;
150-
151- // Process request and create challenge
152- let mut request = ProductionAuthDebugUnlockReq :: default ( ) ;
153- FirmwareProcessor :: copy_req_verify_chksum ( & mut txn, request. as_mut_bytes ( ) , false ) ?;
154-
155- // Use common function to create challenge
156- let challenge = debug_unlock:: create_debug_unlock_challenge (
157- & mut env. trng ,
158- & env. soc_ifc ,
159- & mut env. dma ,
160- & request,
161- ) ;
162-
163- // Send response
164- match challenge {
165- Err ( err) => {
166- txn. send_response ( MailboxRespHeader :: default ( ) . as_bytes ( ) ) ?;
167- Err ( err)
168- }
169- Ok ( challenge_resp) => {
170- txn. send_response ( challenge_resp. as_bytes ( ) ) ?;
171- Ok ( ( request, challenge_resp) )
176+ // Send response
177+ match challenge {
178+ Err ( err) => {
179+ txn. send_response ( MailboxRespHeader :: default ( ) . as_bytes ( ) ) ?;
180+ response_sent = true ;
181+ Err ( err)
182+ }
183+ Ok ( challenge_resp) => {
184+ txn. send_response ( challenge_resp. as_bytes ( ) ) ?;
185+ response_sent = true ;
186+ Ok ( ( request, challenge_resp) )
187+ }
172188 }
173- }
189+ } ) ( ) ;
190+ ( result, response_sent)
174191}
175192
176193fn handle_auth_debug_unlock_token (
177194 env : & mut RomEnv ,
178195 request : & ProductionAuthDebugUnlockReq ,
179196 challenge : & ProductionAuthDebugUnlockChallenge ,
180- ) -> CaliptraResult < ( ) > {
181- let mbox = & mut env. mbox ;
182- let txn = loop {
183- // Random delay for CFI glitch protection.
184- CfiCounter :: delay ( ) ;
185-
186- match mbox. peek_recv ( ) {
187- Some ( txn) => break txn,
188- None => continue ,
197+ ) -> ( CaliptraResult < ( ) > , bool ) {
198+ let mut response_sent = false ;
199+ let result = ( || {
200+ let mbox = & mut env. mbox ;
201+ let txn = loop {
202+ // Random delay for CFI glitch protection.
203+ CfiCounter :: delay ( ) ;
204+
205+ match mbox. peek_recv ( ) {
206+ Some ( txn) => break txn,
207+ None => continue ,
208+ }
209+ } ;
210+
211+ if CommandId :: from ( txn. cmd ( ) ) != CommandId :: PRODUCTION_AUTH_DEBUG_UNLOCK_TOKEN {
212+ Err ( CaliptraError :: SS_DBG_UNLOCK_PROD_INVALID_TOKEN_MBOX_CMD ) ?;
189213 }
190- } ;
191214
192- if CommandId :: from ( txn. cmd ( ) ) != CommandId :: PRODUCTION_AUTH_DEBUG_UNLOCK_TOKEN {
193- cprintln ! (
194- "Invalid command: {:?}, was expecting PRODUCTION_AUTH_DEBUG_UNLOCK_TOKEN" ,
195- txn. cmd( )
215+ let mut txn = txn. start_txn ( ) ;
216+
217+ // Copy token data
218+ let mut token = ProductionAuthDebugUnlockToken :: default ( ) ;
219+ FirmwareProcessor :: copy_req_verify_chksum ( & mut txn, token. as_mut_bytes ( ) , false ) ?;
220+
221+ // Use common validation function
222+ let result = debug_unlock:: validate_debug_unlock_token (
223+ & env. soc_ifc ,
224+ & mut env. sha2_512_384 ,
225+ & mut env. sha2_512_384_acc ,
226+ & mut env. ecc384 ,
227+ & mut env. mldsa87 ,
228+ & mut env. dma ,
229+ request,
230+ challenge,
231+ & token,
196232 ) ;
197- Err ( CaliptraError :: SS_DBG_UNLOCK_PROD_INVALID_TOKEN_MBOX_CMD ) ?;
198- }
199233
200- let mut txn = ManuallyDrop :: new ( txn. start_txn ( ) ) ;
201-
202- // Copy token from mailbox
203- let mut token = ProductionAuthDebugUnlockToken :: default ( ) ;
204- FirmwareProcessor :: copy_req_verify_chksum ( & mut txn, token. as_mut_bytes ( ) , false ) ?;
205-
206- // Use common validation function
207- let result = debug_unlock:: validate_debug_unlock_token (
208- & env. soc_ifc ,
209- & mut env. sha2_512_384 ,
210- & mut env. sha2_512_384_acc ,
211- & mut env. ecc384 ,
212- & mut env. mldsa87 ,
213- & mut env. dma ,
214- request,
215- challenge,
216- & token,
217- ) ;
218-
219- // Send response
220- let _ = txn. send_response ( MailboxRespHeader :: default ( ) . as_bytes ( ) ) ;
221- result
234+ // Send response
235+ if txn
236+ . send_response ( MailboxRespHeader :: default ( ) . as_bytes ( ) )
237+ . is_ok ( )
238+ {
239+ response_sent = true ;
240+ }
241+ result
242+ } ) ( ) ;
243+ ( result, response_sent)
222244}
223245
224246fn handle_production ( env : & mut RomEnv ) -> CaliptraResult < ( ) > {
225247 cprintln ! ( "[dbg_prod] ++" ) ;
226248
227- env . soc_ifc . set_ss_dbg_unlock_in_progress ( true ) ;
249+ start_debug_unlock ( env ) ;
228250
229- let mut debug_unlock_op = || -> CaliptraResult < u8 > {
230- let ( request, challenge) = handle_auth_debug_unlock_request ( env) ?;
231- handle_auth_debug_unlock_token ( env, & request, & challenge) ?;
232- Ok ( request. unlock_level )
251+ let ( result, response_sent) = match handle_auth_debug_unlock_request ( env) {
252+ ( Ok ( ( request, challenge) ) , request_response_sent) => {
253+ let ( token_result, token_response_sent) =
254+ handle_auth_debug_unlock_token ( env, & request, & challenge) ;
255+ (
256+ token_result. map ( |_| request. unlock_level ) ,
257+ request_response_sent || token_response_sent,
258+ )
259+ }
260+ ( Err ( err) , response_sent) => ( Err ( err) , response_sent) ,
233261 } ;
234-
235- let result = debug_unlock_op ( ) ;
236262 match result {
237263 Ok ( unlock_level) => {
238264 env. soc_ifc . set_ss_dbg_unlock_level ( unlock_level) ;
@@ -245,7 +271,7 @@ fn handle_production(env: &mut RomEnv) -> CaliptraResult<()> {
245271 env. soc_ifc . set_ss_dbg_unlock_result ( false ) ;
246272 }
247273 }
248- env . soc_ifc . set_ss_dbg_unlock_in_progress ( false ) ;
274+ finish_debug_unlock ( env , response_sent ) ;
249275
250276 cprintln ! ( "[dbg_prod] --" ) ;
251277 result. map ( |_| ( ) )
0 commit comments