Skip to content

Commit 661c707

Browse files
committed
add Hash library currently supports SHA1
1 parent 605e76f commit 661c707

File tree

6 files changed

+378
-0
lines changed

6 files changed

+378
-0
lines changed

libraries/Hash/examples/sha1.ino

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* simple demo to show sha1 calculation
3+
*/
4+
#include <Arduino.h>
5+
#include <hash.h>
6+
7+
void setup() {
8+
Serial.begin(921600);
9+
}
10+
11+
void loop() {
12+
uint8_t hash[20];
13+
const uint8_t test[] = "test";
14+
15+
sha1((uint8_t *)&test[0], sizeof(test)-1, &hash[0]);
16+
17+
// SHA1: A94A8FE5CCB19BA61C4C0873D391E987982FBBD3
18+
Serial.print("SHA1:");
19+
for(uint16_t i = 0; i < 20; i++) {
20+
Serial.printf("%02X", hash[i]);
21+
}
22+
Serial.println();
23+
24+
delay(1000);
25+
}
26+

libraries/Hash/library.properties

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name=Hash
2+
version=1.0
3+
author=Markus Sattler
4+
maintainer=Markus Sattler
5+
sentence=Generate Hash from data
6+
paragraph=
7+
url=
8+
architectures=esp8266

libraries/Hash/src/hash.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* @file hash.cpp
3+
* @date 20.05.2015
4+
* @author Markus Sattler
5+
*
6+
* Copyright (c) 2015 Markus Sattler. All rights reserved.
7+
* This file is part of the esp8266 core for Arduino environment.
8+
*
9+
* This library is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 2.1 of the License, or (at your option) any later version.
13+
*
14+
* This library is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with this library; if not, write to the Free Software
21+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22+
*
23+
*/
24+
25+
#include <Arduino.h>
26+
27+
#include "hash.h"
28+
29+
extern "C" {
30+
#include "sha1/sha1.h"
31+
}
32+
33+
/**
34+
* create a sha1 hash from data
35+
* @param data uint8_t *
36+
* @param size uint32_t
37+
* @param hash uint8_t[20]
38+
*/
39+
void sha1(uint8_t * data, uint32_t size, uint8_t hash[20]) {
40+
41+
SHA1_CTX ctx;
42+
43+
#ifdef DEBUG_SHA1
44+
os_printf("DATA:");
45+
for(uint16_t i = 0; i < size; i++) {
46+
os_printf("%02X", data[i]);
47+
}
48+
os_printf("\n");
49+
os_printf("DATA:");
50+
for(uint16_t i = 0; i < size; i++) {
51+
os_printf("%c", data[i]);
52+
}
53+
os_printf("\n");
54+
#endif
55+
56+
SHA1Init(&ctx);
57+
SHA1Update(&ctx, data, size);
58+
SHA1Final(hash, &ctx);
59+
60+
#ifdef DEBUG_SHA1
61+
os_printf("SHA1:");
62+
for(uint16_t i = 0; i < 20; i++) {
63+
os_printf("%02X", hash[i]);
64+
}
65+
os_printf("\n\n");
66+
#endif
67+
}
68+
69+
void sha1(const uint8_t * data, uint32_t size, uint8_t hash[20]) {
70+
sha1((uint8_t *) data, size, hash);
71+
}

libraries/Hash/src/hash.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @file hash.h
3+
* @date 20.05.2015
4+
* @author Markus Sattler
5+
*
6+
* Copyright (c) 2015 Markus Sattler. All rights reserved.
7+
* This file is part of the esp8266 core for Arduino environment.
8+
*
9+
* This library is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 2.1 of the License, or (at your option) any later version.
13+
*
14+
* This library is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with this library; if not, write to the Free Software
21+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22+
*
23+
*/
24+
25+
#ifndef HASH_H_
26+
#define HASH_H_
27+
28+
//#define DEBUG_SHA1
29+
30+
void sha1(uint8_t * data, uint32_t size, uint8_t hash[20]);
31+
void sha1(const uint8_t * data, uint32_t size, uint8_t hash[20]);
32+
33+
#endif /* HASH_H_ */

libraries/Hash/src/sha1/sha1.c

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/**
2+
* @file sha1.c
3+
* @date 20.05.2015
4+
* @author Steve Reid <steve@edmweb.com>
5+
*
6+
* from: http://www.virtualbox.org/svn/vbox/trunk/src/recompiler/tests/sha1.c
7+
*/
8+
9+
/* from valgrind tests */
10+
11+
/* ================ sha1.c ================ */
12+
/*
13+
SHA-1 in C
14+
By Steve Reid <steve@edmweb.com>
15+
100% Public Domain
16+
17+
Test Vectors (from FIPS PUB 180-1)
18+
"abc"
19+
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
20+
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
21+
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
22+
A million repetitions of "a"
23+
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
24+
*/
25+
26+
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
27+
/* #define SHA1HANDSOFF * Copies data before messing with it. */
28+
29+
#define SHA1HANDSOFF
30+
31+
#include <stdio.h>
32+
#include <string.h>
33+
#include <stdint.h>
34+
#include <c_types.h>
35+
36+
#include "sha1.h"
37+
38+
//#include <endian.h>
39+
40+
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
41+
42+
/* blk0() and blk() perform the initial expand. */
43+
/* I got the idea of expanding during the round function from SSLeay */
44+
#if BYTE_ORDER == LITTLE_ENDIAN
45+
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
46+
|(rol(block->l[i],8)&0x00FF00FF))
47+
#elif BYTE_ORDER == BIG_ENDIAN
48+
#define blk0(i) block->l[i]
49+
#else
50+
#error "Endianness not defined!"
51+
#endif
52+
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
53+
^block->l[(i+2)&15]^block->l[i&15],1))
54+
55+
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
56+
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
57+
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
58+
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
59+
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
60+
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
61+
62+
63+
/* Hash a single 512-bit block. This is the core of the algorithm. */
64+
65+
void ICACHE_FLASH_ATTR SHA1Transform(uint32_t state[5], uint8_t buffer[64])
66+
{
67+
uint32_t a, b, c, d, e;
68+
typedef union {
69+
unsigned char c[64];
70+
uint32_t l[16];
71+
} CHAR64LONG16;
72+
#ifdef SHA1HANDSOFF
73+
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
74+
memcpy(block, buffer, 64);
75+
#else
76+
/* The following had better never be used because it causes the
77+
* pointer-to-const buffer to be cast into a pointer to non-const.
78+
* And the result is written through. I threw a "const" in, hoping
79+
* this will cause a diagnostic.
80+
*/
81+
CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
82+
#endif
83+
/* Copy context->state[] to working vars */
84+
a = state[0];
85+
b = state[1];
86+
c = state[2];
87+
d = state[3];
88+
e = state[4];
89+
/* 4 rounds of 20 operations each. Loop unrolled. */
90+
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
91+
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
92+
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
93+
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
94+
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
95+
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
96+
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
97+
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
98+
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
99+
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
100+
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
101+
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
102+
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
103+
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
104+
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
105+
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
106+
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
107+
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
108+
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
109+
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
110+
/* Add the working vars back into context.state[] */
111+
state[0] += a;
112+
state[1] += b;
113+
state[2] += c;
114+
state[3] += d;
115+
state[4] += e;
116+
/* Wipe variables */
117+
a = b = c = d = e = 0;
118+
#ifdef SHA1HANDSOFF
119+
memset(block, '\0', sizeof(block));
120+
#endif
121+
}
122+
123+
124+
/* SHA1Init - Initialize new context */
125+
126+
void ICACHE_FLASH_ATTR SHA1Init(SHA1_CTX* context)
127+
{
128+
/* SHA1 initialization constants */
129+
context->state[0] = 0x67452301;
130+
context->state[1] = 0xEFCDAB89;
131+
context->state[2] = 0x98BADCFE;
132+
context->state[3] = 0x10325476;
133+
context->state[4] = 0xC3D2E1F0;
134+
context->count[0] = context->count[1] = 0;
135+
}
136+
137+
138+
/* Run your data through this. */
139+
140+
void ICACHE_FLASH_ATTR SHA1Update(SHA1_CTX* context, uint8_t* data, uint32_t len)
141+
{
142+
uint32_t i;
143+
uint32_t j;
144+
145+
j = context->count[0];
146+
if ((context->count[0] += len << 3) < j)
147+
context->count[1]++;
148+
context->count[1] += (len>>29);
149+
j = (j >> 3) & 63;
150+
if ((j + len) > 63) {
151+
memcpy(&context->buffer[j], data, (i = 64-j));
152+
SHA1Transform(context->state, context->buffer);
153+
for ( ; i + 63 < len; i += 64) {
154+
SHA1Transform(context->state, &data[i]);
155+
}
156+
j = 0;
157+
}
158+
else i = 0;
159+
memcpy(&context->buffer[j], &data[i], len - i);
160+
}
161+
162+
163+
/* Add padding and return the message digest. */
164+
165+
void ICACHE_FLASH_ATTR SHA1Final(unsigned char digest[20], SHA1_CTX* context)
166+
{
167+
unsigned i;
168+
unsigned char finalcount[8];
169+
unsigned char c;
170+
171+
#if 0 /* untested "improvement" by DHR */
172+
/* Convert context->count to a sequence of bytes
173+
* in finalcount. Second element first, but
174+
* big-endian order within element.
175+
* But we do it all backwards.
176+
*/
177+
unsigned char *fcp = &finalcount[8];
178+
179+
for (i = 0; i < 2; i++)
180+
{
181+
uint32_t t = context->count[i];
182+
int j;
183+
184+
for (j = 0; j < 4; t >>= 8, j++)
185+
*--fcp = (unsigned char) t;
186+
}
187+
#else
188+
for (i = 0; i < 8; i++) {
189+
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
190+
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
191+
}
192+
#endif
193+
c = 0200;
194+
SHA1Update(context, &c, 1);
195+
while ((context->count[0] & 504) != 448) {
196+
c = 0000;
197+
SHA1Update(context, &c, 1);
198+
}
199+
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
200+
for (i = 0; i < 20; i++) {
201+
digest[i] = (unsigned char)
202+
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
203+
}
204+
/* Wipe variables */
205+
memset(context, '\0', sizeof(*context));
206+
memset(&finalcount, '\0', sizeof(finalcount));
207+
}
208+
/* ================ end of sha1.c ================ */

libraries/Hash/src/sha1/sha1.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @file sha1.h
3+
* @date 20.05.2015
4+
* @author Steve Reid <steve@edmweb.com>
5+
*
6+
* from: http://www.virtualbox.org/svn/vbox/trunk/src/recompiler/tests/sha1.c
7+
*/
8+
9+
/* ================ sha1.h ================ */
10+
/*
11+
SHA-1 in C
12+
By Steve Reid <steve@edmweb.com>
13+
100% Public Domain
14+
*/
15+
16+
#ifndef SHA1_H_
17+
#define SHA1_H_
18+
19+
typedef struct {
20+
uint32_t state[5];
21+
uint32_t count[2];
22+
unsigned char buffer[64];
23+
} SHA1_CTX;
24+
25+
void SHA1Transform(uint32_t state[5], uint8_t buffer[64]);
26+
void SHA1Init(SHA1_CTX* context);
27+
void SHA1Update(SHA1_CTX* context, uint8_t* data, uint32_t len);
28+
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
29+
30+
#endif /* SHA1_H_ */
31+
32+
/* ================ end of sha1.h ================ */

0 commit comments

Comments
 (0)