Skip to content

Commit dd6fc11

Browse files
committed
http CBC
1 parent aaf671e commit dd6fc11

File tree

5 files changed

+91
-33
lines changed

5 files changed

+91
-33
lines changed

http/README.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ESP32 Ultimate OTA (HTTP)
22
ESP32 OTA over many forms!\
3-
Crypted functions use AES-256 ECB.
3+
Crypted functions use AES-256 CBC.
44

55
WiFi library: [WiFi](https://github.com/urbanze/esp32-wifi)
66

@@ -13,32 +13,35 @@ WiFi library: [WiFi](https://github.com/urbanze/esp32-wifi)
1313

1414
## How it works?
1515
* Basically, OTA HTTP get file (MIME MEDIA bytes) sent to ESP32 and write in OTA partition.
16-
* .PROCESS() will host TCP server, wait new client in HTTP web page, wait upload file and write all new incoming bytes to OTA partition.
16+
* .PROCESS() will host HTTP/HTML server, wait new client in HTTP web page, wait upload file and write all new incoming bytes to OTA partition.
1717
* This library will write **ALL BYTES** received in MIME MEDIA. After start, your external software can't send any byte that are not from the binary file.
1818
* If you use this library in separate task, stack of 4096B should be enough.
1919
* This library can do Factory Reset (last binary burned by USB).
2020

21-
## Simple example to use HTTP (Crypto OFF)
21+
## Simple example to use OTA HTTP (Crypto OFF)
2222
```
2323
WF wifi;
2424
OTA_HTTP ota;
2525
wifi.ap_start("wifi", "1234567890");
2626
27-
ota.init(""); //Default port 80 (you can change in second param)
27+
ota.init(); //Default port 80
2828
while (1)
2929
{
3030
ota.process(); //Wait client connection (up to 1sec) and read bytes sent by client in HTTP web page.
3131
}
3232
```
3333

34-
## Simple example to use HTTP (Crypto ON)
34+
## Simple example to use OTA HTTP (Crypto ON)
3535
Insert your desired key.
3636
```
3737
WF wifi;
3838
OTA_HTTP ota;
3939
wifi.ap_start("wifi", "1234567890");
4040
41-
ota.init("1234567890"); //Default port 80 (you can change in second param)
41+
ota.init(); //Default port 80
42+
43+
//Set AES-256-CBC KEY and initial IV.
44+
ota.crypto("12345678901234567890123456789012", "0123456789012345");
4245
while (1)
4346
{
4447
ota.process(); //Wait client connection (up to 1sec) and read bytes sent by client in HTTP web page.

http/ota-http.cpp

+48-23
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void OTA_HTTP::decrypt(uint8_t *data, uint16_t size)
4343
aes_inp[i] = (j+i > size) ? 0 : data[j+i];
4444
}
4545

46-
mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_DECRYPT, aes_inp, aes_out);
46+
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, _iv, aes_inp, aes_out);
4747

4848
for (int8_t i = 0; i < 16; i++)
4949
{
@@ -116,6 +116,10 @@ void OTA_HTTP::iterator(uint8_t *data, uint16_t data_size)
116116
const esp_partition_t *ota_partition = NULL;
117117
ota_partition = esp_ota_get_next_update_partition(NULL);
118118

119+
for (uint8_t i = 0; i < 16; i++)
120+
{
121+
_iv[i] = _firstiv[i];
122+
}
119123

120124
err = esp_ota_begin(ota_partition, OTA_SIZE_UNKNOWN, &ota_handle);
121125
if (err != ESP_OK)
@@ -124,6 +128,11 @@ void OTA_HTTP::iterator(uint8_t *data, uint16_t data_size)
124128
tcp.printf("OTA begin fail [0x%x]</body></html>\r\n", err);
125129
return;
126130
}
131+
else
132+
{
133+
ESP_LOGI(tag, "OTA Started");
134+
}
135+
127136

128137

129138
//First write comming from packet read in process()
@@ -148,14 +157,15 @@ void OTA_HTTP::iterator(uint8_t *data, uint16_t data_size)
148157
//After all bytes sent, tcp.available() may not be MODULE of 16, causing infinity loop.
149158
//This instructions break if this loop occurs, removing desnecessary bytes.
150159
if (!th) {th = esp_timer_get_time();}
151-
if (esp_timer_get_time() - th < 2000000)
160+
if (esp_timer_get_time() - th > 2000000)
152161
{
153-
for (int16_t i = 0; i < (avl%16); i++)
154-
{tcp.read();}
162+
//Nothing
163+
}
164+
else
165+
{
166+
vTaskDelay(100);
167+
continue;
155168
}
156-
157-
vTaskDelay(1);
158-
continue;
159169
}
160170

161171
th = 0;//Crypted loop aux.
@@ -386,6 +396,36 @@ void OTA_HTTP::process()
386396
tcp.stop();
387397
}
388398

399+
/**
400+
* @brief Enable AES-256 CBC crypto.
401+
*
402+
* @attention IV is modified by MBEDTLS.
403+
*
404+
* @attention Key must be 32 Chars.
405+
* @attention IV must be 16 Chars.
406+
*
407+
* @param [*key]: AES key.
408+
* @param [*iv]: Initial IV.
409+
*/
410+
void OTA_HTTP::crypto(const char *key="", const char *iv="")
411+
{
412+
_cry = 0;
413+
414+
if (strlen(key) != 32) {ESP_LOGE(tag, "Key must be 32 Chars. Crypto OFF."); return;}
415+
if (strlen(iv) != 16) {ESP_LOGE(tag, "IV must be 16 Chars. Crypto OFF."); return;}
416+
417+
418+
mbedtls_aes_init(&aes);
419+
mbedtls_aes_setkey_enc(&aes, (uint8_t*)key, 256);
420+
421+
for (uint8_t i = 0; i < 16; i++)
422+
{
423+
_firstiv[i] = iv[i];
424+
}
425+
426+
_cry = 1;
427+
}
428+
389429
/**
390430
* @brief Init OTA HTTP functions.
391431
*
@@ -394,23 +434,8 @@ void OTA_HTTP::process()
394434
* @param [*key]: AES-256 ECB decrypt key (<=32 chars).
395435
* @param [port]: Port to use in HTTP web server. (eg: 8080, 80, etc)
396436
*/
397-
void OTA_HTTP::init(const char *key, uint16_t port=80)
437+
void OTA_HTTP::init(uint16_t port=80)
398438
{
399439
_port = port;
400440
host.begin(_port);
401-
402-
if (strlen(key))
403-
{
404-
char key2[32] = {0};
405-
_cry = 1;
406-
407-
strncpy(key2, key, sizeof(key2));
408-
409-
mbedtls_aes_init(&aes);
410-
mbedtls_aes_setkey_enc(&aes, (uint8_t*)key2, 256);
411-
}
412-
else
413-
{
414-
_cry = 0;
415-
}
416441
}

http/ota-http.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class OTA_HTTP
1919
private:
2020
const char tag[9] = "OTA_HTTP";
2121
int8_t _cry = 0;
22+
uint8_t _firstiv[16] = {0};
23+
uint8_t _iv[16] = {0};
2224
uint16_t _port = 80;
2325
mbedtls_aes_context aes;
2426
TCP_CLIENT tcp;
@@ -32,7 +34,8 @@ class OTA_HTTP
3234

3335

3436
public:
35-
void init(const char *key, uint16_t port);
37+
void init(uint16_t port);
38+
void crypto(const char *key, const char *iv);
3639
void process();
3740

3841

tcp/esp32-tcp/tcp.cpp

+25-2
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,17 @@ int16_t TCP_CLIENT::printf(const char *format, ...)
199199
return write((uint8_t*)bff, size);
200200
}
201201

202+
/**
203+
* @brief Send data over TCP connection.
204+
*
205+
*
206+
* @return Data wrote.
207+
*/
208+
int16_t TCP_CLIENT::print(const char *str)
209+
{
210+
return write((uint8_t*)str, strlen(str));
211+
}
212+
202213
/**
203214
* @brief Read only one Byte of data available.
204215
*
@@ -286,7 +297,8 @@ void TCP_SERVER::begin(uint16_t port)
286297
* When client connect in TCP Server, this function will return immediately and
287298
* return instance to use in TCP_CLIENT object (read/write/etc).
288299
*
289-
* See "How to use in "Github example in README.md
300+
* See "How to use" in Github example (README.md)
301+
* Attention: This function block current task.
290302
*
291303
* @param [timeout]: Max seconds to wait client connection.
292304
*
@@ -304,10 +316,11 @@ int16_t TCP_SERVER::sv(int32_t timeout)
304316
stv.tv_sec = timeout;
305317
stv.tv_usec = 0;
306318

319+
memset(rmt_ip, 0, sizeof(rmt_ip));
307320
select(max, &fds, NULL, NULL, &stv);
308321
if (FD_ISSET(s, &fds))
309322
{
310-
struct sockaddr_in6 src;
323+
struct sockaddr_in src;
311324
socklen_t src_len = sizeof(src);
312325

313326
c = accept(s, (struct sockaddr *)&src, &src_len);
@@ -316,7 +329,17 @@ int16_t TCP_SERVER::sv(int32_t timeout)
316329
ESP_LOGE(tag, "Fail to accept socket connections [%d]", errno);
317330
close(s);
318331
}
332+
333+
inet_ntop(AF_INET, &src.sin_addr , rmt_ip, sizeof(rmt_ip));
319334
}
320335

321336
return c;
337+
}
338+
339+
/**
340+
* @brief Get source IP from last received packet.
341+
*/
342+
char *TCP_SERVER::remoteIP()
343+
{
344+
return rmt_ip;
322345
}

tcp/esp32-tcp/tcp.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class TCP_CLIENT
7171

7272
int16_t write(uint8_t *data, uint16_t size);
7373
int16_t printf(const char *format, ...);
74+
int16_t print(const char *str);
7475

7576
uint8_t read();
7677
void readBytes(uint8_t *bff, uint16_t size);
@@ -83,13 +84,16 @@ class TCP_SERVER
8384
private:
8485
const char tag[11] = "TCP_SERVER";
8586
int s = 0;
87+
char rmt_ip[16] = {0};
8688

8789
public:
8890
~TCP_SERVER();
8991

9092
void begin(uint16_t port);
9193
int16_t sv(int32_t timeout);
94+
char *remoteIP();
95+
9296
};
9397

9498

95-
#endif
99+
#endif

0 commit comments

Comments
 (0)