@@ -3,11 +3,12 @@ import fs from 'fs/promises'
3
3
import path from 'path'
4
4
import crypto from 'crypto'
5
5
6
- const challenge = Buffer . from (
6
+ const challengeSelf = Buffer . from (
7
7
Array ( 32 )
8
8
. fill ( 0 )
9
9
. map ( ( ) => Math . floor ( Math . random ( ) * 256 ) )
10
10
)
11
+ let fwContent : Buffer
11
12
Util . Init ( async ( ) => {
12
13
// reader client.crt
13
14
const cert = await fs . readFile ( path . join ( process . env . PROJECT_ROOT , 'client.crt' ) , 'utf-8' )
@@ -25,11 +26,23 @@ Util.Init(async () => {
25
26
//random challenge 32 bytes
26
27
verifyCertificateUnidirectional . diagSetParameter ( 'lengthOfChallengeClient' , 32 )
27
28
verifyCertificateUnidirectional . diagSetParameterSize ( 'challengeClient' , 32 * 8 )
28
- verifyCertificateUnidirectional . diagSetParameterRaw ( 'challengeClient' , challenge )
29
+ verifyCertificateUnidirectional . diagSetParameterRaw ( 'challengeClient' , challengeSelf )
29
30
//save
30
31
await verifyCertificateUnidirectional . changeService ( )
32
+
33
+ //read fwContent
34
+ fwContent = await fs . readFile ( path . join ( process . env . PROJECT_ROOT , 'test.txt' ) )
35
+ //setup 0x34 size
36
+ const RequestDownload520 = DiagRequest . from ( 'Tester_can_0.RequestDownload520' )
37
+ RequestDownload520 . diagSetParameter ( 'memorySize' , fwContent . length )
38
+ await RequestDownload520 . changeService ( )
31
39
} )
32
40
41
+ const ecdh = crypto . createECDH ( 'prime256v1' )
42
+ ecdh . generateKeys ( )
43
+ const publicKey = ecdh . getPublicKey ( )
44
+ let realKey : Buffer
45
+
33
46
Util . On ( 'Tester_can_0.verifyCertificateUnidirectional.recv' , async ( resp ) => {
34
47
const data = resp . diagGetRaw ( )
35
48
// 69 11 11 lengthOfCertificateClient(2)
@@ -47,6 +60,80 @@ Util.On('Tester_can_0.verifyCertificateUnidirectional.recv', async (resp) => {
47
60
proofOfOwnership . diagSetParameterSize ( 'proofOfOwnershipClient' , sign . length * 8 )
48
61
proofOfOwnership . diagSetParameterRaw ( 'proofOfOwnershipClient' , sign )
49
62
proofOfOwnership . diagSetParameter ( 'lengthOfProofOfOwnershipClient' , sign . length )
63
+
64
+ proofOfOwnership . diagSetParameter ( 'lengthOfEphemeralPublicKeyClient' , publicKey . length )
65
+ proofOfOwnership . diagSetParameterSize ( 'ephemeralPublicKeyClient' , publicKey . length * 8 )
66
+ proofOfOwnership . diagSetParameterRaw ( 'ephemeralPublicKeyClient' , publicKey )
50
67
//save
51
68
await proofOfOwnership . changeService ( )
69
+
70
+ const lengthOfPeerKey = data . readUint16BE ( 5 + lengthOfCertificateClient )
71
+ const peerPublicKey = data . subarray (
72
+ 5 + lengthOfCertificateClient + 2 ,
73
+ 5 + lengthOfCertificateClient + 2 + lengthOfPeerKey
74
+ )
75
+ console . log ( `peerPublicKey length:${ lengthOfPeerKey } ` )
76
+ const sharedSecret = ecdh . computeSecret ( peerPublicKey )
77
+ console . log ( `sharedSecret in tester:${ sharedSecret . toString ( 'hex' ) } ` )
78
+ //hkdf
79
+ const salt = Buffer . concat ( [ challengeSelf , challenge ] )
80
+ realKey = Buffer . from ( crypto . hkdfSync ( 'sha256' , sharedSecret , salt , '' , 32 ) )
81
+ console . log ( `realKey in tester:${ realKey . toString ( 'hex' ) } ` )
82
+ } )
83
+
84
+ let maxChunkSize = 0
85
+ Util . On ( 'Tester_can_0.RequestDownload520.recv' , ( resp ) => {
86
+ maxChunkSize = resp . diagGetParameterRaw ( 'maxNumberOfBlockLength' ) . readUint32BE ( 0 )
87
+ } )
88
+
89
+ //aes-gcm encrypt
90
+
91
+ Util . Register ( 'Tester_can_0.SecureDownload' , async ( ) => {
92
+ if ( maxChunkSize <= 2 ) {
93
+ throw new Error ( 'maxNumberOfBlockLength is undefined or too small' )
94
+ }
95
+ if ( fwContent ) {
96
+ const cipher = crypto . createCipheriv ( 'aes-256-gcm' , realKey , Buffer . alloc ( 12 , 0 ) )
97
+ maxChunkSize -= 2
98
+ if ( maxChunkSize & 0x07 ) {
99
+ maxChunkSize -= maxChunkSize & 0x07
100
+ }
101
+ const numChunks = Math . ceil ( fwContent . length / maxChunkSize )
102
+ const list = [ ]
103
+ for ( let i = 0 ; i < numChunks ; i ++ ) {
104
+ const start = i * maxChunkSize
105
+ const end = Math . min ( start + maxChunkSize , fwContent . length )
106
+ console . log ( `chunk ${ i + 1 } /${ numChunks } start: ${ start } , end: ${ end } ` )
107
+ const chunk = fwContent . subarray ( start , end )
108
+
109
+ const transferRequest = DiagRequest . from ( 'Tester_can_0.TransferData540' )
110
+
111
+ const encrypt = cipher . update ( chunk )
112
+ console . log (
113
+ `chunk ${ i + 1 } /${ numChunks } size: ${ chunk . length } , encrypted size: ${ encrypt . length } `
114
+ )
115
+ transferRequest . diagSetParameterSize ( 'transferRequestParameterRecord' , encrypt . length * 8 )
116
+ // 设置传输请求参数记录
117
+ transferRequest . diagSetParameterRaw ( 'transferRequestParameterRecord' , encrypt )
118
+
119
+ // 计算块序号 (从1开始)
120
+ const blockSequenceCounter = Buffer . alloc ( 1 )
121
+ blockSequenceCounter . writeUInt8 ( ( i + 1 ) & 0xff ) // 使用循环计数 1-255
122
+ transferRequest . diagSetParameterRaw ( 'blockSequenceCounter' , blockSequenceCounter )
123
+
124
+ list . push ( transferRequest )
125
+ }
126
+ //set auth tag
127
+ cipher . final ( )
128
+ const authTag = cipher . getAuthTag ( )
129
+ const RequestTransferExit550 = DiagRequest . from ( 'Tester_can_0.RequestTransferExit550' )
130
+ RequestTransferExit550 . diagSetParameterSize ( 'auth' , authTag . length * 8 )
131
+ // 设置传输请求参数记录
132
+ RequestTransferExit550 . diagSetParameterRaw ( 'auth' , authTag )
133
+ await RequestTransferExit550 . changeService ( )
134
+ // 发送所有块
135
+ return list
136
+ } else {
137
+ return [ ]
138
+ }
52
139
} )
0 commit comments