@@ -18,6 +18,9 @@ Util.On('Tester_can_0.authenticationConfiguration.send', async (req) => {
1818let memorySize : number
1919Util . On ( 'Tester_can_0.RequestDownload520.send' , async ( req ) => {
2020 const resp = DiagResponse . fromDiagRequest ( req )
21+ // Reset transfer session state so this example can run repeatedly.
22+ fwContent = Buffer . alloc ( 0 )
23+ encryptedContent = Buffer . alloc ( 0 )
2124 memorySize = Number ( req . diagGetParameter ( 'memorySize' ) )
2225 console . log ( `memorySize:${ memorySize } ` )
2326 resp . diagSetRaw ( Buffer . from ( [ 0x74 , 0x40 , 0 , 0 , 0 , 0x81 ] ) )
@@ -101,30 +104,53 @@ Util.On('Tester_can_0.proofOfOwnership.send', async (req) => {
101104 }
102105} )
103106let fwContent : Buffer = Buffer . alloc ( 0 )
104- let decipher : crypto . DecipherGCM
107+ let encryptedContent : Buffer = Buffer . alloc ( 0 )
105108
106109Util . On ( 'Tester_can_0.TransferData540.send' , async ( req ) => {
107110 const raw = req . diagGetRaw ( )
108- if ( ! decipher ) {
109- decipher = crypto . createDecipheriv ( 'aes-256-gcm' , realKey , Buffer . alloc ( 12 , 0 ) )
110- }
111111 const transferRequestParameterRecord = raw . subarray ( 2 )
112- const decrypted = decipher . update ( transferRequestParameterRecord )
113- if ( fwContent . length < memorySize ) {
114- fwContent = Buffer . concat ( [ fwContent , decrypted ] )
115- if ( fwContent . length >= memorySize ) {
116- console . log ( `decrypted content :${ fwContent . subarray ( 0 , memorySize ) . toString ( 'ascii' ) } ` )
117- }
112+ console . log ( `TransferData payload length:${ transferRequestParameterRecord . length } ` )
113+ if ( encryptedContent . length < memorySize ) {
114+ encryptedContent = Buffer . concat ( [ encryptedContent , transferRequestParameterRecord ] )
115+ console . log ( `encryptedContent length:${ encryptedContent . length } /${ memorySize } ` )
118116 }
119117 const resp = DiagResponse . fromDiagRequest ( req )
120118 resp . diagSetRaw ( Buffer . from ( [ 0x76 , Number ( req . diagGetParameter ( 'blockSequenceCounter' ) ) ] ) )
121119 await resp . outputDiag ( )
122120} )
123121
124122Util . On ( 'Tester_can_0.RequestTransferExit550.send' , async ( req ) => {
123+ if ( ! realKey || encryptedContent . length === 0 ) {
124+ throw new Error ( 'transfer session not initialized' )
125+ }
125126 const raw = req . diagGetRaw ( )
126- decipher . setAuthTag ( raw . subarray ( 2 ) )
127- decipher . final ( )
127+ let authTag = req . diagGetParameterRaw ( 'auth' )
128+ console . log ( `RequestTransferExit raw length:${ raw . length } , auth length:${ authTag . length } ` )
129+ console . log (
130+ `RequestTransferExit encryptedContent length:${ encryptedContent . length } /${ memorySize } `
131+ )
132+ // Some service descriptions keep auth default at 4 bytes unless resized at runtime.
133+ // AES-GCM tag is 16 bytes, so fall back to the last 16 bytes of raw payload.
134+ if ( authTag . length !== 16 && raw . length >= 17 ) {
135+ authTag = raw . subarray ( raw . length - 16 )
136+ console . log ( `fallback auth length:${ authTag . length } ` )
137+ }
138+ if ( authTag . length !== 16 ) {
139+ throw new Error ( `invalid auth tag length:${ authTag . length } ` )
140+ }
141+ // Some stacks may append extra bytes in TransferData payload. Keep only expected download size.
142+ const encryptedPayload = encryptedContent . subarray ( 0 , memorySize )
143+ if ( encryptedContent . length !== memorySize ) {
144+ console . log (
145+ `trim encryptedContent from ${ encryptedContent . length } to ${ encryptedPayload . length } `
146+ )
147+ }
148+ const decipher = crypto . createDecipheriv ( 'aes-256-gcm' , realKey , Buffer . alloc ( 12 , 0 ) )
149+ decipher . setAuthTag ( authTag )
150+ const decrypted = Buffer . concat ( [ decipher . update ( encryptedPayload ) , decipher . final ( ) ] )
151+ fwContent = decrypted
152+ console . log ( `decrypted content :${ fwContent . subarray ( 0 , memorySize ) . toString ( 'ascii' ) } ` )
153+ encryptedContent = Buffer . alloc ( 0 )
128154 const resp = DiagResponse . fromDiagRequest ( req )
129155 resp . diagSetRaw ( Buffer . from ( [ 0x77 ] ) )
130156 await resp . outputDiag ( )
0 commit comments