Skip to content

Commit 81663f5

Browse files
committed
Add SHA1Builder
1 parent 289f59d commit 81663f5

File tree

4 files changed

+517
-1
lines changed

4 files changed

+517
-1
lines changed

Diff for: CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ set(CORE_SRCS
5050
cores/esp32/Esp.cpp
5151
cores/esp32/FunctionalInterrupt.cpp
5252
cores/esp32/HardwareSerial.cpp
53+
cores/esp32/HEXBuilder.cpp
5354
cores/esp32/IPAddress.cpp
5455
cores/esp32/IPv6Address.cpp
5556
cores/esp32/libb64/cdecode.c
5657
cores/esp32/libb64/cencode.c
5758
cores/esp32/main.cpp
5859
cores/esp32/MD5Builder.cpp
59-
cores/esp32/HEXBuilder.cpp
6060
cores/esp32/Print.cpp
61+
cores/esp32/SHA1Builder.cpp
6162
cores/esp32/stdlib_noniso.c
6263
cores/esp32/Stream.cpp
6364
cores/esp32/StreamString.cpp

Diff for: cores/esp32/SHA1Builder.cpp

+367
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
/*
2+
* FIPS-180-1 compliant SHA-1 implementation
3+
*
4+
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
* not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*
19+
* This file is part of mbed TLS (https://tls.mbed.org)
20+
* Modified for esp32 by Lucas Saavedra Vaz on 11 Jan 2024
21+
*/
22+
23+
#include <Arduino.h>
24+
#include <SHA1Builder.h>
25+
26+
// 32-bit integer manipulation macros (big endian)
27+
28+
#ifndef GET_UINT32_BE
29+
#define GET_UINT32_BE(n,b,i) \
30+
{ \
31+
(n) = ((uint32_t) (b)[(i) ] << 24) \
32+
| ((uint32_t) (b)[(i) + 1] << 16) \
33+
| ((uint32_t) (b)[(i) + 2] << 8) \
34+
| ((uint32_t) (b)[(i) + 3] ); \
35+
}
36+
#endif
37+
38+
#ifndef PUT_UINT32_BE
39+
#define PUT_UINT32_BE(n,b,i) \
40+
{ \
41+
(b)[(i) ] = (uint8_t) ((n) >> 24); \
42+
(b)[(i) + 1] = (uint8_t) ((n) >> 16); \
43+
(b)[(i) + 2] = (uint8_t) ((n) >> 8); \
44+
(b)[(i) + 3] = (uint8_t) ((n) ); \
45+
}
46+
#endif
47+
48+
// Constants
49+
50+
static const uint8_t sha1_padding[64] =
51+
{
52+
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
56+
};
57+
58+
// Private methods
59+
60+
void SHA1Builder::process(const uint8_t* data)
61+
{
62+
uint32_t temp, W[16], A, B, C, D, E;
63+
64+
GET_UINT32_BE(W[ 0], data, 0);
65+
GET_UINT32_BE(W[ 1], data, 4);
66+
GET_UINT32_BE(W[ 2], data, 8);
67+
GET_UINT32_BE(W[ 3], data, 12);
68+
GET_UINT32_BE(W[ 4], data, 16);
69+
GET_UINT32_BE(W[ 5], data, 20);
70+
GET_UINT32_BE(W[ 6], data, 24);
71+
GET_UINT32_BE(W[ 7], data, 28);
72+
GET_UINT32_BE(W[ 8], data, 32);
73+
GET_UINT32_BE(W[ 9], data, 36);
74+
GET_UINT32_BE(W[10], data, 40);
75+
GET_UINT32_BE(W[11], data, 44);
76+
GET_UINT32_BE(W[12], data, 48);
77+
GET_UINT32_BE(W[13], data, 52);
78+
GET_UINT32_BE(W[14], data, 56);
79+
GET_UINT32_BE(W[15], data, 60);
80+
81+
#define sha1_S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
82+
83+
#define sha1_R(t) \
84+
( \
85+
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
86+
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
87+
(W[t & 0x0F] = sha1_S(temp,1)) \
88+
)
89+
90+
#define sha1_P(a,b,c,d,e,x) \
91+
{ \
92+
e += sha1_S(a,5) + sha1_F(b,c,d) + sha1_K + x; b = sha1_S(b,30); \
93+
}
94+
95+
A = state[0];
96+
B = state[1];
97+
C = state[2];
98+
D = state[3];
99+
E = state[4];
100+
101+
#define sha1_F(x,y,z) (z ^ (x & (y ^ z)))
102+
#define sha1_K 0x5A827999
103+
104+
sha1_P( A, B, C, D, E, W[0] );
105+
sha1_P( E, A, B, C, D, W[1] );
106+
sha1_P( D, E, A, B, C, W[2] );
107+
sha1_P( C, D, E, A, B, W[3] );
108+
sha1_P( B, C, D, E, A, W[4] );
109+
sha1_P( A, B, C, D, E, W[5] );
110+
sha1_P( E, A, B, C, D, W[6] );
111+
sha1_P( D, E, A, B, C, W[7] );
112+
sha1_P( C, D, E, A, B, W[8] );
113+
sha1_P( B, C, D, E, A, W[9] );
114+
sha1_P( A, B, C, D, E, W[10] );
115+
sha1_P( E, A, B, C, D, W[11] );
116+
sha1_P( D, E, A, B, C, W[12] );
117+
sha1_P( C, D, E, A, B, W[13] );
118+
sha1_P( B, C, D, E, A, W[14] );
119+
sha1_P( A, B, C, D, E, W[15] );
120+
sha1_P( E, A, B, C, D, sha1_R(16) );
121+
sha1_P( D, E, A, B, C, sha1_R(17) );
122+
sha1_P( C, D, E, A, B, sha1_R(18) );
123+
sha1_P( B, C, D, E, A, sha1_R(19) );
124+
125+
#undef sha1_K
126+
#undef sha1_F
127+
128+
#define sha1_F(x,y,z) (x ^ y ^ z)
129+
#define sha1_K 0x6ED9EBA1
130+
131+
sha1_P( A, B, C, D, E, sha1_R(20) );
132+
sha1_P( E, A, B, C, D, sha1_R(21) );
133+
sha1_P( D, E, A, B, C, sha1_R(22) );
134+
sha1_P( C, D, E, A, B, sha1_R(23) );
135+
sha1_P( B, C, D, E, A, sha1_R(24) );
136+
sha1_P( A, B, C, D, E, sha1_R(25) );
137+
sha1_P( E, A, B, C, D, sha1_R(26) );
138+
sha1_P( D, E, A, B, C, sha1_R(27) );
139+
sha1_P( C, D, E, A, B, sha1_R(28) );
140+
sha1_P( B, C, D, E, A, sha1_R(29) );
141+
sha1_P( A, B, C, D, E, sha1_R(30) );
142+
sha1_P( E, A, B, C, D, sha1_R(31) );
143+
sha1_P( D, E, A, B, C, sha1_R(32) );
144+
sha1_P( C, D, E, A, B, sha1_R(33) );
145+
sha1_P( B, C, D, E, A, sha1_R(34) );
146+
sha1_P( A, B, C, D, E, sha1_R(35) );
147+
sha1_P( E, A, B, C, D, sha1_R(36) );
148+
sha1_P( D, E, A, B, C, sha1_R(37) );
149+
sha1_P( C, D, E, A, B, sha1_R(38) );
150+
sha1_P( B, C, D, E, A, sha1_R(39) );
151+
152+
#undef sha1_K
153+
#undef sha1_F
154+
155+
#define sha1_F(x,y,z) ((x & y) | (z & (x | y)))
156+
#define sha1_K 0x8F1BBCDC
157+
158+
sha1_P( A, B, C, D, E, sha1_R(40) );
159+
sha1_P( E, A, B, C, D, sha1_R(41) );
160+
sha1_P( D, E, A, B, C, sha1_R(42) );
161+
sha1_P( C, D, E, A, B, sha1_R(43) );
162+
sha1_P( B, C, D, E, A, sha1_R(44) );
163+
sha1_P( A, B, C, D, E, sha1_R(45) );
164+
sha1_P( E, A, B, C, D, sha1_R(46) );
165+
sha1_P( D, E, A, B, C, sha1_R(47) );
166+
sha1_P( C, D, E, A, B, sha1_R(48) );
167+
sha1_P( B, C, D, E, A, sha1_R(49) );
168+
sha1_P( A, B, C, D, E, sha1_R(50) );
169+
sha1_P( E, A, B, C, D, sha1_R(51) );
170+
sha1_P( D, E, A, B, C, sha1_R(52) );
171+
sha1_P( C, D, E, A, B, sha1_R(53) );
172+
sha1_P( B, C, D, E, A, sha1_R(54) );
173+
sha1_P( A, B, C, D, E, sha1_R(55) );
174+
sha1_P( E, A, B, C, D, sha1_R(56) );
175+
sha1_P( D, E, A, B, C, sha1_R(57) );
176+
sha1_P( C, D, E, A, B, sha1_R(58) );
177+
sha1_P( B, C, D, E, A, sha1_R(59) );
178+
179+
#undef sha1_K
180+
#undef sha1_F
181+
182+
#define sha1_F(x,y,z) (x ^ y ^ z)
183+
#define sha1_K 0xCA62C1D6
184+
185+
sha1_P( A, B, C, D, E, sha1_R(60) );
186+
sha1_P( E, A, B, C, D, sha1_R(61) );
187+
sha1_P( D, E, A, B, C, sha1_R(62) );
188+
sha1_P( C, D, E, A, B, sha1_R(63) );
189+
sha1_P( B, C, D, E, A, sha1_R(64) );
190+
sha1_P( A, B, C, D, E, sha1_R(65) );
191+
sha1_P( E, A, B, C, D, sha1_R(66) );
192+
sha1_P( D, E, A, B, C, sha1_R(67) );
193+
sha1_P( C, D, E, A, B, sha1_R(68) );
194+
sha1_P( B, C, D, E, A, sha1_R(69) );
195+
sha1_P( A, B, C, D, E, sha1_R(70) );
196+
sha1_P( E, A, B, C, D, sha1_R(71) );
197+
sha1_P( D, E, A, B, C, sha1_R(72) );
198+
sha1_P( C, D, E, A, B, sha1_R(73) );
199+
sha1_P( B, C, D, E, A, sha1_R(74) );
200+
sha1_P( A, B, C, D, E, sha1_R(75) );
201+
sha1_P( E, A, B, C, D, sha1_R(76) );
202+
sha1_P( D, E, A, B, C, sha1_R(77) );
203+
sha1_P( C, D, E, A, B, sha1_R(78) );
204+
sha1_P( B, C, D, E, A, sha1_R(79) );
205+
206+
#undef sha1_K
207+
#undef sha1_F
208+
209+
state[0] += A;
210+
state[1] += B;
211+
state[2] += C;
212+
state[3] += D;
213+
state[4] += E;
214+
}
215+
216+
// Public methods
217+
218+
void SHA1Builder::begin(void)
219+
{
220+
total[0] = 0;
221+
total[1] = 0;
222+
223+
state[0] = 0x67452301;
224+
state[1] = 0xEFCDAB89;
225+
state[2] = 0x98BADCFE;
226+
state[3] = 0x10325476;
227+
state[4] = 0xC3D2E1F0;
228+
229+
memset(buffer, 0x00, sizeof(buffer));
230+
memset(hash, 0x00, sizeof(hash));
231+
}
232+
233+
void SHA1Builder::add(uint8_t* data, size_t len)
234+
{
235+
size_t fill;
236+
uint32_t left;
237+
238+
if(len == 0)
239+
{
240+
return;
241+
}
242+
243+
left = total[0] & 0x3F;
244+
fill = 64 - left;
245+
246+
total[0] += (uint32_t) len;
247+
total[0] &= 0xFFFFFFFF;
248+
249+
if(total[0] < (uint32_t) len)
250+
{
251+
total[1]++;
252+
}
253+
254+
if(left && len >= fill)
255+
{
256+
memcpy((void *) (buffer + left), data, fill);
257+
process(buffer);
258+
data += fill;
259+
len -= fill;
260+
left = 0;
261+
}
262+
263+
while(len >= 64)
264+
{
265+
process(data);
266+
data += 64;
267+
len -= 64;
268+
}
269+
270+
if(len > 0) {
271+
memcpy((void *) (buffer + left), data, len);
272+
}
273+
}
274+
275+
void SHA1Builder::addHexString(const char * data)
276+
{
277+
uint16_t len = strlen(data);
278+
uint8_t * tmp = (uint8_t*)malloc(len/2);
279+
if(tmp == NULL) {
280+
return;
281+
}
282+
hex2bytes(tmp, len/2, data);
283+
add(tmp, len/2);
284+
free(tmp);
285+
}
286+
287+
bool SHA1Builder::addStream(Stream & stream, const size_t maxLen)
288+
{
289+
const int buf_size = 512;
290+
int maxLengthLeft = maxLen;
291+
uint8_t * buf = (uint8_t*) malloc(buf_size);
292+
293+
if(!buf) {
294+
return false;
295+
}
296+
297+
int bytesAvailable = stream.available();
298+
while((bytesAvailable > 0) && (maxLengthLeft > 0)) {
299+
300+
// determine number of bytes to read
301+
int readBytes = bytesAvailable;
302+
if(readBytes > maxLengthLeft) {
303+
readBytes = maxLengthLeft ; // read only until max_len
304+
}
305+
if(readBytes > buf_size) {
306+
readBytes = buf_size; // not read more the buffer can handle
307+
}
308+
309+
// read data and check if we got something
310+
int numBytesRead = stream.readBytes(buf, readBytes);
311+
if(numBytesRead< 1) {
312+
free(buf);
313+
return false;
314+
}
315+
316+
// Update SHA1 with buffer payload
317+
add(buf, numBytesRead);
318+
319+
// update available number of bytes
320+
maxLengthLeft -= numBytesRead;
321+
bytesAvailable = stream.available();
322+
}
323+
free(buf);
324+
return true;
325+
}
326+
327+
void SHA1Builder::calculate(void)
328+
{
329+
uint32_t last, padn;
330+
uint32_t high, low;
331+
uint8_t msglen[8];
332+
333+
high = (total[0] >> 29) | (total[1] << 3);
334+
low = (total[0] << 3);
335+
336+
PUT_UINT32_BE(high, msglen, 0);
337+
PUT_UINT32_BE(low, msglen, 4);
338+
339+
last = total[0] & 0x3F;
340+
padn = (last < 56) ? (56 - last) : (120 - last);
341+
342+
add((uint8_t*)sha1_padding, padn);
343+
add(msglen, 8);
344+
345+
PUT_UINT32_BE(state[0], hash, 0);
346+
PUT_UINT32_BE(state[1], hash, 4);
347+
PUT_UINT32_BE(state[2], hash, 8);
348+
PUT_UINT32_BE(state[3], hash, 12);
349+
PUT_UINT32_BE(state[4], hash, 16);
350+
}
351+
352+
void SHA1Builder::getBytes(uint8_t * output)
353+
{
354+
memcpy(output, hash, SHA1_HASH_SIZE);
355+
}
356+
357+
void SHA1Builder::getChars(char * output)
358+
{
359+
bytes2hex(output, SHA1_HASH_SIZE*2+1, hash, SHA1_HASH_SIZE);
360+
}
361+
362+
String SHA1Builder::toString(void)
363+
{
364+
char out[(SHA1_HASH_SIZE * 2) + 1];
365+
getChars(out);
366+
return String(out);
367+
}

0 commit comments

Comments
 (0)