Arduino Cryptography Library
SHA256.cpp
1 /*
2  * Copyright (C) 2015 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "SHA256.h"
24 #include "Crypto.h"
25 #include "utility/RotateUtil.h"
26 #include "utility/EndianUtil.h"
27 #include "utility/ProgMemUtil.h"
28 #include <string.h>
29 
53 {
54  reset();
55 }
56 
62 {
63  clean(state);
64 }
65 
66 size_t SHA256::hashSize() const
67 {
68  return 32;
69 }
70 
71 size_t SHA256::blockSize() const
72 {
73  return 64;
74 }
75 
77 {
78  state.h[0] = 0x6a09e667;
79  state.h[1] = 0xbb67ae85;
80  state.h[2] = 0x3c6ef372;
81  state.h[3] = 0xa54ff53a,
82  state.h[4] = 0x510e527f;
83  state.h[5] = 0x9b05688c;
84  state.h[6] = 0x1f83d9ab;
85  state.h[7] = 0x5be0cd19;
86  state.chunkSize = 0;
87  state.length = 0;
88 }
89 
90 void SHA256::update(const void *data, size_t len)
91 {
92  // Update the total length (in bits, not bytes).
93  state.length += ((uint64_t)len) << 3;
94 
95  // Break the input up into 512-bit chunks and process each in turn.
96  const uint8_t *d = (const uint8_t *)data;
97  while (len > 0) {
98  uint8_t size = 64 - state.chunkSize;
99  if (size > len)
100  size = len;
101  memcpy(((uint8_t *)state.w) + state.chunkSize, d, size);
102  state.chunkSize += size;
103  len -= size;
104  d += size;
105  if (state.chunkSize == 64) {
106  processChunk();
107  state.chunkSize = 0;
108  }
109  }
110 }
111 
112 void SHA256::finalize(void *hash, size_t len)
113 {
114  // Pad the last chunk. We may need two padding chunks if there
115  // isn't enough room in the first for the padding and length.
116  uint8_t *wbytes = (uint8_t *)state.w;
117  if (state.chunkSize <= (64 - 9)) {
118  wbytes[state.chunkSize] = 0x80;
119  memset(wbytes + state.chunkSize + 1, 0x00, 64 - 8 - (state.chunkSize + 1));
120  state.w[14] = htobe32((uint32_t)(state.length >> 32));
121  state.w[15] = htobe32((uint32_t)state.length);
122  processChunk();
123  } else {
124  wbytes[state.chunkSize] = 0x80;
125  memset(wbytes + state.chunkSize + 1, 0x00, 64 - (state.chunkSize + 1));
126  processChunk();
127  memset(wbytes, 0x00, 64 - 8);
128  state.w[14] = htobe32((uint32_t)(state.length >> 32));
129  state.w[15] = htobe32((uint32_t)state.length);
130  processChunk();
131  }
132 
133  // Convert the result into big endian and return it.
134  for (uint8_t posn = 0; posn < 8; ++posn)
135  state.w[posn] = htobe32(state.h[posn]);
136 
137  // Copy the hash to the caller's return buffer.
138  size_t maxHashSize = hashSize();
139  if (len > maxHashSize)
140  len = maxHashSize;
141  memcpy(hash, state.w, len);
142 }
143 
145 {
146  clean(state);
147  reset();
148 }
149 
150 void SHA256::resetHMAC(const void *key, size_t keyLen)
151 {
152  formatHMACKey(state.w, key, keyLen, 0x36);
153  state.length += 64 * 8;
154  processChunk();
155 }
156 
157 void SHA256::finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen)
158 {
159  uint8_t temp[32];
160  finalize(temp, sizeof(temp));
161  formatHMACKey(state.w, key, keyLen, 0x5C);
162  state.length += 64 * 8;
163  processChunk();
164  update(temp, hashSize());
165  finalize(hash, hashLen);
166  clean(temp);
167 }
168 
175 {
176  // Round constants for SHA-256.
177  static uint32_t const k[64] PROGMEM = {
178  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
179  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
180  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
181  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
182  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
183  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
184  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
185  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
186  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
187  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
188  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
189  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
190  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
191  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
192  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
193  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
194  };
195 
196  // Convert the first 16 words from big endian to host byte order.
197  uint8_t index;
198  for (index = 0; index < 16; ++index)
199  state.w[index] = be32toh(state.w[index]);
200 
201  // Initialise working variables to the current hash value.
202  uint32_t a = state.h[0];
203  uint32_t b = state.h[1];
204  uint32_t c = state.h[2];
205  uint32_t d = state.h[3];
206  uint32_t e = state.h[4];
207  uint32_t f = state.h[5];
208  uint32_t g = state.h[6];
209  uint32_t h = state.h[7];
210 
211  // Perform the first 16 rounds of the compression function main loop.
212  uint32_t temp1, temp2;
213  for (index = 0; index < 16; ++index) {
214  temp1 = h + pgm_read_dword(k + index) + state.w[index] +
215  (rightRotate6(e) ^ rightRotate11(e) ^ rightRotate25(e)) +
216  ((e & f) ^ ((~e) & g));
217  temp2 = (rightRotate2(a) ^ rightRotate13(a) ^ rightRotate22(a)) +
218  ((a & b) ^ (a & c) ^ (b & c));
219  h = g;
220  g = f;
221  f = e;
222  e = d + temp1;
223  d = c;
224  c = b;
225  b = a;
226  a = temp1 + temp2;
227  }
228 
229  // Perform the 48 remaining rounds. We expand the first 16 words to
230  // 64 in-place in the "w" array. This saves 192 bytes of memory
231  // that would have otherwise need to be allocated to the "w" array.
232  for (; index < 64; ++index) {
233  // Expand the next word.
234  temp1 = state.w[(index - 15) & 0x0F];
235  temp2 = state.w[(index - 2) & 0x0F];
236  temp1 = state.w[index & 0x0F] =
237  state.w[(index - 16) & 0x0F] + state.w[(index - 7) & 0x0F] +
238  (rightRotate7(temp1) ^ rightRotate18(temp1) ^ (temp1 >> 3)) +
239  (rightRotate17(temp2) ^ rightRotate19(temp2) ^ (temp2 >> 10));
240 
241  // Perform the round.
242  temp1 = h + pgm_read_dword(k + index) + temp1 +
243  (rightRotate6(e) ^ rightRotate11(e) ^ rightRotate25(e)) +
244  ((e & f) ^ ((~e) & g));
245  temp2 = (rightRotate2(a) ^ rightRotate13(a) ^ rightRotate22(a)) +
246  ((a & b) ^ (a & c) ^ (b & c));
247  h = g;
248  g = f;
249  f = e;
250  e = d + temp1;
251  d = c;
252  c = b;
253  b = a;
254  a = temp1 + temp2;
255  }
256 
257  // Add the compressed chunk to the current hash value.
258  state.h[0] += a;
259  state.h[1] += b;
260  state.h[2] += c;
261  state.h[3] += d;
262  state.h[4] += e;
263  state.h[5] += f;
264  state.h[6] += g;
265  state.h[7] += h;
266 
267  // Attempt to clean up the stack.
268  a = b = c = d = e = f = g = h = temp1 = temp2 = 0;
269 }
void formatHMACKey(void *block, const void *key, size_t len, uint8_t pad)
Formats a HMAC key into a block.
Definition: Hash.cpp:162
void resetHMAC(const void *key, size_t keyLen)
Resets the hash ready for a new HMAC hashing process.
Definition: SHA256.cpp:150
void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen)
Finalizes the HMAC hashing process and returns the hash.
Definition: SHA256.cpp:157
void update(const void *data, size_t len)
Updates the hash with more data.
Definition: SHA256.cpp:90
void finalize(void *hash, size_t len)
Finalizes the hashing process and returns the hash.
Definition: SHA256.cpp:112
size_t hashSize() const
Size of the hash result from finalize().
Definition: SHA256.cpp:66
SHA256()
Constructs a SHA-256 hash object.
Definition: SHA256.cpp:52
virtual ~SHA256()
Destroys this SHA-256 hash object after clearing sensitive information.
Definition: SHA256.cpp:61
void reset()
Resets the hash ready for a new hashing process.
Definition: SHA256.cpp:76
size_t blockSize() const
Size of the internal block used by the hash algorithm.
Definition: SHA256.cpp:71
void clear()
Clears the hash state, removing all sensitive data, and then resets the hash ready for a new hashing ...
Definition: SHA256.cpp:144
void processChunk()
Processes a single 512-bit chunk with the core SHA-256 algorithm.
Definition: SHA256.cpp:174