]>
git.proxmox.com Git - mirror_frr.git/blob - lib/sha256.c
1 // SPDX-License-Identifier: BSD-2-Clause
3 * Copyright 2005,2007,2009 Colin Percival
10 #if !HAVE_DECL_BE32DEC
11 static inline uint32_t be32dec(const void *pp
)
13 const uint8_t *p
= (uint8_t const *)pp
;
15 return ((uint32_t)(p
[3]) + ((uint32_t)(p
[2]) << 8)
16 + ((uint32_t)(p
[1]) << 16) + ((uint32_t)(p
[0]) << 24));
20 #if !HAVE_DECL_BE32ENC
21 static inline void be32enc(void *pp
, uint32_t x
)
23 uint8_t *p
= (uint8_t *)pp
;
26 p
[2] = (x
>> 8) & 0xff;
27 p
[1] = (x
>> 16) & 0xff;
28 p
[0] = (x
>> 24) & 0xff;
33 * Encode a length len/4 vector of (uint32_t) into a length len vector of
34 * (unsigned char) in big-endian form. Assumes len is a multiple of 4.
36 static void be32enc_vect(unsigned char *dst
, const uint32_t *src
, size_t len
)
40 for (i
= 0; i
< len
/ 4; i
++)
41 be32enc(dst
+ i
* 4, src
[i
]);
45 * Decode a big-endian length len vector of (unsigned char) into a length
46 * len/4 vector of (uint32_t). Assumes len is a multiple of 4.
48 static void be32dec_vect(uint32_t *dst
, const unsigned char *src
, size_t len
)
52 for (i
= 0; i
< len
/ 4; i
++)
53 dst
[i
] = be32dec(src
+ i
* 4);
56 /* Elementary functions used by SHA256 */
57 #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
58 #define Maj(x, y, z) ((x & (y | z)) | (y & z))
59 #define SHR(x, n) (x >> n)
60 #define ROTR(x, n) ((x >> n) | (x << (32 - n)))
61 #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
62 #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
63 #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
64 #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
66 /* SHA256 round function */
67 #define RND(a, b, c, d, e, f, g, h, k) \
68 t0 = h + S1(e) + Ch(e, f, g) + k; \
69 t1 = S0(a) + Maj(a, b, c); \
73 /* Adjusted round function for rotating state */
74 #define RNDr(S, W, i, k) \
75 RND(S[(64 - i) % 8], S[(65 - i) % 8], S[(66 - i) % 8], \
76 S[(67 - i) % 8], S[(68 - i) % 8], S[(69 - i) % 8], \
77 S[(70 - i) % 8], S[(71 - i) % 8], W[i] + k)
80 * SHA256 block compression function. The 256-bit state is transformed via
81 * the 512-bit input block to produce a new state.
83 static void SHA256_Transform(uint32_t *state
, const unsigned char block
[64])
90 /* 1. Prepare message schedule W. */
91 be32dec_vect(W
, block
, 64);
92 for (i
= 16; i
< 64; i
++)
93 W
[i
] = s1(W
[i
- 2]) + W
[i
- 7] + s0(W
[i
- 15]) + W
[i
- 16];
95 /* 2. Initialize working variables. */
99 RNDr(S
, W
, 0, 0x428a2f98);
100 RNDr(S
, W
, 1, 0x71374491);
101 RNDr(S
, W
, 2, 0xb5c0fbcf);
102 RNDr(S
, W
, 3, 0xe9b5dba5);
103 RNDr(S
, W
, 4, 0x3956c25b);
104 RNDr(S
, W
, 5, 0x59f111f1);
105 RNDr(S
, W
, 6, 0x923f82a4);
106 RNDr(S
, W
, 7, 0xab1c5ed5);
107 RNDr(S
, W
, 8, 0xd807aa98);
108 RNDr(S
, W
, 9, 0x12835b01);
109 RNDr(S
, W
, 10, 0x243185be);
110 RNDr(S
, W
, 11, 0x550c7dc3);
111 RNDr(S
, W
, 12, 0x72be5d74);
112 RNDr(S
, W
, 13, 0x80deb1fe);
113 RNDr(S
, W
, 14, 0x9bdc06a7);
114 RNDr(S
, W
, 15, 0xc19bf174);
115 RNDr(S
, W
, 16, 0xe49b69c1);
116 RNDr(S
, W
, 17, 0xefbe4786);
117 RNDr(S
, W
, 18, 0x0fc19dc6);
118 RNDr(S
, W
, 19, 0x240ca1cc);
119 RNDr(S
, W
, 20, 0x2de92c6f);
120 RNDr(S
, W
, 21, 0x4a7484aa);
121 RNDr(S
, W
, 22, 0x5cb0a9dc);
122 RNDr(S
, W
, 23, 0x76f988da);
123 RNDr(S
, W
, 24, 0x983e5152);
124 RNDr(S
, W
, 25, 0xa831c66d);
125 RNDr(S
, W
, 26, 0xb00327c8);
126 RNDr(S
, W
, 27, 0xbf597fc7);
127 RNDr(S
, W
, 28, 0xc6e00bf3);
128 RNDr(S
, W
, 29, 0xd5a79147);
129 RNDr(S
, W
, 30, 0x06ca6351);
130 RNDr(S
, W
, 31, 0x14292967);
131 RNDr(S
, W
, 32, 0x27b70a85);
132 RNDr(S
, W
, 33, 0x2e1b2138);
133 RNDr(S
, W
, 34, 0x4d2c6dfc);
134 RNDr(S
, W
, 35, 0x53380d13);
135 RNDr(S
, W
, 36, 0x650a7354);
136 RNDr(S
, W
, 37, 0x766a0abb);
137 RNDr(S
, W
, 38, 0x81c2c92e);
138 RNDr(S
, W
, 39, 0x92722c85);
139 RNDr(S
, W
, 40, 0xa2bfe8a1);
140 RNDr(S
, W
, 41, 0xa81a664b);
141 RNDr(S
, W
, 42, 0xc24b8b70);
142 RNDr(S
, W
, 43, 0xc76c51a3);
143 RNDr(S
, W
, 44, 0xd192e819);
144 RNDr(S
, W
, 45, 0xd6990624);
145 RNDr(S
, W
, 46, 0xf40e3585);
146 RNDr(S
, W
, 47, 0x106aa070);
147 RNDr(S
, W
, 48, 0x19a4c116);
148 RNDr(S
, W
, 49, 0x1e376c08);
149 RNDr(S
, W
, 50, 0x2748774c);
150 RNDr(S
, W
, 51, 0x34b0bcb5);
151 RNDr(S
, W
, 52, 0x391c0cb3);
152 RNDr(S
, W
, 53, 0x4ed8aa4a);
153 RNDr(S
, W
, 54, 0x5b9cca4f);
154 RNDr(S
, W
, 55, 0x682e6ff3);
155 RNDr(S
, W
, 56, 0x748f82ee);
156 RNDr(S
, W
, 57, 0x78a5636f);
157 RNDr(S
, W
, 58, 0x84c87814);
158 RNDr(S
, W
, 59, 0x8cc70208);
159 RNDr(S
, W
, 60, 0x90befffa);
160 RNDr(S
, W
, 61, 0xa4506ceb);
161 RNDr(S
, W
, 62, 0xbef9a3f7);
162 RNDr(S
, W
, 63, 0xc67178f2);
164 /* 4. Mix local working variables into global state */
165 for (i
= 0; i
< 8; i
++)
168 /* Clean the stack. */
169 explicit_bzero(W
, 256);
170 explicit_bzero(S
, 32);
171 explicit_bzero(&t0
, sizeof(t0
));
172 explicit_bzero(&t1
, sizeof(t0
));
175 static unsigned char PAD
[64] = {
176 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
180 /* Add padding and terminating bit-count. */
181 static void SHA256_Pad(SHA256_CTX
*ctx
)
183 unsigned char len
[8];
187 * Convert length to a vector of bytes -- we do this now rather
188 * than later because the length will change after we pad.
190 be32enc_vect(len
, ctx
->count
, 8);
192 /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
193 r
= (ctx
->count
[1] >> 3) & 0x3f;
194 plen
= (r
< 56) ? (56 - r
) : (120 - r
);
195 SHA256_Update(ctx
, PAD
, (size_t)plen
);
197 /* Add the terminating bit-count */
198 SHA256_Update(ctx
, len
, 8);
201 /* SHA-256 initialization. Begins a SHA-256 operation. */
202 void SHA256_Init(SHA256_CTX
*ctx
)
205 /* Zero bits processed so far */
206 ctx
->count
[0] = ctx
->count
[1] = 0;
208 /* Magic initialization constants */
209 ctx
->state
[0] = 0x6A09E667;
210 ctx
->state
[1] = 0xBB67AE85;
211 ctx
->state
[2] = 0x3C6EF372;
212 ctx
->state
[3] = 0xA54FF53A;
213 ctx
->state
[4] = 0x510E527F;
214 ctx
->state
[5] = 0x9B05688C;
215 ctx
->state
[6] = 0x1F83D9AB;
216 ctx
->state
[7] = 0x5BE0CD19;
219 /* Add bytes into the hash */
220 void SHA256_Update(SHA256_CTX
*ctx
, const void *in
, size_t len
)
224 const unsigned char *src
= in
;
226 /* Number of bytes left in the buffer from previous updates */
227 r
= (ctx
->count
[1] >> 3) & 0x3f;
229 /* Convert the length into a number of bits */
230 bitlen
[1] = ((uint32_t)len
) << 3;
231 bitlen
[0] = (uint32_t)(len
>> 29);
233 /* Update number of bits */
234 if ((ctx
->count
[1] += bitlen
[1]) < bitlen
[1])
236 ctx
->count
[0] += bitlen
[0];
238 /* Handle the case where we don't need to perform any transforms */
240 memcpy(&ctx
->buf
[r
], src
, len
);
244 /* Finish the current block */
245 memcpy(&ctx
->buf
[r
], src
, 64 - r
);
246 SHA256_Transform(ctx
->state
, ctx
->buf
);
250 /* Perform complete blocks */
252 SHA256_Transform(ctx
->state
, src
);
257 /* Copy left over data into buffer */
258 memcpy(ctx
->buf
, src
, len
);
262 * SHA-256 finalization. Pads the input data, exports the hash value,
263 * and clears the context state.
265 void SHA256_Final(unsigned char digest
[32], SHA256_CTX
*ctx
)
272 be32enc_vect(digest
, ctx
->state
, 32);
274 /* Clear the context state */
275 explicit_bzero((void *)ctx
, sizeof(*ctx
));
278 /* Initialize an HMAC-SHA256 operation with the given key. */
279 void HMAC__SHA256_Init(HMAC_SHA256_CTX
*ctx
, const void *_K
, size_t Klen
)
281 unsigned char pad
[64];
282 unsigned char khash
[32];
283 const unsigned char *K
= _K
;
286 /* If Klen > 64, the key is really SHA256(K). */
288 SHA256_Init(&ctx
->ictx
);
289 SHA256_Update(&ctx
->ictx
, K
, Klen
);
290 SHA256_Final(khash
, &ctx
->ictx
);
295 /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
296 SHA256_Init(&ctx
->ictx
);
297 memset(pad
, 0x36, 64);
298 for (i
= 0; i
< Klen
; i
++)
300 SHA256_Update(&ctx
->ictx
, pad
, 64);
302 /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
303 SHA256_Init(&ctx
->octx
);
304 memset(pad
, 0x5c, 64);
305 for (i
= 0; i
< Klen
; i
++)
307 SHA256_Update(&ctx
->octx
, pad
, 64);
309 /* Clean the stack. */
310 explicit_bzero(khash
, 32);
313 /* Add bytes to the HMAC-SHA256 operation. */
314 void HMAC__SHA256_Update(HMAC_SHA256_CTX
*ctx
, const void *in
, size_t len
)
317 /* Feed data to the inner SHA256 operation. */
318 SHA256_Update(&ctx
->ictx
, in
, len
);
321 /* Finish an HMAC-SHA256 operation. */
322 void HMAC__SHA256_Final(unsigned char digest
[32], HMAC_SHA256_CTX
*ctx
)
324 unsigned char ihash
[32];
326 /* Finish the inner SHA256 operation. */
327 SHA256_Final(ihash
, &ctx
->ictx
);
329 /* Feed the inner hash to the outer SHA256 operation. */
330 SHA256_Update(&ctx
->octx
, ihash
, 32);
332 /* Finish the outer SHA256 operation. */
333 SHA256_Final(digest
, &ctx
->octx
);
335 /* Clean the stack. */
336 explicit_bzero(ihash
, 32);
340 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
341 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
342 * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
344 void PBKDF2_SHA256(const uint8_t *passwd
, size_t passwdlen
, const uint8_t *salt
,
345 size_t saltlen
, uint64_t c
, uint8_t *buf
, size_t dkLen
)
347 HMAC_SHA256_CTX PShctx
, hctx
;
356 /* Compute HMAC state after processing P and S. */
357 HMAC__SHA256_Init(&PShctx
, passwd
, passwdlen
);
358 HMAC__SHA256_Update(&PShctx
, salt
, saltlen
);
360 /* Iterate through the blocks. */
361 for (i
= 0; i
* 32 < dkLen
; i
++) {
362 /* Generate INT(i + 1). */
363 be32enc(ivec
, (uint32_t)(i
+ 1));
365 /* Compute U_1 = PRF(P, S || INT(i)). */
366 memcpy(&hctx
, &PShctx
, sizeof(HMAC_SHA256_CTX
));
367 HMAC__SHA256_Update(&hctx
, ivec
, 4);
368 HMAC__SHA256_Final(U
, &hctx
);
373 for (j
= 2; j
<= c
; j
++) {
375 HMAC__SHA256_Init(&hctx
, passwd
, passwdlen
);
376 HMAC__SHA256_Update(&hctx
, U
, 32);
377 HMAC__SHA256_Final(U
, &hctx
);
379 /* ... xor U_j ... */
380 for (k
= 0; k
< 32; k
++)
384 /* Copy as many bytes as necessary into buf. */
385 clen
= dkLen
- i
* 32;
388 memcpy(&buf
[i
* 32], T
, clen
);
391 /* Clean PShctx, since we never called _Final on it. */
392 explicit_bzero(&PShctx
, sizeof(HMAC_SHA256_CTX
));