25 #include "utility/RotateUtil.h"
26 #include "utility/EndianUtil.h"
27 #include "utility/ProgMemUtil.h"
68 static uint64_t
const hashStart[8] PROGMEM = {
69 0x6A09E667F3BCC908ULL, 0xBB67AE8584CAA73BULL, 0x3C6EF372FE94F82BULL,
70 0xA54FF53A5F1D36F1ULL, 0x510E527FADE682D1ULL, 0x9B05688C2B3E6C1FULL,
71 0x1F83D9ABFB41BD6BULL, 0x5BE0CD19137E2179ULL
73 memcpy_P(state.h, hashStart,
sizeof(hashStart));
82 uint64_t temp = state.lengthLow;
83 state.lengthLow += (((uint64_t)len) << 3);
84 state.lengthHigh += (((uint64_t)len) >> 61);
85 if (state.lengthLow < temp)
89 const uint8_t *d = (
const uint8_t *)data;
91 uint8_t size = 128 - state.chunkSize;
94 memcpy(((uint8_t *)state.w) + state.chunkSize, d, size);
95 state.chunkSize += size;
98 if (state.chunkSize == 128) {
109 uint8_t *wbytes = (uint8_t *)state.w;
110 if (state.chunkSize <= (128 - 17)) {
111 wbytes[state.chunkSize] = 0x80;
112 memset(wbytes + state.chunkSize + 1, 0x00, 128 - 16 - (state.chunkSize + 1));
113 state.w[14] = htobe64(state.lengthHigh);
114 state.w[15] = htobe64(state.lengthLow);
117 wbytes[state.chunkSize] = 0x80;
118 memset(wbytes + state.chunkSize + 1, 0x00, 128 - (state.chunkSize + 1));
120 memset(wbytes, 0x00, 128 - 16);
121 state.w[14] = htobe64(state.lengthHigh);
122 state.w[15] = htobe64(state.lengthLow);
127 for (uint8_t posn = 0; posn < 8; ++posn)
128 state.w[posn] = htobe64(state.h[posn]);
133 memcpy(hash, state.w, len);
145 state.lengthLow += 128 * 8;
154 state.lengthLow += 128 * 8;
156 update(temp,
sizeof(temp));
166 void SHA512::processChunk()
169 static uint64_t
const k[80] PROGMEM = {
170 0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL, 0xB5C0FBCFEC4D3B2FULL,
171 0xE9B5DBA58189DBBCULL, 0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
172 0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL, 0xD807AA98A3030242ULL,
173 0x12835B0145706FBEULL, 0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
174 0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL, 0x9BDC06A725C71235ULL,
175 0xC19BF174CF692694ULL, 0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
176 0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL, 0x2DE92C6F592B0275ULL,
177 0x4A7484AA6EA6E483ULL, 0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
178 0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL, 0xB00327C898FB213FULL,
179 0xBF597FC7BEEF0EE4ULL, 0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
180 0x06CA6351E003826FULL, 0x142929670A0E6E70ULL, 0x27B70A8546D22FFCULL,
181 0x2E1B21385C26C926ULL, 0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
182 0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL, 0x81C2C92E47EDAEE6ULL,
183 0x92722C851482353BULL, 0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
184 0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL, 0xD192E819D6EF5218ULL,
185 0xD69906245565A910ULL, 0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
186 0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL, 0x2748774CDF8EEB99ULL,
187 0x34B0BCB5E19B48A8ULL, 0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
188 0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL, 0x748F82EE5DEFB2FCULL,
189 0x78A5636F43172F60ULL, 0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
190 0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL, 0xBEF9A3F7B2C67915ULL,
191 0xC67178F2E372532BULL, 0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
192 0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL, 0x06F067AA72176FBAULL,
193 0x0A637DC5A2C898A6ULL, 0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
194 0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL, 0x3C9EBE0A15C9BEBCULL,
195 0x431D67C49C100D4CULL, 0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
196 0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
201 for (index = 0; index < 16; ++index)
202 state.w[index] = be64toh(state.w[index]);
205 uint64_t a = state.h[0];
206 uint64_t b = state.h[1];
207 uint64_t c = state.h[2];
208 uint64_t d = state.h[3];
209 uint64_t e = state.h[4];
210 uint64_t f = state.h[5];
211 uint64_t g = state.h[6];
212 uint64_t h = state.h[7];
215 uint64_t temp1, temp2;
216 for (index = 0; index < 16; ++index) {
217 temp1 = h + pgm_read_qword(k + index) + state.w[index] +
218 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
219 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
220 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
221 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
235 for (; index < 80; ++index) {
237 temp1 = state.w[(index - 15) & 0x0F];
238 temp2 = state.w[(index - 2) & 0x0F];
239 temp1 = state.w[index & 0x0F] =
240 state.w[(index - 16) & 0x0F] + state.w[(index - 7) & 0x0F] +
241 (rightRotate1_64(temp1) ^ rightRotate8_64(temp1) ^
243 (rightRotate19_64(temp2) ^ rightRotate61_64(temp2) ^
247 temp1 = h + pgm_read_qword(k + index) + temp1 +
248 (rightRotate14_64(e) ^ rightRotate18_64(e) ^
249 rightRotate41_64(e)) + ((e & f) ^ ((~e) & g));
250 temp2 = (rightRotate28_64(a) ^ rightRotate34_64(a) ^
251 rightRotate39_64(a)) + ((a & b) ^ (a & c) ^ (b & c));
273 a = b = c = d = e = f = g = h = temp1 = temp2 = 0;
size_t hashSize() const
Size of the hash result from finalize().
size_t blockSize() const
Size of the internal block used by the hash algorithm.
virtual ~SHA512()
Destroys this SHA-512 hash object after clearing sensitive information.
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 update(const void *data, size_t len)
Updates the hash with more data.
void finalize(void *hash, size_t len)
Finalizes the hashing process and returns the hash.
void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen)
Finalizes the HMAC hashing process and returns the hash.
SHA512()
Constructs a SHA-512 hash object.
void formatHMACKey(void *block, const void *key, size_t len, uint8_t pad)
Formats a HMAC key into a block.
void resetHMAC(const void *key, size_t keyLen)
Resets the hash ready for a new HMAC hashing process.