Coverage Report

Created: 2026-07-30 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/lib/sha256.c
Line
Count
Source
1
// SPDX-License-Identifier: BSD-2-Clause
2
/*-
3
 * Copyright 2005,2007,2009 Colin Percival
4
 * All rights reserved.
5
 */
6
7
#include <zebra.h>
8
#include "sha256.h"
9
10
#if !HAVE_DECL_BE32DEC
11
static inline uint32_t be32dec(const void *pp)
12
0
{
13
0
  const uint8_t *p = (uint8_t const *)pp;
14
15
0
  return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8)
16
0
    + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
17
0
}
18
#endif
19
20
#if !HAVE_DECL_BE32ENC
21
static inline void be32enc(void *pp, uint32_t x)
22
0
{
23
0
  uint8_t *p = (uint8_t *)pp;
24
25
0
  p[3] = x & 0xff;
26
0
  p[2] = (x >> 8) & 0xff;
27
0
  p[1] = (x >> 16) & 0xff;
28
0
  p[0] = (x >> 24) & 0xff;
29
0
}
30
#endif
31
32
/*
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.
35
 */
36
static void be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
37
0
{
38
0
  size_t i;
39
40
0
  for (i = 0; i < len / 4; i++)
41
0
    be32enc(dst + i * 4, src[i]);
42
0
}
43
44
/*
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.
47
 */
48
static void be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
49
0
{
50
0
  size_t i;
51
52
0
  for (i = 0; i < len / 4; i++)
53
0
    dst[i] = be32dec(src + i * 4);
54
0
}
55
56
/* Elementary functions used by SHA256 */
57
0
#define Ch(x, y, z)     ((x & (y ^ z)) ^ z)
58
0
#define Maj(x, y, z)    ((x & (y | z)) | (y & z))
59
0
#define SHR(x, n)       (x >> n)
60
0
#define ROTR(x, n)      ((x >> n) | (x << (32 - n)))
61
0
#define S0(x)           (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
62
0
#define S1(x)           (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
63
0
#define s0(x)           (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
64
0
#define s1(x)           (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
65
66
/* SHA256 round function */
67
#define RND(a, b, c, d, e, f, g, h, k)                                         \
68
0
  t0 = h + S1(e) + Ch(e, f, g) + k;                                      \
69
0
  t1 = S0(a) + Maj(a, b, c);                                             \
70
0
  d += t0;                                                               \
71
0
  h = t0 + t1;
72
73
/* Adjusted round function for rotating state */
74
#define RNDr(S, W, i, k)                                                       \
75
0
  RND(S[(64 - i) % 8], S[(65 - i) % 8], S[(66 - i) % 8],                 \
76
0
      S[(67 - i) % 8], S[(68 - i) % 8], S[(69 - i) % 8],                 \
77
0
      S[(70 - i) % 8], S[(71 - i) % 8], W[i] + k)
78
79
/*
80
 * SHA256 block compression function.  The 256-bit state is transformed via
81
 * the 512-bit input block to produce a new state.
82
 */
83
static void SHA256_Transform(uint32_t *state, const unsigned char block[64])
84
0
{
85
0
  uint32_t W[64];
86
0
  uint32_t S[8];
87
0
  uint32_t t0, t1;
88
0
  int i;
89
90
  /* 1. Prepare message schedule W. */
91
0
  be32dec_vect(W, block, 64);
92
0
  for (i = 16; i < 64; i++)
93
0
    W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
94
95
  /* 2. Initialize working variables. */
96
0
  memcpy(S, state, 32);
97
98
  /* 3. Mix. */
99
0
  RNDr(S, W, 0, 0x428a2f98);
100
0
  RNDr(S, W, 1, 0x71374491);
101
0
  RNDr(S, W, 2, 0xb5c0fbcf);
102
0
  RNDr(S, W, 3, 0xe9b5dba5);
103
0
  RNDr(S, W, 4, 0x3956c25b);
104
0
  RNDr(S, W, 5, 0x59f111f1);
105
0
  RNDr(S, W, 6, 0x923f82a4);
106
0
  RNDr(S, W, 7, 0xab1c5ed5);
107
0
  RNDr(S, W, 8, 0xd807aa98);
108
0
  RNDr(S, W, 9, 0x12835b01);
109
0
  RNDr(S, W, 10, 0x243185be);
110
0
  RNDr(S, W, 11, 0x550c7dc3);
111
0
  RNDr(S, W, 12, 0x72be5d74);
112
0
  RNDr(S, W, 13, 0x80deb1fe);
113
0
  RNDr(S, W, 14, 0x9bdc06a7);
114
0
  RNDr(S, W, 15, 0xc19bf174);
115
0
  RNDr(S, W, 16, 0xe49b69c1);
116
0
  RNDr(S, W, 17, 0xefbe4786);
117
0
  RNDr(S, W, 18, 0x0fc19dc6);
118
0
  RNDr(S, W, 19, 0x240ca1cc);
119
0
  RNDr(S, W, 20, 0x2de92c6f);
120
0
  RNDr(S, W, 21, 0x4a7484aa);
121
0
  RNDr(S, W, 22, 0x5cb0a9dc);
122
0
  RNDr(S, W, 23, 0x76f988da);
123
0
  RNDr(S, W, 24, 0x983e5152);
124
0
  RNDr(S, W, 25, 0xa831c66d);
125
0
  RNDr(S, W, 26, 0xb00327c8);
126
0
  RNDr(S, W, 27, 0xbf597fc7);
127
0
  RNDr(S, W, 28, 0xc6e00bf3);
128
0
  RNDr(S, W, 29, 0xd5a79147);
129
0
  RNDr(S, W, 30, 0x06ca6351);
130
0
  RNDr(S, W, 31, 0x14292967);
131
0
  RNDr(S, W, 32, 0x27b70a85);
132
0
  RNDr(S, W, 33, 0x2e1b2138);
133
0
  RNDr(S, W, 34, 0x4d2c6dfc);
134
0
  RNDr(S, W, 35, 0x53380d13);
135
0
  RNDr(S, W, 36, 0x650a7354);
136
0
  RNDr(S, W, 37, 0x766a0abb);
137
0
  RNDr(S, W, 38, 0x81c2c92e);
138
0
  RNDr(S, W, 39, 0x92722c85);
139
0
  RNDr(S, W, 40, 0xa2bfe8a1);
140
0
  RNDr(S, W, 41, 0xa81a664b);
141
0
  RNDr(S, W, 42, 0xc24b8b70);
142
0
  RNDr(S, W, 43, 0xc76c51a3);
143
0
  RNDr(S, W, 44, 0xd192e819);
144
0
  RNDr(S, W, 45, 0xd6990624);
145
0
  RNDr(S, W, 46, 0xf40e3585);
146
0
  RNDr(S, W, 47, 0x106aa070);
147
0
  RNDr(S, W, 48, 0x19a4c116);
148
0
  RNDr(S, W, 49, 0x1e376c08);
149
0
  RNDr(S, W, 50, 0x2748774c);
150
0
  RNDr(S, W, 51, 0x34b0bcb5);
151
0
  RNDr(S, W, 52, 0x391c0cb3);
152
0
  RNDr(S, W, 53, 0x4ed8aa4a);
153
0
  RNDr(S, W, 54, 0x5b9cca4f);
154
0
  RNDr(S, W, 55, 0x682e6ff3);
155
0
  RNDr(S, W, 56, 0x748f82ee);
156
0
  RNDr(S, W, 57, 0x78a5636f);
157
0
  RNDr(S, W, 58, 0x84c87814);
158
0
  RNDr(S, W, 59, 0x8cc70208);
159
0
  RNDr(S, W, 60, 0x90befffa);
160
0
  RNDr(S, W, 61, 0xa4506ceb);
161
0
  RNDr(S, W, 62, 0xbef9a3f7);
162
0
  RNDr(S, W, 63, 0xc67178f2);
163
164
  /* 4. Mix local working variables into global state */
165
0
  for (i = 0; i < 8; i++)
166
0
    state[i] += S[i];
167
168
  /* Clean the stack. */
169
0
  explicit_bzero(W, 256);
170
0
  explicit_bzero(S, 32);
171
0
  explicit_bzero(&t0, sizeof(t0));
172
0
  explicit_bzero(&t1, sizeof(t0));
173
0
}
174
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};
179
180
/* Add padding and terminating bit-count. */
181
static void SHA256_Pad(SHA256_CTX *ctx)
182
0
{
183
0
  unsigned char len[8];
184
0
  uint32_t r, plen;
185
186
  /*
187
   * Convert length to a vector of bytes -- we do this now rather
188
   * than later because the length will change after we pad.
189
   */
190
0
  be32enc_vect(len, ctx->count, 8);
191
192
  /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
193
0
  r = (ctx->count[1] >> 3) & 0x3f;
194
0
  plen = (r < 56) ? (56 - r) : (120 - r);
195
0
  SHA256_Update(ctx, PAD, (size_t)plen);
196
197
  /* Add the terminating bit-count */
198
0
  SHA256_Update(ctx, len, 8);
199
0
}
200
201
/* SHA-256 initialization.  Begins a SHA-256 operation. */
202
void SHA256_Init(SHA256_CTX *ctx)
203
0
{
204
205
  /* Zero bits processed so far */
206
0
  ctx->count[0] = ctx->count[1] = 0;
207
208
  /* Magic initialization constants */
209
0
  ctx->state[0] = 0x6A09E667;
210
0
  ctx->state[1] = 0xBB67AE85;
211
0
  ctx->state[2] = 0x3C6EF372;
212
0
  ctx->state[3] = 0xA54FF53A;
213
0
  ctx->state[4] = 0x510E527F;
214
0
  ctx->state[5] = 0x9B05688C;
215
0
  ctx->state[6] = 0x1F83D9AB;
216
0
  ctx->state[7] = 0x5BE0CD19;
217
0
}
218
219
/* Add bytes into the hash */
220
void SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len)
221
0
{
222
0
  uint32_t bitlen[2];
223
0
  uint32_t r;
224
0
  const unsigned char *src = in;
225
226
  /* Number of bytes left in the buffer from previous updates */
227
0
  r = (ctx->count[1] >> 3) & 0x3f;
228
229
  /* Convert the length into a number of bits */
230
0
  bitlen[1] = ((uint32_t)len) << 3;
231
0
  bitlen[0] = (uint32_t)(len >> 29);
232
233
  /* Update number of bits */
234
0
  if ((ctx->count[1] += bitlen[1]) < bitlen[1])
235
0
    ctx->count[0]++;
236
0
  ctx->count[0] += bitlen[0];
237
238
  /* Handle the case where we don't need to perform any transforms */
239
0
  if (len < 64 - r) {
240
0
    memcpy(&ctx->buf[r], src, len);
241
0
    return;
242
0
  }
243
244
  /* Finish the current block */
245
0
  memcpy(&ctx->buf[r], src, 64 - r);
246
0
  SHA256_Transform(ctx->state, ctx->buf);
247
0
  src += 64 - r;
248
0
  len -= 64 - r;
249
250
  /* Perform complete blocks */
251
0
  while (len >= 64) {
252
0
    SHA256_Transform(ctx->state, src);
253
0
    src += 64;
254
0
    len -= 64;
255
0
  }
256
257
  /* Copy left over data into buffer */
258
0
  memcpy(ctx->buf, src, len);
259
0
}
260
261
/*
262
 * SHA-256 finalization.  Pads the input data, exports the hash value,
263
 * and clears the context state.
264
 */
265
void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
266
0
{
267
268
  /* Add padding */
269
0
  SHA256_Pad(ctx);
270
271
  /* Write the hash */
272
0
  be32enc_vect(digest, ctx->state, 32);
273
274
  /* Clear the context state */
275
0
  explicit_bzero((void *)ctx, sizeof(*ctx));
276
0
}
277
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)
280
0
{
281
0
  unsigned char pad[64];
282
0
  unsigned char khash[32];
283
0
  const unsigned char *K = _K;
284
0
  size_t i;
285
286
  /* If Klen > 64, the key is really SHA256(K). */
287
0
  if (Klen > 64) {
288
0
    SHA256_Init(&ctx->ictx);
289
0
    SHA256_Update(&ctx->ictx, K, Klen);
290
0
    SHA256_Final(khash, &ctx->ictx);
291
0
    K = khash;
292
0
    Klen = 32;
293
0
  }
294
295
  /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
296
0
  SHA256_Init(&ctx->ictx);
297
0
  memset(pad, 0x36, 64);
298
0
  for (i = 0; i < Klen; i++)
299
0
    pad[i] ^= K[i];
300
0
  SHA256_Update(&ctx->ictx, pad, 64);
301
302
  /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
303
0
  SHA256_Init(&ctx->octx);
304
0
  memset(pad, 0x5c, 64);
305
0
  for (i = 0; i < Klen; i++)
306
0
    pad[i] ^= K[i];
307
0
  SHA256_Update(&ctx->octx, pad, 64);
308
309
  /* Clean the stack. */
310
0
  explicit_bzero(khash, 32);
311
0
}
312
313
/* Add bytes to the HMAC-SHA256 operation. */
314
void HMAC__SHA256_Update(HMAC_SHA256_CTX *ctx, const void *in, size_t len)
315
0
{
316
317
  /* Feed data to the inner SHA256 operation. */
318
0
  SHA256_Update(&ctx->ictx, in, len);
319
0
}
320
321
/* Finish an HMAC-SHA256 operation. */
322
void HMAC__SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX *ctx)
323
0
{
324
0
  unsigned char ihash[32];
325
326
  /* Finish the inner SHA256 operation. */
327
0
  SHA256_Final(ihash, &ctx->ictx);
328
329
  /* Feed the inner hash to the outer SHA256 operation. */
330
0
  SHA256_Update(&ctx->octx, ihash, 32);
331
332
  /* Finish the outer SHA256 operation. */
333
0
  SHA256_Final(digest, &ctx->octx);
334
335
  /* Clean the stack. */
336
0
  explicit_bzero(ihash, 32);
337
0
}
338
339
/**
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).
343
 */
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)
346
0
{
347
0
  HMAC_SHA256_CTX PShctx, hctx;
348
0
  size_t i;
349
0
  uint8_t ivec[4];
350
0
  uint8_t U[32];
351
0
  uint8_t T[32];
352
0
  uint64_t j;
353
0
  int k;
354
0
  size_t clen;
355
356
  /* Compute HMAC state after processing P and S. */
357
0
  HMAC__SHA256_Init(&PShctx, passwd, passwdlen);
358
0
  HMAC__SHA256_Update(&PShctx, salt, saltlen);
359
360
  /* Iterate through the blocks. */
361
0
  for (i = 0; i * 32 < dkLen; i++) {
362
    /* Generate INT(i + 1). */
363
0
    be32enc(ivec, (uint32_t)(i + 1));
364
365
    /* Compute U_1 = PRF(P, S || INT(i)). */
366
0
    memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
367
0
    HMAC__SHA256_Update(&hctx, ivec, 4);
368
0
    HMAC__SHA256_Final(U, &hctx);
369
370
    /* T_i = U_1 ... */
371
0
    memcpy(T, U, 32);
372
373
0
    for (j = 2; j <= c; j++) {
374
      /* Compute U_j. */
375
0
      HMAC__SHA256_Init(&hctx, passwd, passwdlen);
376
0
      HMAC__SHA256_Update(&hctx, U, 32);
377
0
      HMAC__SHA256_Final(U, &hctx);
378
379
      /* ... xor U_j ... */
380
0
      for (k = 0; k < 32; k++)
381
0
        T[k] ^= U[k];
382
0
    }
383
384
    /* Copy as many bytes as necessary into buf. */
385
0
    clen = dkLen - i * 32;
386
0
    if (clen > 32)
387
0
      clen = 32;
388
0
    memcpy(&buf[i * 32], T, clen);
389
0
  }
390
391
  /* Clean PShctx, since we never called _Final on it. */
392
0
  explicit_bzero(&PShctx, sizeof(HMAC_SHA256_CTX));
393
0
}