40#if UIP_BYTE_ORDER != UIP_LITTLE_ENDIAN
42#define be32enc_vect memcpy
45#define be32dec_vect memcpy
48be64enc(uint8_t *p, uint64_t u)
50 memcpy(p, &u,
sizeof(uint64_t));
55be32dec(uint8_t
const *p)
57 return ((uint32_t)p[0] << 24)
58 | ((uint32_t)p[1] << 16)
59 | ((uint32_t)p[2] << 8)
64be32enc(uint8_t *p, uint32_t u)
66 p[0] = (u >> 24) & 0xff;
67 p[1] = (u >> 16) & 0xff;
68 p[2] = (u >> 8) & 0xff;
73be64enc(uint8_t *p, uint64_t u)
75 be32enc(p, (uint32_t)(u >> 32));
76 be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
84be32enc_vect(uint8_t *dst,
const uint32_t *src,
size_t len)
88 for(i = 0; i < len / 4; i++) {
89 be32enc(dst + i * 4, src[i]);
98be32dec_vect(uint32_t *dst,
const uint8_t *src,
size_t len)
102 for(i = 0; i < len / 4; i++) {
103 dst[i] = be32dec(src + i * 4);
108static const uint32_t K[64] = {
109 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
110 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
111 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
112 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
113 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
114 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
115 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
116 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
117 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
118 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
119 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
120 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
121 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
122 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
123 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
124 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
128#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
129#define Maj(x, y, z) ((x & (y | z)) | (y & z))
130#define SHR(x, n) (x >> n)
131#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
132#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
133#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
134#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
135#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
138#define RND(a, b, c, d, e, f, g, h, k) \
139 h += S1(e) + Ch(e, f, g) + k; \
141 h += S0(a) + Maj(a, b, c);
144#define RNDr(S, W, i, ii) \
145 RND(S[(64 - i) % 8], S[(65 - i) % 8], \
146 S[(66 - i) % 8], S[(67 - i) % 8], \
147 S[(68 - i) % 8], S[(69 - i) % 8], \
148 S[(70 - i) % 8], S[(71 - i) % 8], \
149 W[i + ii] + K[i + ii])
152#define MSCH(W, ii, i) \
153 W[i + ii + 16] = s1(W[i + ii + 14]) \
155 + s0(W[i + ii + 1]) \
158static sha_256_checkpoint_t checkpoint;
166transform(
const uint8_t block[
static SHA_256_BLOCK_SIZE])
173 be32dec_vect(W, block, 64);
176 memcpy(S, checkpoint.state, 32);
179 for(i = 0; i < 64; i += 16) {
219 for(i = 0; i < 8; i++) {
220 checkpoint.state[i] += S[i];
228 static const unsigned char PAD[64] = {
229 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
236 if(checkpoint.buf_len < 56) {
238 memcpy(&checkpoint.buf[checkpoint.buf_len], PAD, 56 - checkpoint.buf_len);
241 memcpy(&checkpoint.buf[checkpoint.buf_len], PAD,
242 SHA_256_BLOCK_SIZE - checkpoint.buf_len);
243 transform(checkpoint.buf);
246 memset(&checkpoint.buf[0], 0, 56);
250 be64enc(&checkpoint.buf[56], checkpoint.bit_count);
253 transform(checkpoint.buf);
261 checkpoint.bit_count = 0;
262 checkpoint.buf_len = 0;
265 checkpoint.state[0] = 0x6A09E667;
266 checkpoint.state[1] = 0xBB67AE85;
267 checkpoint.state[2] = 0x3C6EF372;
268 checkpoint.state[3] = 0xA54FF53A;
269 checkpoint.state[4] = 0x510E527F;
270 checkpoint.state[5] = 0x9B05688C;
271 checkpoint.state[6] = 0x1F83D9AB;
272 checkpoint.state[7] = 0x5BE0CD19;
277update(
const uint8_t *data,
size_t len)
285 checkpoint.bit_count += bitlen;
288 if(len < SHA_256_BLOCK_SIZE - checkpoint.buf_len) {
289 memcpy(&checkpoint.buf[checkpoint.buf_len], data, len);
290 checkpoint.buf_len += len;
295 memcpy(&checkpoint.buf[checkpoint.buf_len],
297 SHA_256_BLOCK_SIZE - checkpoint.buf_len);
298 transform(checkpoint.buf);
299 data += SHA_256_BLOCK_SIZE - checkpoint.buf_len;
300 len -= SHA_256_BLOCK_SIZE - checkpoint.buf_len;
301 checkpoint.buf_len = 0;
306 data += SHA_256_BLOCK_SIZE;
307 len -= SHA_256_BLOCK_SIZE;
311 memcpy(checkpoint.buf, data, len);
312 checkpoint.buf_len += len;
320finalize(uint8_t digest[
static SHA_256_DIGEST_LENGTH])
326 be32enc_vect(digest, checkpoint.state, SHA_256_DIGEST_LENGTH);
329 memset(&checkpoint.buf, 0,
sizeof(checkpoint.buf));
330 memset(&checkpoint.state, 0,
sizeof(checkpoint.state));
334create_checkpoint(sha_256_checkpoint_t *cp)
336 memcpy(cp, &checkpoint,
sizeof(*cp));
340restore_checkpoint(
const sha_256_checkpoint_t *cp)
342 memcpy(&checkpoint, cp,
sizeof(checkpoint));
346sha_256_hash(
const uint8_t *data,
size_t len,
347 uint8_t digest[
static SHA_256_DIGEST_LENGTH])
350 SHA_256.update(data, len);
351 SHA_256.finalize(digest);
357 uint8_t hashed_key[SHA_256_DIGEST_LENGTH];
358 uint8_t ipad[SHA_256_BLOCK_SIZE];
361 if(key_len > SHA_256_BLOCK_SIZE) {
362 SHA_256.hash(key, key_len, hashed_key);
363 key_len = SHA_256_DIGEST_LENGTH;
366 for(i = 0; i < key_len; i++) {
367 ipad[i] = key[i] ^ 0x36;
368 checkpoint.opad[i] = key[i] ^ 0x5c;
370 for(; i < SHA_256_BLOCK_SIZE; i++) {
372 checkpoint.opad[i] = 0x5c;
376 SHA_256.update(ipad,
sizeof(ipad));
382 SHA_256.update(data, data_len);
386sha_256_hmac_finish(uint8_t hmac[SHA_256_DIGEST_LENGTH])
388 SHA_256.finalize(hmac);
390 SHA_256.update(checkpoint.opad,
sizeof(checkpoint.opad));
391 SHA_256.update(hmac, SHA_256_DIGEST_LENGTH);
392 SHA_256.finalize(hmac);
393 memset(&checkpoint.opad, 0,
sizeof(checkpoint.opad));
397sha_256_hmac(
const uint8_t *key,
size_t key_len,
398 const uint8_t *data,
size_t data_len,
399 uint8_t hmac[
static SHA_256_DIGEST_LENGTH])
403 sha_256_hmac_finish(hmac);
407sha_256_hkdf_extract(
const uint8_t *salt,
size_t salt_len,
408 const uint8_t *ikm,
size_t ikm_len,
409 uint8_t prk[
static SHA_256_DIGEST_LENGTH])
411 sha_256_hmac(salt, salt_len, ikm, ikm_len, prk);
416 const uint8_t *info,
size_t info_len,
417 uint8_t *okm, uint_fast16_t okm_len)
421 uint8_t t_i[SHA_256_DIGEST_LENGTH];
423 okm_len = MIN(okm_len, 255 * SHA_256_DIGEST_LENGTH);
424 n = okm_len / SHA_256_DIGEST_LENGTH
425 + (okm_len % SHA_256_DIGEST_LENGTH ? 1 : 0);
427 for(i = 1; i <= n; i++) {
434 sha_256_hmac_finish(t_i);
435 memcpy(okm + ((i - 1) * SHA_256_DIGEST_LENGTH),
437 MIN(SHA_256_DIGEST_LENGTH, okm_len));
438 okm_len -= SHA_256_DIGEST_LENGTH;
444 const uint8_t *ikm,
size_t ikm_len,
445 const uint8_t *info,
size_t info_len,
446 uint8_t *okm, uint_fast16_t okm_len)
448 uint8_t prk[SHA_256_DIGEST_LENGTH];
450 sha_256_hkdf_extract(salt, salt_len, ikm, ikm_len, prk);
Default definitions of C compiler quirk work-arounds.
void sha_256_hmac_update(const uint8_t *data, size_t data_len)
Proceeds with the computation of an HMAC-SHA-256.
void sha_256_hkdf(const uint8_t *salt, size_t salt_len, const uint8_t *ikm, size_t ikm_len, const uint8_t *info, size_t info_len, uint8_t *okm, uint_fast16_t okm_len)
Performs both extraction and expansion as per RFC 5869.
void sha_256_hkdf_expand(const uint8_t *prk, size_t prk_len, const uint8_t *info, size_t info_len, uint8_t *okm, uint_fast16_t okm_len)
Expands a key as per RFC 5869.
void sha_256_hmac_init(const uint8_t *key, size_t key_len)
Initiates a stepwise HMAC-SHA-256 computation.
void sha_256_hash(const uint8_t *data, size_t len, uint8_t digest[static 32])
Generic implementation of sha_256_driver::hash.
Platform-independent SHA-256 API.
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.