1 Termine ins Archiv verschoben
[stratum0-wiki.git] / Spacegate%2F1.Crap.mw
1 1. Implementation von SHA256 inkl. UART gelaber (noch mit human Stuff)
2
3 <syntaxhighlight lang="cpp">
4 #include <sha256.h>
5 #define LITTLE_ENDIAN
6
7 uint8_t summed[32];
8 char input[32];
9 int poscnt = 0;
10 byte recdata;
11
12 void setup() {
13 // put your setup code here, to run once:
14 Serial.begin(9600);
15 Serial.println("Input");
16 }
17
18 void serialEvent() {
19 recdata = Serial.read();
20 if (recdata == 0x0D && poscnt == 0) {
21 Serial.println();
22 Serial.println("Input");
23 }
24
25 if (poscnt >=32 || recdata == 0x0D) {
26 Serial.println();
27 Serial.print("Received: ");
28 Serial.println(input);
29 sha256(&summed, input, poscnt*8);
30 Serial.print("SHA256: ");
31 for (int i = 0; i <= 31; i++) {
32 Serial.print(summed[i], HEX);
33 input[i] = NULL;
34 }
35 Serial.println();
36 poscnt = 0;
37 Serial.print("Input");
38 }
39 else {
40 input[poscnt] = recdata;
41 Serial.println(input);
42 poscnt++;
43 }
44
45
46 }
47
48 void loop() {
49
50 }
51
52
53
54 // AVR crypto lib
55 uint32_t sha256_init_vector[]={
56 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
57 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
58
59
60 /*************************************************************************/
61
62 /**
63 * \brief \c sh256_init initialises a sha256 context for hashing.
64 * \c sh256_init c initialises the given sha256 context for hashing
65 * @param state pointer to a sha256 context
66 * @return none
67 */
68 void sha256_init(sha256_ctx_t *state){
69 state->length=0;
70 memcpy(state->h, sha256_init_vector, 8*4);
71 }
72
73 /*************************************************************************/
74
75 /**
76 * rotate x right by n positions
77 */
78 uint32_t rotr32( uint32_t x, uint8_t n){
79 return ((x>>n) | (x<<(32-n)));
80 }
81
82
83 /*************************************************************************/
84
85 // #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
86
87 uint32_t change_endian32(uint32_t x){
88 return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
89 }
90
91
92 /*************************************************************************/
93
94 /* sha256 functions as macros for speed and size, cause they are called only once */
95
96 #define CH(x,y,z) (((x)&(y)) ^ ((~(x))&(z)))
97 #define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
98
99 #define SIGMA0(x) (rotr32((x),2) ^ rotr32((x),13) ^ rotr32((x),22))
100 #define SIGMA1(x) (rotr32((x),6) ^ rotr32((x),11) ^ rotr32((x),25))
101 #define SIGMA_a(x) (rotr32((x),7) ^ rotr32((x),18) ^ ((x)>>3))
102 #define SIGMA_b(x) (rotr32((x),17) ^ rotr32((x),19) ^ ((x)>>10))
103
104
105 uint32_t k[]={
106 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
107 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
108 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
109 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
110 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
111 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
112 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
113 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
114 };
115
116
117 /*************************************************************************/
118
119 /**
120 * block must be, 512, Bit = 64, Byte, long !!!
121 */
122 void sha256_nextBlock (sha256_ctx_t *state, const void* block){
123 uint32_t w[64]; /* this is 256, byte, large, */
124 uint8_t i;
125 uint32_t a[8],t1,t2;
126
127 /* init w */
128 #if defined LITTLE_ENDIAN
129 for (i=0; i<16; ++i){
130 w[i]= change_endian32(((uint32_t*)block)[i]);
131 }
132 #elif defined BIG_ENDIAN
133 memcpy((void*)w, block, 64);
134 #endif
135 for (i=16; i<64; ++i){
136 w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];
137 }
138
139 /* init working variables */
140 memcpy((void*)a,(void*)(state->h), 8*4);
141
142 /* do the, fun stuff, */
143 for (i=0; i<64; ++i){
144 t1 = a[7] + SIGMA1(a[4]) + CH(a[4],a[5],a[6]) + k[i] + w[i];
145 t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]);
146 memmove(&(a[1]), &(a[0]), 7*4); /* a[7]=a[6]; a[6]=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; */
147 a[4] += t1;
148 a[0] = t1 + t2;
149 }
150
151 /* update, the, state, */
152 for (i=0; i<8; ++i){
153 state->h[i] += a[i];
154 }
155 state->length += 512;
156 }
157
158
159 /*************************************************************************/
160
161 /**
162 * \brief function to process the last block being hashed
163 * @param state Pointer to the context in which this block should be processed.
164 * @param block Pointer to the message wich should be hashed.
165 * @param length is the length of only THIS block in BITS not in bytes!
166 * bits are big endian, meaning high bits come first.
167 * if you have a message with bits at the end, the byte must be padded with zeros
168 */
169 void sha256_lastBlock(sha256_ctx_t *state, const void* block, uint16_t length){
170 uint8_t lb[SHA256_BLOCK_BITS/8]; /* local block */
171 while(length>=SHA256_BLOCK_BITS){
172 sha256_nextBlock(state, block);
173 length -= SHA256_BLOCK_BITS;
174 block = (uint8_t*)block+SHA256_BLOCK_BYTES;
175 }
176
177 state->length += length;
178 memcpy (&(lb[0]), block, length/8);
179
180 /* set the final one bit */
181 if (length & 0x7){ // if we have single bits at the end
182 lb[length/8] = ((uint8_t*)(block))[length/8];
183 }
184 else {
185 lb[length/8] = 0;
186 }
187 lb[length/8] |= 0x80>>(length & 0x7);
188 length =(length >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
189 /* pad with zeros */
190 if (length>64-8){ /* not enouth space for 64bit length value */
191 memset((void*)(&(lb[length])), 0, 64-length);
192 sha256_nextBlock(state, lb);
193 state->length -= 512;
194 length = 0;
195 }
196 memset((void*)(&(lb[length])), 0, 56-length);
197 /* store the 64bit length value */
198 #if defined LITTLE_ENDIAN
199 /* this is now rolled up */
200 uint8_t i;
201 for (i=1; i<=8; ++i){
202 lb[55+i] = (uint8_t)(state->length>>(64- 8*i));
203 }
204 #elif defined BIG_ENDIAN
205 *((uint64_t)&(lb[56])) = state->length;
206 #endif
207 sha256_nextBlock(state, lb);
208 }
209
210
211 /*************************************************************************/
212
213 /*
214 * length in bits!
215 */
216 void sha256(sha256_hash_t *dest, const void* msg, uint32_t length){ /* length could be choosen longer but this is for µC */
217 sha256_ctx_t s;
218 sha256_init(&s);
219 while(length >= SHA256_BLOCK_BITS){
220 sha256_nextBlock(&s, msg);
221 msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
222 length -= SHA256_BLOCK_BITS;
223 }
224 sha256_lastBlock(&s, msg, length);
225 sha256_ctx2hash(dest,&s);
226 }
227
228
229
230 /*************************************************************************/
231
232 void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state){
233 #if defined LITTLE_ENDIAN
234 uint8_t i;
235 for(i=0; i<8; ++i){
236 ((uint32_t*)dest)[i] = change_endian32(state->h[i]);
237 }
238 #elif BIG_ENDIAN
239 if (dest != state->h)
240 memcpy(dest, state->h, SHA256_HASH_BITS/8);
241 #else
242
243 #endif
244 }
245
246
247
248
249 </syntaxhighlight>
This page took 0.077175 seconds and 5 git commands to generate.