25 #include "utility/RotateUtil.h"
26 #include "utility/EndianUtil.h"
27 #include "utility/ProgMemUtil.h"
78 static uint64_t
const hashStart[8] PROGMEM = {
79 0x6A09E667F3BCC908ULL, 0xBB67AE8584CAA73BULL, 0x3C6EF372FE94F82BULL,
80 0xA54FF53A5F1D36F1ULL, 0x510E527FADE682D1ULL, 0x9B05688C2B3E6C1FULL,
81 0x1F83D9ABFB41BD6BULL, 0x5BE0CD19137E2179ULL
83 memcpy_P(state.h, hashStart,
sizeof(hashStart));
92 uint64_t temp = state.lengthLow;
93 state.lengthLow += (((uint64_t)len) << 3);
94 state.lengthHigh += (((uint64_t)len) >> 61);
95 if (state.lengthLow < temp)
99 const uint8_t *d = (
const uint8_t *)data;
101 uint8_t size = 128 - state.chunkSize;
104 memcpy(((uint8_t *)state.w) + state.chunkSize, d, size);
105 state.chunkSize += size;
108 if (state.chunkSize == 128) {
119 uint8_t *wbytes = (uint8_t *)state.w;
120 if (state.chunkSize <= (128 - 17)) {
121 wbytes[state.chunkSize] = 0x80;
122 memset(wbytes + state.chunkSize + 1, 0x00, 128 - 16 - (state.chunkSize + 1));
123 state.w[14] = htobe64(state.lengthHigh);
124 state.w[15] = htobe64(state.lengthLow);
127 wbytes[state.chunkSize] = 0x80;
128 memset(wbytes + state.chunkSize + 1, 0x00, 128 - (state.chunkSize + 1));
130 memset(wbytes, 0x00, 128 - 16);
131 state.w[14] = htobe64(state.lengthHigh);
132 state.w[15] = htobe64(state.lengthLow);
137 for (uint8_t posn = 0; posn < 8; ++posn)
138 state.w[posn] = htobe64(state.h[posn]);
142 if (len > maxHashSize)
144 memcpy(hash, state.w, len);
156 state.lengthLow += 128 * 8;
165 state.lengthLow += 128 * 8;
180 static uint64_t
const k[80] PROGMEM = {
181 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, 0xB5C0FBCFEC4D3B2FULL,
182 0xE9B5DBA58189DBBCULL, 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
183 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL, 0xD807AA98A3030242ULL,
184 0x12835B0145706FBEULL, 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
185 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, 0x9BDC06A725C71235ULL,
186 0xC19BF174CF692694ULL, 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
187 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL, 0x2DE92C6F592B0275ULL,
188 0x4A7484AA6EA6E483ULL, 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
189 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, 0xB00327C898FB213FULL,
190 0xBF597FC7BEEF0EE4ULL, 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
191 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL, 0x27B70A8546D22FFCULL,
192 0x2E1B21385C26C926ULL, 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
193 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, 0x81C2C92E47EDAEE6ULL,
194 0x92722C851482353BULL, 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
195 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL, 0xD192E819D6EF5218ULL,
196 0xD69906245565A910ULL, 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
197 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, 0x2748774CDF8EEB99ULL,
198 0x34B0BCB5E19B48A8ULL, 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
199 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL, 0x748F82EE5DEFB2FCULL,
200 0x78A5636F43172F60ULL, 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
201 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, 0xBEF9A3F7B2C67915ULL,
202 0xC67178F2E372532BULL, 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
203 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL, 0x06F067AA72176FBAULL,
204 0x0A637DC5A2C898A6ULL, 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
205 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, 0x3C9EBE0A15C9BEBCULL,
206 0x431D67C49C100D4CULL, 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
207 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
212 for (index = 0; index < 16; ++index)
213 state.w[index] = be64toh(state.w[index]);
216 uint64_t a = state.h[0];
217 uint64_t b = state.h[1];
218 uint64_t c = state.h[2];
219 uint64_t d = state.h[3];
220 uint64_t e = state.h[4];
221 uint64_t f = state.h[5];
222 uint64_t g = state.h[6];
223 uint64_t h = state.h[7];
226 uint64_t temp1, temp2;
227 for (index = 0; index < 16; ++index) {
228 temp1 = h + pgm_read_qword(k + index) + state.w[index] +
229 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
230 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
231 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
232 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
246 for (; index < 80; ++index) {
248 temp1 = state.w[(index - 15) & 0x0F];
249 temp2 = state.w[(index - 2) & 0x0F];
250 temp1 = state.w[index & 0x0F] =
251 state.w[(index - 16) & 0x0F] + state.w[(index - 7) & 0x0F] +
252 (rightRotate1_64(temp1) ^ rightRotate8_64(temp1) ^
254 (rightRotate19_64(temp2) ^ rightRotate61_64(temp2) ^
258 temp1 = h + pgm_read_qword(k + index) + temp1 +
259 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
260 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
261 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
262 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
284 a = b = c = d = e = f = g = h = temp1 = temp2 = 0;
void formatHMACKey(void *block, const void *key, size_t len, uint8_t pad)
Formats a HMAC key into a block.
void clear()
Clears the hash state, removing all sensitive data, and then resets the hash ready for a new hashing ...
void reset()
Resets the hash ready for a new hashing process.
void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen)
Finalizes the HMAC hashing process and returns the hash.
void resetHMAC(const void *key, size_t keyLen)
Resets the hash ready for a new HMAC hashing process.
SHA512()
Constructs a SHA-512 hash object.
virtual ~SHA512()
Destroys this SHA-512 hash object after clearing sensitive information.
void update(const void *data, size_t len)
Updates the hash with more data.
size_t hashSize() const
Size of the hash result from finalize().
void processChunk()
Processes a single 1024-bit chunk with the core SHA-512 algorithm.
size_t blockSize() const
Size of the internal block used by the hash algorithm.
void finalize(void *hash, size_t len)
Finalizes the hashing process and returns the hash.