19
19
#include " ArduinoOTA.h"
20
20
#include " NetworkClient.h"
21
21
#include " ESPmDNS.h"
22
- #include " MD5Builder .h"
22
+ #include " SHA3Builder .h"
23
23
#include " Update.h"
24
24
25
25
// #define OTA_DEBUG Serial
@@ -72,12 +72,12 @@ String ArduinoOTAClass::getHostname() {
72
72
73
73
ArduinoOTAClass &ArduinoOTAClass::setPassword (const char *password) {
74
74
if (_state == OTA_IDLE && password) {
75
- MD5Builder passmd5 ;
76
- passmd5 .begin ();
77
- passmd5 .add (password);
78
- passmd5 .calculate ();
75
+ SHA3Builder passsha3 ;
76
+ passsha3 .begin ();
77
+ passsha3 .add (password);
78
+ passsha3 .calculate ();
79
79
_password.clear ();
80
- _password = passmd5 .toString ();
80
+ _password = passsha3 .toString ();
81
81
}
82
82
return *this ;
83
83
}
@@ -188,17 +188,17 @@ void ArduinoOTAClass::_onRx() {
188
188
_udp_ota.read ();
189
189
_md5 = readStringUntil (' \n ' );
190
190
_md5.trim ();
191
- if (_md5.length () != 32 ) {
191
+ if (_md5.length () != 32 ) { // MD5 produces 32 character hex string for firmware integrity
192
192
log_e (" bad md5 length" );
193
193
return ;
194
194
}
195
195
196
196
if (_password.length ()) {
197
- MD5Builder nonce_md5 ;
198
- nonce_md5 .begin ();
199
- nonce_md5 .add (String (micros ()));
200
- nonce_md5 .calculate ();
201
- _nonce = nonce_md5 .toString ();
197
+ SHA3Builder nonce_sha3 ;
198
+ nonce_sha3 .begin ();
199
+ nonce_sha3 .add (String (micros ()));
200
+ nonce_sha3 .calculate ();
201
+ _nonce = nonce_sha3 .toString ();
202
202
203
203
_udp_ota.beginPacket (_udp_ota.remoteIP (), _udp_ota.remotePort ());
204
204
_udp_ota.printf (" AUTH %s" , _nonce.c_str ());
@@ -222,18 +222,26 @@ void ArduinoOTAClass::_onRx() {
222
222
_udp_ota.read ();
223
223
String cnonce = readStringUntil (' ' );
224
224
String response = readStringUntil (' \n ' );
225
- if (cnonce.length () != 32 || response.length () != 32 ) {
225
+ if (cnonce.length () != 64 || response.length () != 64 ) { // SHA3-256 produces 64 character hex string
226
226
log_e (" auth param fail" );
227
227
_state = OTA_IDLE;
228
228
return ;
229
229
}
230
230
231
231
String challenge = _password + " :" + String (_nonce) + " :" + cnonce;
232
- MD5Builder _challengemd5;
233
- _challengemd5.begin ();
234
- _challengemd5.add (challenge);
235
- _challengemd5.calculate ();
236
- String result = _challengemd5.toString ();
232
+ SHA3Builder _challengesha3;
233
+ _challengesha3.begin ();
234
+ _challengesha3.add (challenge);
235
+ _challengesha3.calculate ();
236
+ String result = _challengesha3.toString ();
237
+
238
+ // Debug logging
239
+ log_d (" Challenge: %s" , challenge.c_str ());
240
+ log_d (" Expected: %s" , result.c_str ());
241
+ log_d (" Received: %s" , response.c_str ());
242
+ log_d (" Password hash: %s" , _password.c_str ());
243
+ log_d (" Nonce: %s" , _nonce.c_str ());
244
+ log_d (" CNonce: %s" , cnonce.c_str ());
237
245
238
246
if (result.equals (response)) {
239
247
_udp_ota.beginPacket (_udp_ota.remoteIP (), _udp_ota.remotePort ());
@@ -266,7 +274,7 @@ void ArduinoOTAClass::_runUpdate() {
266
274
_state = OTA_IDLE;
267
275
return ;
268
276
}
269
- Update.setMD5 (_md5.c_str ());
277
+ Update.setMD5 (_md5.c_str ()); // Note: Update library still uses MD5 for firmware integrity, this is separate from authentication
270
278
271
279
if (_start_callback) {
272
280
_start_callback ();
0 commit comments