39#if UIP_BYTE_ORDER != UIP_LITTLE_ENDIAN
41#define be32enc_vect memcpy
44#define be32dec_vect memcpy
47be64enc(uint8_t *p, uint64_t u)
49 memcpy(p, &u,
sizeof(uint64_t));
54be32dec(uint8_t
const *p)
56 return ((uint32_t)p[0] << 24)
57 | ((uint32_t)p[1] << 16)
58 | ((uint32_t)p[2] << 8)
63be32enc(uint8_t *p, uint32_t u)
65 p[0] = (u >> 24) & 0xff;
66 p[1] = (u >> 16) & 0xff;
67 p[2] = (u >> 8) & 0xff;
72be64enc(uint8_t *p, uint64_t u)
74 be32enc(p, (uint32_t)(u >> 32));
75 be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
83be32enc_vect(uint8_t *dst,
const uint32_t *src,
size_t len)
87 for(i = 0; i < len / 4; i++) {
88 be32enc(dst + i * 4, src[i]);
97be32dec_vect(uint32_t *dst,
const uint8_t *src,
size_t len)
101 for(i = 0; i < len / 4; i++) {
102 dst[i] = be32dec(src + i * 4);
107static const uint32_t K[64] = {
108 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
109 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
110 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
111 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
112 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
113 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
114 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
115 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
116 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
117 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
118 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
119 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
120 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
121 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
122 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
123 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
127#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
128#define Maj(x, y, z) ((x & (y | z)) | (y & z))
129#define SHR(x, n) (x >> n)
130#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
131#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
132#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
133#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
134#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
137#define RND(a, b, c, d, e, f, g, h, k) \
138 h += S1(e) + Ch(e, f, g) + k; \
140 h += S0(a) + Maj(a, b, c);
143#define RNDr(S, W, i, ii) \
144 RND(S[(64 - i) % 8], S[(65 - i) % 8], \
145 S[(66 - i) % 8], S[(67 - i) % 8], \
146 S[(68 - i) % 8], S[(69 - i) % 8], \
147 S[(70 - i) % 8], S[(71 - i) % 8], \
148 W[i + ii] + K[i + ii])
151#define MSCH(W, ii, i) \
153 s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
155static sha_256_checkpoint_t checkpoint;
163transform(
const uint8_t block[
static SHA_256_BLOCK_SIZE])
170 be32dec_vect(W, block, 64);
173 memcpy(S, checkpoint.state, 32);
176 for(i = 0; i < 64; i += 16) {
216 for(i = 0; i < 8; i++) {
217 checkpoint.state[i] += S[i];
225 static const unsigned char PAD[64] = {
226 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
233 if(checkpoint.buf_len < 56) {
235 memcpy(&checkpoint.buf[checkpoint.buf_len], PAD, 56 - checkpoint.buf_len);
238 memcpy(&checkpoint.buf[checkpoint.buf_len], PAD, SHA_256_BLOCK_SIZE - checkpoint.buf_len);
239 transform(checkpoint.buf);
242 memset(&checkpoint.buf[0], 0, 56);
246 be64enc(&checkpoint.buf[56], checkpoint.bit_count);
249 transform(checkpoint.buf);
257 checkpoint.bit_count = 0;
258 checkpoint.buf_len = 0;
261 checkpoint.state[0] = 0x6A09E667;
262 checkpoint.state[1] = 0xBB67AE85;
263 checkpoint.state[2] = 0x3C6EF372;
264 checkpoint.state[3] = 0xA54FF53A;
265 checkpoint.state[4] = 0x510E527F;
266 checkpoint.state[5] = 0x9B05688C;
267 checkpoint.state[6] = 0x1F83D9AB;
268 checkpoint.state[7] = 0x5BE0CD19;
273update(
const uint8_t *data,
size_t len)
281 checkpoint.bit_count += bitlen;
284 if(len < SHA_256_BLOCK_SIZE - checkpoint.buf_len) {
285 memcpy(&checkpoint.buf[checkpoint.buf_len], data, len);
286 checkpoint.buf_len += len;
291 memcpy(&checkpoint.buf[checkpoint.buf_len],
293 SHA_256_BLOCK_SIZE - checkpoint.buf_len);
294 transform(checkpoint.buf);
295 data += SHA_256_BLOCK_SIZE - checkpoint.buf_len;
296 len -= SHA_256_BLOCK_SIZE - checkpoint.buf_len;
297 checkpoint.buf_len = 0;
302 data += SHA_256_BLOCK_SIZE;
303 len -= SHA_256_BLOCK_SIZE;
307 memcpy(checkpoint.buf, data, len);
308 checkpoint.buf_len += len;
316finalize(uint8_t digest[
static SHA_256_DIGEST_LENGTH])
322 be32enc_vect(digest, checkpoint.state, SHA_256_DIGEST_LENGTH);
325 memset(&checkpoint, 0,
sizeof(checkpoint));
329create_checkpoint(sha_256_checkpoint_t *cp)
331 memcpy(cp, &checkpoint,
sizeof(*cp));
335restore_checkpoint(
const sha_256_checkpoint_t *cp)
337 memcpy(&checkpoint, cp,
sizeof(checkpoint));
341sha_256_hash(
const uint8_t *data,
size_t len,
342 uint8_t digest[
static SHA_256_DIGEST_LENGTH])
345 SHA_256.update(data, len);
346 SHA_256.finalize(digest);
350hmac_over_data_chunks(
const uint8_t *key,
size_t key_len,
351 struct data_chunk *chunks, uint_fast8_t chunks_count,
352 uint8_t hmac[
static SHA_256_DIGEST_LENGTH])
354 uint8_t hashed_key[SHA_256_DIGEST_LENGTH];
355 uint8_t ipad[SHA_256_BLOCK_SIZE];
356 uint8_t opad[SHA_256_BLOCK_SIZE];
360 if(key_len > SHA_256_BLOCK_SIZE) {
361 SHA_256.hash(key, key_len, hashed_key);
362 key_len = SHA_256_DIGEST_LENGTH;
365 for(i = 0; i < key_len; i++) {
366 ipad[i] = key[i] ^ 0x36;
367 opad[i] = key[i] ^ 0x5c;
369 for(; i < SHA_256_BLOCK_SIZE; i++) {
375 SHA_256.update(ipad, SHA_256_BLOCK_SIZE);
376 for(j = 0; j < chunks_count; j++) {
377 if(chunks[j].data && chunks[j].data_len) {
378 SHA_256.update(chunks[j].data, chunks[j].data_len);
381 SHA_256.finalize(hmac);
384 SHA_256.update(opad, SHA_256_BLOCK_SIZE);
385 SHA_256.update(hmac, SHA_256_DIGEST_LENGTH);
386 SHA_256.finalize(hmac);
390sha_256_hmac(
const uint8_t *key,
size_t key_len,
391 const uint8_t *data,
size_t data_len,
392 uint8_t hmac[
static SHA_256_DIGEST_LENGTH])
394 struct data_chunk chunk;
397 chunk.data_len = data_len;
398 hmac_over_data_chunks(key, key_len, &chunk, 1, hmac);
402sha_256_hkdf_extract(
const uint8_t *salt,
size_t salt_len,
403 const uint8_t *ikm,
size_t ikm_len,
404 uint8_t prk[
static SHA_256_DIGEST_LENGTH])
406 sha_256_hmac(salt, salt_len, ikm, ikm_len, prk);
410sha_256_hkdf_expand(
const uint8_t *prk,
size_t prk_len,
411 const uint8_t *info,
size_t info_len,
412 uint8_t *okm, uint_fast16_t okm_len)
414 struct data_chunk chunks[3];
417 uint8_t t_i[SHA_256_DIGEST_LENGTH];
419 okm_len = MIN(okm_len, 255 * SHA_256_DIGEST_LENGTH);
420 n = okm_len / SHA_256_DIGEST_LENGTH
421 + (okm_len % SHA_256_DIGEST_LENGTH ? 1 : 0);
423 chunks[0].data = t_i;
424 chunks[0].data_len = SHA_256_DIGEST_LENGTH;
425 chunks[1].data = info;
426 chunks[1].data_len = info_len;
428 chunks[2].data_len = 1;
430 for(i = 1; i <= n; i++) {
431 hmac_over_data_chunks(prk, prk_len,
432 chunks + (i == 1), 3 - (i == 1),
434 memcpy(okm + ((i - 1) * SHA_256_DIGEST_LENGTH),
436 MIN(SHA_256_DIGEST_LENGTH, okm_len));
437 okm_len -= SHA_256_DIGEST_LENGTH;
442sha_256_hkdf(
const uint8_t *salt,
size_t salt_len,
443 const uint8_t *ikm,
size_t ikm_len,
444 const uint8_t *info,
size_t info_len,
445 uint8_t *okm, uint_fast16_t okm_len)
447 uint8_t prk[SHA_256_DIGEST_LENGTH];
449 sha_256_hkdf_extract(salt, salt_len, ikm, ikm_len, prk);
450 sha_256_hkdf_expand(prk,
sizeof(prk), info, info_len, okm, okm_len);
Default definitions of C compiler quirk work-arounds.
Platform-independent SHA-256 API.
void sha_256_hash(const uint8_t *data, size_t len, uint8_t digest[static 32])
Generic implementation of sha_256_driver::hash.
Structure of SHA-256 drivers.
void(* create_checkpoint)(sha_256_checkpoint_t *checkpoint)
Saves the hash session, e.g., before pausing a protothread.
void(* finalize)(uint8_t digest[static 32])
Terminates the hash session and produces the digest.
void(* init)(void)
Starts a hash session.
void(* restore_checkpoint)(const sha_256_checkpoint_t *checkpoint)
Restores a hash session, e.g., after resuming a protothread.
void(* update)(const uint8_t *data, size_t len)
Processes a chunk of data.
Header file for the uIP TCP/IP stack.