Aktualizace na verzi 2.10.5

This commit is contained in:
Pavel Brychta 2024-06-06 10:17:05 +02:00
parent 50909fd3cf
commit ea4b7d415c
11 changed files with 435 additions and 77 deletions

View File

@ -36,7 +36,8 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo
Usage and API stays the same as the original library. Usage and API stays the same as the original library.
Please look at the original libraries for more examples and documentation. Please look at the original libraries for more examples and documentation.
[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) - [https://github.com/me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) (original library)
- [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) (fork of the original library)
## `AsyncWebSocketMessageBuffer` and `makeBuffer()` ## `AsyncWebSocketMessageBuffer` and `makeBuffer()`
@ -44,9 +45,8 @@ The fork from `yubox-node-org` introduces some breaking API changes compared to
This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class. This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class.
So you have the choice of which API to use. So you have the choice of which API to use.
I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient.
Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized: Here are examples for serializing a Json document in a websocket message buffer:
```cpp ```cpp
void send(JsonDocument& doc) { void send(JsonDocument& doc) {
@ -60,28 +60,31 @@ void send(JsonDocument& doc) {
} }
``` ```
Here is an example for serializing a Json document in a more optimized way, and compatible with both forks:
```cpp ```cpp
void send(JsonDocument& doc) { void send(JsonDocument& doc) {
const size_t len = measureJson(doc); const size_t len = measureJson(doc);
#if defined(ASYNCWEBSERVER_FORK_mathieucarbou) // this fork (originally from yubox-node-org), uses another API with shared pointer
// this fork (originally from yubox-node-org), uses another API with shared pointer that better support concurrent use cases then the original project
auto buffer = std::make_shared<std::vector<uint8_t>>(len); auto buffer = std::make_shared<std::vector<uint8_t>>(len);
assert(buffer); // up to you to keep or remove this assert(buffer); // up to you to keep or remove this
serializeJson(doc, buffer->data(), len); serializeJson(doc, buffer->data(), len);
_ws->textAll(std::move(buffer)); _ws->textAll(std::move(buffer));
#else
// original API from me-no-dev
AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len);
assert(buffer); // up to you to keep or remove this
serializeJson(doc, buffer->get(), len);
_ws->textAll(buffer);
#endif
} }
``` ```
I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility.
## Stack size and queues
Here are some important flags to tweak depending on your needs:
```cpp
// Async TCP queue size
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128
// Async TCP async task core
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1
// Async TCP async stac ksize
-D CONFIG_ASYNC_TCP_STACK_SIZE=8096
// WebSocket queue size
-D WS_MAX_QUEUED_MESSAGES=64
```

View File

@ -36,7 +36,8 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo
Usage and API stays the same as the original library. Usage and API stays the same as the original library.
Please look at the original libraries for more examples and documentation. Please look at the original libraries for more examples and documentation.
[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) - [https://github.com/me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) (original library)
- [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) (fork of the original library)
## `AsyncWebSocketMessageBuffer` and `makeBuffer()` ## `AsyncWebSocketMessageBuffer` and `makeBuffer()`
@ -44,9 +45,8 @@ The fork from `yubox-node-org` introduces some breaking API changes compared to
This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class. This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class.
So you have the choice of which API to use. So you have the choice of which API to use.
I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient.
Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized: Here are examples for serializing a Json document in a websocket message buffer:
```cpp ```cpp
void send(JsonDocument& doc) { void send(JsonDocument& doc) {
@ -60,28 +60,31 @@ void send(JsonDocument& doc) {
} }
``` ```
Here is an example for serializing a Json document in a more optimized way, and compatible with both forks:
```cpp ```cpp
void send(JsonDocument& doc) { void send(JsonDocument& doc) {
const size_t len = measureJson(doc); const size_t len = measureJson(doc);
#if defined(ASYNCWEBSERVER_FORK_mathieucarbou) // this fork (originally from yubox-node-org), uses another API with shared pointer
// this fork (originally from yubox-node-org), uses another API with shared pointer that better support concurrent use cases then the original project
auto buffer = std::make_shared<std::vector<uint8_t>>(len); auto buffer = std::make_shared<std::vector<uint8_t>>(len);
assert(buffer); // up to you to keep or remove this assert(buffer); // up to you to keep or remove this
serializeJson(doc, buffer->data(), len); serializeJson(doc, buffer->data(), len);
_ws->textAll(std::move(buffer)); _ws->textAll(std::move(buffer));
#else
// original API from me-no-dev
AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len);
assert(buffer); // up to you to keep or remove this
serializeJson(doc, buffer->get(), len);
_ws->textAll(buffer);
#endif
} }
``` ```
I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility.
## Stack size and queues
Here are some important flags to tweak depending on your needs:
```cpp
// Async TCP queue size
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128
// Async TCP async task core
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1
// Async TCP async stac ksize
-D CONFIG_ASYNC_TCP_STACK_SIZE=8096
// WebSocket queue size
-D WS_MAX_QUEUED_MESSAGES=64
```

37
examples/Draft/Draft.ino Normal file
View File

@ -0,0 +1,37 @@
#include <Arduino.h>
#include <MD5Builder.h>
#include "mbedtls/md5.h"
void setup() {
Serial.begin(115200);
delay(2000);
const char* data = "Hello World";
{
uint8_t md5[16];
mbedtls_md5_context _ctx;
mbedtls_md5_init(&_ctx);
mbedtls_md5_starts(&_ctx);
mbedtls_md5_update(&_ctx, (const unsigned char*)data, strlen(data));
mbedtls_md5_finish(&_ctx, md5);
char output[33];
for (int i = 0; i < 16; i++) {
sprintf_P(output + (i * 2), PSTR("%02x"), md5[i]);
}
Serial.println(String(output));
}
{
MD5Builder md5;
md5.begin();
md5.add(data, strlen(data);
md5.calculate();
char output[33];
md5.getChars(output);
Serial.println(String(output));
}
}
void loop() {
}

View File

@ -1,6 +1,6 @@
{ {
"name": "ESP Async WebServer", "name": "ESP Async WebServer",
"version": "2.10.4", "version": "2.10.5",
"description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.",
"keywords": "http,async,websocket,webserver", "keywords": "http,async,websocket,webserver",
"homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer",

View File

@ -1,5 +1,5 @@
name=ESP Async WebServer name=ESP Async WebServer
version=2.10.4 version=2.10.5
author=Me-No-Dev author=Me-No-Dev
maintainer=Mathieu Carbou <mathieu.carbou@gmail.com> maintainer=Mathieu Carbou <mathieu.carbou@gmail.com>
sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 sentence=Asynchronous HTTP and WebSocket Server Library for ESP32

View File

@ -16,10 +16,11 @@ monitor_filters = esp32_exception_decoder, log2file
[platformio] [platformio]
lib_dir = . lib_dir = .
; src_dir = examples/CaptivePortal src_dir = examples/CaptivePortal
; src_dir = examples/SimpleServer ; src_dir = examples/SimpleServer
src_dir = examples/StreamFiles ; src_dir = examples/StreamFiles
; src_dir = examples/Filters ; src_dir = examples/Filters
; src_dir = examples/Draft
[env:arduino] [env:arduino]
platform = espressif32 platform = espressif32
@ -32,8 +33,8 @@ board = esp32dev
[env:arduino-3] [env:arduino-3]
platform = espressif32 platform = espressif32
platform_packages= platform_packages=
platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0 platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1
platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip
board = esp32dev board = esp32dev
[env:esp8266] [env:esp8266]

View File

@ -26,7 +26,11 @@
#include <libb64/cencode.h> #include <libb64/cencode.h>
#ifndef ESP8266 #ifndef ESP8266
#include "mbedtls/sha1.h" #if ESP_IDF_VERSION_MAJOR < 5
#include "./port/SHA1Builder.h"
#else
#include <SHA1Builder.h>
#endif
#include <rom/ets_sys.h> #include <rom/ets_sys.h>
#else #else
#include <Hash.h> #include <Hash.h>
@ -1305,19 +1309,12 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket
#ifdef ESP8266 #ifdef ESP8266
sha1(key + WS_STR_UUID, hash); sha1(key + WS_STR_UUID, hash);
#else #else
(String&)key += WS_STR_UUID; String k = key + WS_STR_UUID;
mbedtls_sha1_context ctx; SHA1Builder sha1;
mbedtls_sha1_init(&ctx); sha1.begin();
#if ESP_IDF_VERSION_MAJOR == 5 sha1.add((const uint8_t*)k.c_str(), k.length());
mbedtls_sha1_starts(&ctx); sha1.calculate();
mbedtls_sha1_update(&ctx, (const unsigned char*)key.c_str(), key.length()); sha1.getBytes(hash);
mbedtls_sha1_finish(&ctx, hash);
#else
mbedtls_sha1_starts_ret(&ctx);
mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length());
mbedtls_sha1_finish_ret(&ctx, hash);
#endif
mbedtls_sha1_free(&ctx);
#endif #endif
base64_encodestate _state; base64_encodestate _state;
base64_init_encodestate(&_state); base64_init_encodestate(&_state);

View File

@ -40,10 +40,10 @@
#error Platform not supported #error Platform not supported
#endif #endif
#define ASYNCWEBSERVER_VERSION "2.10.4" #define ASYNCWEBSERVER_VERSION "2.10.5"
#define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MAJOR 2
#define ASYNCWEBSERVER_VERSION_MINOR 10 #define ASYNCWEBSERVER_VERSION_MINOR 10
#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_VERSION_REVISION 5
#define ASYNCWEBSERVER_FORK_mathieucarbou #define ASYNCWEBSERVER_FORK_mathieucarbou
#ifdef ASYNCWEBSERVER_REGEX #ifdef ASYNCWEBSERVER_REGEX

View File

@ -21,7 +21,7 @@
#include "WebAuthentication.h" #include "WebAuthentication.h"
#include <libb64/cencode.h> #include <libb64/cencode.h>
#ifdef ESP32 #ifdef ESP32
#include "mbedtls/md5.h" #include <MD5Builder.h>
#else #else
#include "md5.h" #include "md5.h"
#endif #endif
@ -66,35 +66,29 @@ bool checkBasicAuthentication(const char * hash, const char * username, const ch
static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or more static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or more
#ifdef ESP32 #ifdef ESP32
mbedtls_md5_context _ctx; MD5Builder md5;
md5.begin();
md5.add(data, len);
md5.calculate();
md5.getChars(output);
#else #else
md5_context_t _ctx; md5_context_t _ctx;
#endif
uint8_t i;
uint8_t * _buf = (uint8_t*)malloc(16); uint8_t * _buf = (uint8_t*)malloc(16);
if(_buf == NULL) if(_buf == NULL)
return false; return false;
memset(_buf, 0x00, 16); memset(_buf, 0x00, 16);
#ifdef ESP32
mbedtls_md5_init(&_ctx);
#if ESP_IDF_VERSION_MAJOR == 5
mbedtls_md5_starts(&_ctx);
mbedtls_md5_update(&_ctx, data, len);
mbedtls_md5_finish(&_ctx, _buf);
#else
mbedtls_md5_starts_ret(&_ctx);
mbedtls_md5_update_ret(&_ctx, data, len);
mbedtls_md5_finish_ret(&_ctx, _buf);
#endif
#else
MD5Init(&_ctx); MD5Init(&_ctx);
MD5Update(&_ctx, data, len); MD5Update(&_ctx, data, len);
MD5Final(_buf, &_ctx); MD5Final(_buf, &_ctx);
#endif
for(i = 0; i < 16; i++) { for(uint8_t i = 0; i < 16; i++) {
sprintf_P(output + (i * 2), PSTR("%02x"), _buf[i]); sprintf_P(output + (i * 2), PSTR("%02x"), _buf[i]);
} }
free(_buf); free(_buf);
#endif
return true; return true;
} }

284
src/port/SHA1Builder.cpp Normal file
View File

@ -0,0 +1,284 @@
/*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
* Modified for esp32 by Lucas Saavedra Vaz on 11 Jan 2024
*/
#include <Arduino.h>
#if ESP_IDF_VERSION_MAJOR < 5
#include "SHA1Builder.h"
// 32-bit integer manipulation macros (big endian)
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n, b, i) \
{ (n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); }
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n, b, i) \
{ \
(b)[(i)] = (uint8_t)((n) >> 24); \
(b)[(i) + 1] = (uint8_t)((n) >> 16); \
(b)[(i) + 2] = (uint8_t)((n) >> 8); \
(b)[(i) + 3] = (uint8_t)((n)); \
}
#endif
// Constants
static const uint8_t sha1_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// Private methods
void SHA1Builder::process(const uint8_t *data) {
uint32_t temp, W[16], A, B, C, D, E;
GET_UINT32_BE(W[0], data, 0);
GET_UINT32_BE(W[1], data, 4);
GET_UINT32_BE(W[2], data, 8);
GET_UINT32_BE(W[3], data, 12);
GET_UINT32_BE(W[4], data, 16);
GET_UINT32_BE(W[5], data, 20);
GET_UINT32_BE(W[6], data, 24);
GET_UINT32_BE(W[7], data, 28);
GET_UINT32_BE(W[8], data, 32);
GET_UINT32_BE(W[9], data, 36);
GET_UINT32_BE(W[10], data, 40);
GET_UINT32_BE(W[11], data, 44);
GET_UINT32_BE(W[12], data, 48);
GET_UINT32_BE(W[13], data, 52);
GET_UINT32_BE(W[14], data, 56);
GET_UINT32_BE(W[15], data, 60);
#define sha1_S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define sha1_R(t) (temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], (W[t & 0x0F] = sha1_S(temp, 1)))
#define sha1_P(a, b, c, d, e, x) \
{ \
e += sha1_S(a, 5) + sha1_F(b, c, d) + sha1_K + x; \
b = sha1_S(b, 30); \
}
A = state[0];
B = state[1];
C = state[2];
D = state[3];
E = state[4];
#define sha1_F(x, y, z) (z ^ (x & (y ^ z)))
#define sha1_K 0x5A827999
sha1_P(A, B, C, D, E, W[0]);
sha1_P(E, A, B, C, D, W[1]);
sha1_P(D, E, A, B, C, W[2]);
sha1_P(C, D, E, A, B, W[3]);
sha1_P(B, C, D, E, A, W[4]);
sha1_P(A, B, C, D, E, W[5]);
sha1_P(E, A, B, C, D, W[6]);
sha1_P(D, E, A, B, C, W[7]);
sha1_P(C, D, E, A, B, W[8]);
sha1_P(B, C, D, E, A, W[9]);
sha1_P(A, B, C, D, E, W[10]);
sha1_P(E, A, B, C, D, W[11]);
sha1_P(D, E, A, B, C, W[12]);
sha1_P(C, D, E, A, B, W[13]);
sha1_P(B, C, D, E, A, W[14]);
sha1_P(A, B, C, D, E, W[15]);
sha1_P(E, A, B, C, D, sha1_R(16));
sha1_P(D, E, A, B, C, sha1_R(17));
sha1_P(C, D, E, A, B, sha1_R(18));
sha1_P(B, C, D, E, A, sha1_R(19));
#undef sha1_K
#undef sha1_F
#define sha1_F(x, y, z) (x ^ y ^ z)
#define sha1_K 0x6ED9EBA1
sha1_P(A, B, C, D, E, sha1_R(20));
sha1_P(E, A, B, C, D, sha1_R(21));
sha1_P(D, E, A, B, C, sha1_R(22));
sha1_P(C, D, E, A, B, sha1_R(23));
sha1_P(B, C, D, E, A, sha1_R(24));
sha1_P(A, B, C, D, E, sha1_R(25));
sha1_P(E, A, B, C, D, sha1_R(26));
sha1_P(D, E, A, B, C, sha1_R(27));
sha1_P(C, D, E, A, B, sha1_R(28));
sha1_P(B, C, D, E, A, sha1_R(29));
sha1_P(A, B, C, D, E, sha1_R(30));
sha1_P(E, A, B, C, D, sha1_R(31));
sha1_P(D, E, A, B, C, sha1_R(32));
sha1_P(C, D, E, A, B, sha1_R(33));
sha1_P(B, C, D, E, A, sha1_R(34));
sha1_P(A, B, C, D, E, sha1_R(35));
sha1_P(E, A, B, C, D, sha1_R(36));
sha1_P(D, E, A, B, C, sha1_R(37));
sha1_P(C, D, E, A, B, sha1_R(38));
sha1_P(B, C, D, E, A, sha1_R(39));
#undef sha1_K
#undef sha1_F
#define sha1_F(x, y, z) ((x & y) | (z & (x | y)))
#define sha1_K 0x8F1BBCDC
sha1_P(A, B, C, D, E, sha1_R(40));
sha1_P(E, A, B, C, D, sha1_R(41));
sha1_P(D, E, A, B, C, sha1_R(42));
sha1_P(C, D, E, A, B, sha1_R(43));
sha1_P(B, C, D, E, A, sha1_R(44));
sha1_P(A, B, C, D, E, sha1_R(45));
sha1_P(E, A, B, C, D, sha1_R(46));
sha1_P(D, E, A, B, C, sha1_R(47));
sha1_P(C, D, E, A, B, sha1_R(48));
sha1_P(B, C, D, E, A, sha1_R(49));
sha1_P(A, B, C, D, E, sha1_R(50));
sha1_P(E, A, B, C, D, sha1_R(51));
sha1_P(D, E, A, B, C, sha1_R(52));
sha1_P(C, D, E, A, B, sha1_R(53));
sha1_P(B, C, D, E, A, sha1_R(54));
sha1_P(A, B, C, D, E, sha1_R(55));
sha1_P(E, A, B, C, D, sha1_R(56));
sha1_P(D, E, A, B, C, sha1_R(57));
sha1_P(C, D, E, A, B, sha1_R(58));
sha1_P(B, C, D, E, A, sha1_R(59));
#undef sha1_K
#undef sha1_F
#define sha1_F(x, y, z) (x ^ y ^ z)
#define sha1_K 0xCA62C1D6
sha1_P(A, B, C, D, E, sha1_R(60));
sha1_P(E, A, B, C, D, sha1_R(61));
sha1_P(D, E, A, B, C, sha1_R(62));
sha1_P(C, D, E, A, B, sha1_R(63));
sha1_P(B, C, D, E, A, sha1_R(64));
sha1_P(A, B, C, D, E, sha1_R(65));
sha1_P(E, A, B, C, D, sha1_R(66));
sha1_P(D, E, A, B, C, sha1_R(67));
sha1_P(C, D, E, A, B, sha1_R(68));
sha1_P(B, C, D, E, A, sha1_R(69));
sha1_P(A, B, C, D, E, sha1_R(70));
sha1_P(E, A, B, C, D, sha1_R(71));
sha1_P(D, E, A, B, C, sha1_R(72));
sha1_P(C, D, E, A, B, sha1_R(73));
sha1_P(B, C, D, E, A, sha1_R(74));
sha1_P(A, B, C, D, E, sha1_R(75));
sha1_P(E, A, B, C, D, sha1_R(76));
sha1_P(D, E, A, B, C, sha1_R(77));
sha1_P(C, D, E, A, B, sha1_R(78));
sha1_P(B, C, D, E, A, sha1_R(79));
#undef sha1_K
#undef sha1_F
state[0] += A;
state[1] += B;
state[2] += C;
state[3] += D;
state[4] += E;
}
// Public methods
void SHA1Builder::begin(void) {
total[0] = 0;
total[1] = 0;
state[0] = 0x67452301;
state[1] = 0xEFCDAB89;
state[2] = 0x98BADCFE;
state[3] = 0x10325476;
state[4] = 0xC3D2E1F0;
memset(buffer, 0x00, sizeof(buffer));
memset(hash, 0x00, sizeof(hash));
}
void SHA1Builder::add(const uint8_t *data, size_t len) {
size_t fill;
uint32_t left;
if (len == 0) {
return;
}
left = total[0] & 0x3F;
fill = 64 - left;
total[0] += (uint32_t)len;
total[0] &= 0xFFFFFFFF;
if (total[0] < (uint32_t)len) {
total[1]++;
}
if (left && len >= fill) {
memcpy((void *)(buffer + left), data, fill);
process(buffer);
data += fill;
len -= fill;
left = 0;
}
while (len >= 64) {
process(data);
data += 64;
len -= 64;
}
if (len > 0) {
memcpy((void *)(buffer + left), data, len);
}
}
void SHA1Builder::calculate(void) {
uint32_t last, padn;
uint32_t high, low;
uint8_t msglen[8];
high = (total[0] >> 29) | (total[1] << 3);
low = (total[0] << 3);
PUT_UINT32_BE(high, msglen, 0);
PUT_UINT32_BE(low, msglen, 4);
last = total[0] & 0x3F;
padn = (last < 56) ? (56 - last) : (120 - last);
add((uint8_t *)sha1_padding, padn);
add(msglen, 8);
PUT_UINT32_BE(state[0], hash, 0);
PUT_UINT32_BE(state[1], hash, 4);
PUT_UINT32_BE(state[2], hash, 8);
PUT_UINT32_BE(state[3], hash, 12);
PUT_UINT32_BE(state[4], hash, 16);
}
void SHA1Builder::getBytes(uint8_t *output) {
memcpy(output, hash, SHA1_HASH_SIZE);
}
#endif // ESP_IDF_VERSION_MAJOR < 5

39
src/port/SHA1Builder.h Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SHA1Builder_h
#define SHA1Builder_h
#include <Stream.h>
#include <WString.h>
#define SHA1_HASH_SIZE 20
class SHA1Builder {
private:
uint32_t total[2]; /* number of bytes processed */
uint32_t state[5]; /* intermediate digest state */
unsigned char buffer[64]; /* data block being processed */
uint8_t hash[SHA1_HASH_SIZE]; /* SHA-1 result */
void process(const uint8_t* data);
public:
void begin();
void add(const uint8_t* data, size_t len);
void calculate();
void getBytes(uint8_t* output);
};
#endif // SHA1Builder_h