-
Notifications
You must be signed in to change notification settings - Fork 2
/
GetKey.ino
175 lines (124 loc) · 6.65 KB
/
GetKey.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Negotiation key functions
/*
In order to command a device, we need to negotiate to obtain a key
=> Send msg 1 with local nonce 0123456789abcdef crypted using device key Cmd = 03 Negotiate session key
<= Receive msg whith remote nonce xxxxxxxxxxxxxxxx crypted using device key
=> Send msg 2 with remote nonce xxxxxxxxxxxxxxxx crypted using device key : Cmd = 05 Finalize session key negotiation (no response expected)
<= Receive No msg
= Compute new key for future messasges
XOR between local nonce and remote nonce
Crypt result using device key
=> New Xor-key => Once you get it, you can send commands to the devices (status, turn On/Off...)
*/
//--------------------------------------------------
void getKey( ){
ret = 0;
//----------------------- Begin Get Key
Serial.println();
Serial.println("===== Get Key =====");
Serial.println(); t1 = millis();
DEBUG_PRINTLN("-- Send Command 1 : Request remote nonce --");
ret = reqRemNonce( ) ;
DEBUG_PRINT("Remote_nonce : " ); p5( remote_nonce, 16 );
if ( ret ) {
DEBUG_PRINTLN();
DEBUG_PRINTLN("-- Send Command 2 : Finalize/acknowledge --");
ret = finalizeRemNonce();
// Generate XOR Key (Xor fonction byte par byte between local and remote nonce + crypt )
genXORkey();
}
DEBUG_PRINTLN();
DEBUG_PRINTLN("===== Fin Get Key =====");
}
//--------------------------------------------------
int reqRemNonce( ) { //-- Send Command 1 : Request remote nonce --
// Command 03 : Negotiate session key
byte m1p34[] = { 0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x44 } ;
byte m1a35[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2c } ;
memcpy ( Tmes.Pload, local_nonce, KEY_LENGTH ); // Payload = local_nonce 012...
Lmes.PloadL = KEY_LENGTH ;
if ( dev.vers == 4 ) {
padPload( ) ;
encrypt_v34( Tmes.Pload, dev.key, Lmes.PloadL) ;
//------------ Formating output message
outMsgL = 0 ;
addTooutMsg( m1p34, sizeof( m1p34 ) ) ; // Prefix
addTooutMsg( Tmes.Pload, Lmes.PloadL ) ; // Pload
//------------ Compute SHA256Key on Prefix + pload
genSHA256Key( dev.key, outMsg, SHA256Key, 48 );
//------------ Finalize Message
addTooutMsg( SHA256Key, SHA256HMAC_SIZE ) ; // add CRC
addTooutMsg( Suf34, sizeof(Suf34) ) ; // Add Suffix
}
if ( dev.vers == 5 ) {
memcpy( wIV, Tmes.Pload, 12 ) ; // IV = first 12c (local_nonce)
encrypt_v35( Tmes.Pload, dev.key, wIV, Lmes.PloadL, m1a35, 14 ) ;
//--------------- Format message
outMsgL = 0 ;
addTooutMsg( head66, sizeof( head66 ) ) ; // Heading
addTooutMsg( m1a35, sizeof( m1a35 ) ) ; // Prefix
addTooutMsg( wIV, sizeof( wIV ) ) ; // Initial Vector
addTooutMsg(Tmes.Pload, Lmes.PloadL ) ; // Pload
addTooutMsg( wTag, sizeof( wTag ) ) ; // Tag
addTooutMsg( Suf35, sizeof( Suf35 ) ) ; // Suffix
}
DEBUG_PRINTLN("Message 1 : " ); p5( outMsg, outMsgL );
//----------------------- Send message
sendMsg( outMsg, outMsgL ) ;
//----------------------- Receive response
int ret = receiveMsg( ) ;
Lmes.TotL = ret ;
InitLmes( 'M' ); // Init Message structure ( length)
memcpy( crypt_key, dev.key, 16 ) ; // We use Device decrypt Key
parse_header();
parse_suffix();
getPayload();
DumpMsg() ;
memcpy( remote_nonce, Tmes.Pload, 16) ; // Get remote_nonce
return 16 ;
}
//--------------------------------------------------
int finalizeRemNonce() { //-- Send Command 2 : Request remote nonce --
// Command 05 Finalize session key negotiation
byte Pref34[] = { 0x00, 0x00, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x54 } ;
byte m2a35[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c } ;
// Compute SHA256Key on remote_nonce with device key
genSHA256Key( dev.key, remote_nonce, SHA256Key, KEY_LENGTH );
//------------ Create Pload
memcpy( Tmes.Pload, SHA256Key, SHA256HMAC_SIZE ) ;
Lmes.PloadL = SHA256HMAC_SIZE ;
if ( dev.vers == 4 ) {
// m2l = 100;
for ( int i = 0 ; i < 16; i++ ) { Tmes.Pload[Lmes.PloadL] = 0x10 ; Lmes.PloadL = Lmes.PloadL + 1; } // Extend to from 32 to 48c
//------------ Crypt pload with Device key
encrypt_v34( Tmes.Pload, dev.key, 48 );
//------------ Formating output message
outMsgL = 0 ;
addTooutMsg( Pref34, sizeof( Pref34 ) ) ; // Prefix
addTooutMsg( Tmes.Pload, Lmes.PloadL ) ; // add Pload
//------------ Compute SHA256Key on Prefix + pload
genSHA256Key( dev.key, outMsg, SHA256Key, 64 );
//------------ Finalize Message
addTooutMsg( SHA256Key, SHA256HMAC_SIZE ) ; // add CRC
addTooutMsg( Suf34, sizeof(Suf34) ) ; // add Suffix
}
if ( dev.vers == 5 ) {
memcpy( wIV, local_nonce, 12 ) ; // IV = first 12c (local_nonce)
encrypt_v35( Tmes.Pload, dev.key, wIV, Lmes.PloadL, m2a35, 14 ) ,
//--------------- Format message
outMsgL = 0 ;
addTooutMsg( head66, sizeof( head66 ) ) ; // Heading
addTooutMsg( m2a35, sizeof( m2a35 ) ) ; // Prefix
addTooutMsg( wIV, sizeof( wIV ) ) ; // IV
addTooutMsg(Tmes.Pload, Lmes.PloadL ) ; // add Pload
addTooutMsg( wTag, sizeof( wTag ) ) ; // add Tag
addTooutMsg( Suf35, sizeof( Suf35 ) ) ; // add Suffix
}
DEBUG_PRINTLN("----------------------");
DEBUG_PRINT("outMsg 2 : " ); p5( outMsg, outMsgL );
DEBUG_PRINTLN("----------------------");
//----------------------- Send messagea acknowledge
sendMsg( outMsg, outMsgL );
// Don't expect any response
return outMsgL ;
}