Coverage Report

Created: 2026-09-14 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/hash/hash_sha.c
Line
Count
Source
1
/*
2
  +----------------------------------------------------------------------+
3
  | Copyright © The PHP Group and Contributors.                          |
4
  +----------------------------------------------------------------------+
5
  | This source file is subject to the Modified BSD License that is      |
6
  | bundled with this package in the file LICENSE, and is available      |
7
  | through the World Wide Web at <https://www.php.net/license/>.        |
8
  |                                                                      |
9
  | SPDX-License-Identifier: BSD-3-Clause                                |
10
  +----------------------------------------------------------------------+
11
  | Authors: Steffan Esser <sesser@php.net>                              |
12
  |          Sara Golemon <pollita@php.net>                              |
13
  +----------------------------------------------------------------------+
14
*/
15
16
#include "php_hash.h"
17
#include "php_hash_sha.h"
18
#include "Zend/zend_cpuinfo.h"
19
20
static const unsigned char PADDING[128] =
21
{
22
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
30
};
31
32
/* {{{ SHAEncode32
33
   Encodes input (uint32_t) into output (unsigned char). Assumes len is
34
   a multiple of 4.
35
 */
36
static void SHAEncode32(unsigned char *output, uint32_t *input, unsigned int len)
37
362
{
38
362
  unsigned int i, j;
39
40
3.22k
  for (i = 0, j = 0; j < len; i++, j += 4) {
41
2.86k
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
42
2.86k
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
43
2.86k
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
44
2.86k
    output[j + 3] = (unsigned char) (input[i] & 0xff);
45
2.86k
  }
46
362
}
47
/* }}} */
48
49
50
/* {{{ SHADecode32
51
   Decodes input (unsigned char) into output (uint32_t). Assumes len is
52
   a multiple of 4.
53
 */
54
static void SHADecode32(uint32_t *output, const unsigned char *input, unsigned int len)
55
0
{
56
0
  unsigned int i, j;
57
0
58
0
  for (i = 0, j = 0; j < len; i++, j += 4)
59
0
    output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
60
0
      (((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
61
0
}
62
/* }}} */
63
64
const php_hash_ops php_hash_sha1_ops = {
65
  "sha1",
66
  (php_hash_init_func_t) PHP_SHA1InitArgs,
67
  (php_hash_update_func_t) PHP_SHA1Update,
68
  (php_hash_final_func_t) PHP_SHA1Final,
69
  php_hash_copy,
70
  php_hash_serialize,
71
  php_hash_unserialize,
72
  PHP_SHA1_SPEC,
73
  20,
74
  64,
75
  sizeof(PHP_SHA1_CTX),
76
  1,
77
  0
78
};
79
80
/* sha224/sha256 */
81
82
const php_hash_ops php_hash_sha256_ops = {
83
  "sha256",
84
  (php_hash_init_func_t) PHP_SHA256InitArgs,
85
  (php_hash_update_func_t) PHP_SHA256Update,
86
  (php_hash_final_func_t) PHP_SHA256Final,
87
  php_hash_copy,
88
  php_hash_serialize,
89
  php_hash_unserialize,
90
  PHP_SHA256_SPEC,
91
  32,
92
  64,
93
  sizeof(PHP_SHA256_CTX),
94
  1,
95
  0
96
};
97
98
const php_hash_ops php_hash_sha224_ops = {
99
  "sha224",
100
  (php_hash_init_func_t) PHP_SHA224InitArgs,
101
  (php_hash_update_func_t) PHP_SHA224Update,
102
  (php_hash_final_func_t) PHP_SHA224Final,
103
  php_hash_copy,
104
  php_hash_serialize,
105
  php_hash_unserialize,
106
  PHP_SHA224_SPEC,
107
  28,
108
  64,
109
  sizeof(PHP_SHA224_CTX),
110
  1,
111
  0
112
};
113
114
0
#define ROTR32(b,x)   ((x >> b) | (x << (32 - b)))
115
18.3M
#define ROTR64(b,x)   ((x >> b) | (x << (64 - b)))
116
3.19M
#define SHR(b, x)   (x >> b)
117
118
/* Ch */
119
0
#define SHA256_F0(x,y,z)  (((x) & (y)) ^ ((~(x)) & (z)))
120
/* Maj */
121
0
#define SHA256_F1(x,y,z)  (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
122
/* SUM0 */
123
0
#define SHA256_F2(x)    (ROTR32( 2,(x)) ^ ROTR32(13,(x)) ^ ROTR32(22,(x)))
124
/* SUM1 */
125
0
#define SHA256_F3(x)    (ROTR32( 6,(x)) ^ ROTR32(11,(x)) ^ ROTR32(25,(x)))
126
/* OM0 */
127
0
#define SHA256_F4(x)    (ROTR32( 7,(x)) ^ ROTR32(18,(x)) ^ SHR( 3,(x)))
128
/* OM1 */
129
0
#define SHA256_F5(x)    (ROTR32(17,(x)) ^ ROTR32(19,(x)) ^ SHR(10,(x)))
130
131
static const uint32_t SHA256_K[64] = {
132
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
133
  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
134
  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
135
  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
136
  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
137
  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
138
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
139
  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
140
141
/* {{{ PHP_SHA256InitArgs
142
 * SHA256 initialization. Begins an SHA256 operation, writing a new context.
143
 */
144
PHP_HASH_API void PHP_SHA256InitArgs(PHP_SHA256_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
145
341
{
146
341
  context->count[0] = context->count[1] = 0;
147
  /* Load magic initialization constants.
148
   */
149
341
  context->state[0] = 0x6a09e667;
150
341
  context->state[1] = 0xbb67ae85;
151
341
  context->state[2] = 0x3c6ef372;
152
341
  context->state[3] = 0xa54ff53a;
153
341
  context->state[4] = 0x510e527f;
154
341
  context->state[5] = 0x9b05688c;
155
341
  context->state[6] = 0x1f83d9ab;
156
341
  context->state[7] = 0x5be0cd19;
157
341
}
158
/* }}} */
159
160
/* {{{ SHA256Transform
161
 * SHA256 basic transformation. Transforms state based on block.
162
 */
163
static void SHA256Transform(uint32_t state[8], const unsigned char block[64])
164
56.3k
{
165
#if defined(PHP_HASH_INTRIN_SHA_NATIVE)
166
  SHA256_Transform_shani(state, block);
167
  return;
168
#elif defined(PHP_HASH_INTRIN_SHA_RESOLVER)
169
56.3k
  if (zend_cpu_supports(ZEND_CPU_FEATURE_SSSE3) && zend_cpu_supports(ZEND_CPU_FEATURE_SHA)) {
170
0
    SHA256_Transform_shani(state, block);
171
0
    return;
172
0
  }
173
56.3k
#endif
174
175
56.3k
#if defined(__SSE2__)
176
56.3k
  uint32_t tmp32[72];
177
178
56.3k
  SHA256_Transform_sse2(state, block, &tmp32[0], &tmp32[64]);
179
56.3k
  ZEND_SECURE_ZERO((unsigned char*) tmp32, sizeof(tmp32));
180
56.3k
  return;
181
0
#endif
182
183
0
  uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
184
0
  uint32_t e = state[4], f = state[5], g = state[6], h = state[7];
185
0
  uint32_t x[16], T1, T2, W[64];
186
0
  int i;
187
188
0
  SHADecode32(x, block, 64);
189
190
  /* Schedule */
191
0
  for(i = 0; i < 16; i++) {
192
0
    W[i] = x[i];
193
0
  }
194
0
  for(i = 16; i < 64; i++) {
195
0
    W[i] = SHA256_F5(W[i-2]) + W[i-7] + SHA256_F4(W[i-15]) + W[i-16];
196
0
  }
197
198
0
  for (i = 0; i < 64; i++) {
199
0
    T1 = h + SHA256_F3(e) + SHA256_F0(e,f,g) + SHA256_K[i] + W[i];
200
0
    T2 = SHA256_F2(a) + SHA256_F1(a,b,c);
201
0
    h = g; g = f; f = e; e = d + T1;
202
0
    d = c; c = b; b = a; a = T1 + T2;
203
0
  }
204
205
0
  state[0] += a;
206
0
  state[1] += b;
207
0
  state[2] += c;
208
0
  state[3] += d;
209
0
  state[4] += e;
210
0
  state[5] += f;
211
0
  state[6] += g;
212
0
  state[7] += h;
213
214
  /* Zeroize sensitive information. */
215
0
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
216
0
}
217
/* }}} */
218
219
/* {{{ PHP_SHA224InitArgs
220
 * SHA224 initialization. Begins an SHA224 operation, writing a new context.
221
 */
222
PHP_HASH_API void PHP_SHA224InitArgs(PHP_SHA224_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
223
36
{
224
36
  context->count[0] = context->count[1] = 0;
225
  /* Load magic initialization constants.
226
   */
227
36
  context->state[0] = 0xc1059ed8;
228
36
  context->state[1] = 0x367cd507;
229
36
  context->state[2] = 0x3070dd17;
230
36
  context->state[3] = 0xf70e5939;
231
36
  context->state[4] = 0xffc00b31;
232
36
  context->state[5] = 0x68581511;
233
36
  context->state[6] = 0x64f98fa7;
234
36
  context->state[7] = 0xbefa4fa4;
235
36
}
236
/* }}} */
237
238
/* {{{ PHP_SHA224Update
239
   SHA224 block update operation. Continues an SHA224 message-digest
240
   operation, processing another message block, and updating the
241
   context.
242
 */
243
PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX * context, const unsigned char *input, size_t inputLen)
244
108
{
245
108
  unsigned int index, partLen;
246
108
  size_t i;
247
248
  /* Compute number of bytes mod 64 */
249
108
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
250
251
  /* Update number of bits */
252
108
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
253
33
    context->count[1]++;
254
33
  }
255
108
  context->count[1] += (uint32_t) (inputLen >> 29);
256
257
108
  partLen = 64 - index;
258
259
  /* Transform as many times as possible.
260
   */
261
108
  if (inputLen >= partLen) {
262
84
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
263
84
    SHA256Transform(context->state, context->buffer);
264
265
21.0k
    for (i = partLen; i + 63 < inputLen; i += 64) {
266
20.9k
      SHA256Transform(context->state, &input[i]);
267
20.9k
    }
268
269
84
    index = 0;
270
84
  } else {
271
24
    i = 0;
272
24
  }
273
274
  /* Buffer remaining input */
275
108
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
276
108
}
277
/* }}} */
278
279
/* {{{ PHP_SHA224Final
280
   SHA224 finalization. Ends an SHA224 message-digest operation, writing the
281
   the message digest and zeroizing the context.
282
 */
283
PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context)
284
36
{
285
36
  unsigned char bits[8];
286
36
  unsigned int index, padLen;
287
288
  /* Save number of bits */
289
36
  bits[7] = (unsigned char) (context->count[0] & 0xFF);
290
36
  bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
291
36
  bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
292
36
  bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
293
36
  bits[3] = (unsigned char) (context->count[1] & 0xFF);
294
36
  bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
295
36
  bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
296
36
  bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
297
298
  /* Pad out to 56 mod 64.
299
   */
300
36
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
301
36
  padLen = (index < 56) ? (56 - index) : (120 - index);
302
36
  PHP_SHA224Update(context, PADDING, padLen);
303
304
  /* Append length (before padding) */
305
36
  PHP_SHA224Update(context, bits, 8);
306
307
  /* Store state in digest */
308
36
  SHAEncode32(digest, context->state, 28);
309
310
  /* Zeroize sensitive information.
311
   */
312
36
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
313
36
}
314
/* }}} */
315
316
/* {{{ PHP_SHA256Update
317
   SHA256 block update operation. Continues an SHA256 message-digest
318
   operation, processing another message block, and updating the
319
   context.
320
 */
321
PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, size_t inputLen)
322
1.24k
{
323
1.24k
  unsigned int index, partLen;
324
1.24k
  size_t i;
325
326
  /* Compute number of bytes mod 64 */
327
1.24k
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
328
329
  /* Update number of bits */
330
1.24k
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
331
49
    context->count[1]++;
332
49
  }
333
1.24k
  context->count[1] += (uint32_t) (inputLen >> 29);
334
335
1.24k
  partLen = 64 - index;
336
337
  /* Transform as many times as possible.
338
   */
339
1.24k
  if (inputLen >= partLen) {
340
676
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
341
676
    SHA256Transform(context->state, context->buffer);
342
343
35.2k
    for (i = partLen; i + 63 < inputLen; i += 64) {
344
34.6k
      SHA256Transform(context->state, &input[i]);
345
34.6k
    }
346
347
676
    index = 0;
348
676
  } else {
349
566
    i = 0;
350
566
  }
351
352
  /* Buffer remaining input */
353
1.24k
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
354
1.24k
}
355
/* }}} */
356
357
/* {{{ PHP_SHA256Final
358
   SHA256 finalization. Ends an SHA256 message-digest operation, writing the
359
   the message digest and zeroizing the context.
360
 */
361
PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
362
326
{
363
326
  unsigned char bits[8];
364
326
  unsigned int index, padLen;
365
366
  /* Save number of bits */
367
326
  bits[7] = (unsigned char) (context->count[0] & 0xFF);
368
326
  bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
369
326
  bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
370
326
  bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
371
326
  bits[3] = (unsigned char) (context->count[1] & 0xFF);
372
326
  bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
373
326
  bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
374
326
  bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
375
376
  /* Pad out to 56 mod 64.
377
   */
378
326
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
379
326
  padLen = (index < 56) ? (56 - index) : (120 - index);
380
326
  PHP_SHA256Update(context, PADDING, padLen);
381
382
  /* Append length (before padding) */
383
326
  PHP_SHA256Update(context, bits, 8);
384
385
  /* Store state in digest */
386
326
  SHAEncode32(digest, context->state, 32);
387
388
  /* Zeroize sensitive information.
389
   */
390
326
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
391
326
}
392
/* }}} */
393
394
/* sha384/sha512 */
395
396
/* Ch */
397
1.99M
#define SHA512_F0(x,y,z)    (((x) & (y)) ^ ((~(x)) & (z)))
398
/* Maj */
399
1.99M
#define SHA512_F1(x,y,z)    (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
400
/* SUM0 */
401
1.99M
#define SHA512_F2(x)      (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
402
/* SUM1 */
403
1.99M
#define SHA512_F3(x)      (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
404
/* OM0 */
405
1.59M
#define SHA512_F4(x)      (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
406
/* OM1 */
407
1.59M
#define SHA512_F5(x)      (ROTR64(19, x) ^ ROTR64(61, x) ^ SHR(6, x))
408
409
static const uint64_t SHA512_K[128] = {
410
  L64(0x428a2f98d728ae22), L64(0x7137449123ef65cd), L64(0xb5c0fbcfec4d3b2f), L64(0xe9b5dba58189dbbc),
411
  L64(0x3956c25bf348b538), L64(0x59f111f1b605d019), L64(0x923f82a4af194f9b), L64(0xab1c5ed5da6d8118),
412
  L64(0xd807aa98a3030242), L64(0x12835b0145706fbe), L64(0x243185be4ee4b28c), L64(0x550c7dc3d5ffb4e2),
413
  L64(0x72be5d74f27b896f), L64(0x80deb1fe3b1696b1), L64(0x9bdc06a725c71235), L64(0xc19bf174cf692694),
414
  L64(0xe49b69c19ef14ad2), L64(0xefbe4786384f25e3), L64(0x0fc19dc68b8cd5b5), L64(0x240ca1cc77ac9c65),
415
  L64(0x2de92c6f592b0275), L64(0x4a7484aa6ea6e483), L64(0x5cb0a9dcbd41fbd4), L64(0x76f988da831153b5),
416
  L64(0x983e5152ee66dfab), L64(0xa831c66d2db43210), L64(0xb00327c898fb213f), L64(0xbf597fc7beef0ee4),
417
  L64(0xc6e00bf33da88fc2), L64(0xd5a79147930aa725), L64(0x06ca6351e003826f), L64(0x142929670a0e6e70),
418
  L64(0x27b70a8546d22ffc), L64(0x2e1b21385c26c926), L64(0x4d2c6dfc5ac42aed), L64(0x53380d139d95b3df),
419
  L64(0x650a73548baf63de), L64(0x766a0abb3c77b2a8), L64(0x81c2c92e47edaee6), L64(0x92722c851482353b),
420
  L64(0xa2bfe8a14cf10364), L64(0xa81a664bbc423001), L64(0xc24b8b70d0f89791), L64(0xc76c51a30654be30),
421
  L64(0xd192e819d6ef5218), L64(0xd69906245565a910), L64(0xf40e35855771202a), L64(0x106aa07032bbd1b8),
422
  L64(0x19a4c116b8d2d0c8), L64(0x1e376c085141ab53), L64(0x2748774cdf8eeb99), L64(0x34b0bcb5e19b48a8),
423
  L64(0x391c0cb3c5c95a63), L64(0x4ed8aa4ae3418acb), L64(0x5b9cca4f7763e373), L64(0x682e6ff3d6b2b8a3),
424
  L64(0x748f82ee5defb2fc), L64(0x78a5636f43172f60), L64(0x84c87814a1f0ab72), L64(0x8cc702081a6439ec),
425
  L64(0x90befffa23631e28), L64(0xa4506cebde82bde9), L64(0xbef9a3f7b2c67915), L64(0xc67178f2e372532b),
426
  L64(0xca273eceea26619c), L64(0xd186b8c721c0c207), L64(0xeada7dd6cde0eb1e), L64(0xf57d4f7fee6ed178),
427
  L64(0x06f067aa72176fba), L64(0x0a637dc5a2c898a6), L64(0x113f9804bef90dae), L64(0x1b710b35131c471b),
428
  L64(0x28db77f523047d84), L64(0x32caab7b40c72493), L64(0x3c9ebe0a15c9bebc), L64(0x431d67c49c100d4c),
429
  L64(0x4cc5d4becb3e42b6), L64(0x597f299cfc657e2a), L64(0x5fcb6fab3ad6faec), L64(0x6c44198c4a475817) };
430
431
/* {{{ SHAEncode64
432
   Encodes input (uint64_t) into output (unsigned char). Assumes len is
433
   a multiple of 8.
434
 */
435
static void SHAEncode64(unsigned char *output, uint64_t *input, unsigned int len)
436
261
{
437
261
  unsigned int i, j;
438
439
2.08k
  for (i = 0, j = 0; j < len; i++, j += 8) {
440
1.82k
    output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
441
1.82k
    output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
442
1.82k
    output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
443
1.82k
    output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
444
1.82k
    output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
445
1.82k
    output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
446
1.82k
    output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
447
1.82k
    output[j + 7] = (unsigned char) (input[i] & 0xff);
448
1.82k
  }
449
261
}
450
/* }}} */
451
452
453
/* {{{ SHADecode64
454
   Decodes input (unsigned char) into output (uint64_t). Assumes len is
455
   a multiple of 8.
456
 */
457
static void SHADecode64(uint64_t *output, const unsigned char *input, unsigned int len)
458
24.9k
{
459
24.9k
  unsigned int i, j;
460
461
424k
  for (i = 0, j = 0; j < len; i++, j += 8)
462
399k
    output[i] =
463
399k
      ((uint64_t) input[j + 7]) | (((uint64_t) input[j + 6]) << 8) |
464
399k
      (((uint64_t) input[j + 5]) << 16) | (((uint64_t) input[j + 4]) << 24) |
465
399k
      (((uint64_t) input[j + 3]) << 32) | (((uint64_t) input[j + 2]) << 40) |
466
399k
      (((uint64_t) input[j + 1]) << 48) | (((uint64_t) input[j]) << 56);
467
24.9k
}
468
/* }}} */
469
470
/* {{{ PHP_SHA384InitArgs
471
 * SHA384 initialization. Begins an SHA384 operation, writing a new context.
472
 */
473
PHP_HASH_API void PHP_SHA384InitArgs(PHP_SHA384_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
474
134
{
475
134
  context->count[0] = context->count[1] = 0;
476
  /* Load magic initialization constants.
477
   */
478
134
  context->state[0] = L64(0xcbbb9d5dc1059ed8);
479
134
  context->state[1] = L64(0x629a292a367cd507);
480
134
  context->state[2] = L64(0x9159015a3070dd17);
481
134
  context->state[3] = L64(0x152fecd8f70e5939);
482
134
  context->state[4] = L64(0x67332667ffc00b31);
483
134
  context->state[5] = L64(0x8eb44a8768581511);
484
134
  context->state[6] = L64(0xdb0c2e0d64f98fa7);
485
134
  context->state[7] = L64(0x47b5481dbefa4fa4);
486
134
}
487
/* }}} */
488
489
/* {{{ SHA512Transform
490
 * SHA512 basic transformation. Transforms state based on block.
491
 * SHA384 uses the exact same algorithm
492
 */
493
static void SHA512Transform(uint64_t state[8], const unsigned char block[128])
494
24.9k
{
495
24.9k
  uint64_t a = state[0], b = state[1], c = state[2], d = state[3];
496
24.9k
  uint64_t e = state[4], f = state[5], g = state[6], h = state[7];
497
24.9k
  uint64_t x[16], T1, T2, W[80];
498
24.9k
  int i;
499
500
24.9k
  SHADecode64(x, block, 128);
501
502
  /* Schedule */
503
424k
  for(i = 0; i < 16; i++) {
504
399k
    W[i] = x[i];
505
399k
  }
506
1.62M
  for(i = 16; i < 80; i++) {
507
1.59M
    W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
508
1.59M
  }
509
510
2.02M
  for (i = 0; i < 80; i++) {
511
1.99M
    T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
512
1.99M
    T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
513
1.99M
    h = g; g = f; f = e; e = d + T1;
514
1.99M
    d = c; c = b; b = a; a = T1 + T2;
515
1.99M
  }
516
517
24.9k
  state[0] += a;
518
24.9k
  state[1] += b;
519
24.9k
  state[2] += c;
520
24.9k
  state[3] += d;
521
24.9k
  state[4] += e;
522
24.9k
  state[5] += f;
523
24.9k
  state[6] += g;
524
24.9k
  state[7] += h;
525
526
  /* Zeroize sensitive information. */
527
24.9k
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
528
24.9k
}
529
/* }}} */
530
531
/* {{{ PHP_SHA384Update
532
   SHA384 block update operation. Continues an SHA384 message-digest
533
   operation, processing another message block, and updating the
534
   context.
535
 */
536
PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX * context, const unsigned char *input, size_t inputLen)
537
390
{
538
390
  unsigned int index, partLen;
539
390
  size_t i = 0;
540
541
  /* Compute number of bytes mod 128 */
542
390
  index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
543
544
  /* Update number of bits */
545
390
  if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
546
22
    context->count[1]++;
547
22
  }
548
  /* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
549
390
  context->count[1] += (uint64_t) inputLen >> 61;
550
551
390
  partLen = 128 - index;
552
553
  /* Transform as many times as possible.
554
   */
555
390
  if (inputLen >= partLen) {
556
224
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
557
224
    SHA512Transform(context->state, context->buffer);
558
559
11.1k
    for (i = partLen; i + 127 < inputLen; i += 128) {
560
10.9k
      SHA512Transform(context->state, &input[i]);
561
10.9k
    }
562
563
224
    index = 0;
564
224
  }
565
566
  /* Buffer remaining input */
567
390
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
568
390
}
569
/* }}} */
570
571
/* {{{ PHP_SHA384Final
572
   SHA384 finalization. Ends an SHA384 message-digest operation, writing the
573
   the message digest and zeroizing the context.
574
 */
575
PHP_HASH_API void PHP_SHA384Final(unsigned char digest[48], PHP_SHA384_CTX * context)
576
130
{
577
130
  unsigned char bits[16];
578
130
  unsigned int index, padLen;
579
580
  /* Save number of bits */
581
130
  bits[15] = (unsigned char) (context->count[0] & 0xFF);
582
130
  bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
583
130
  bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
584
130
  bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
585
130
  bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
586
130
  bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
587
130
  bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
588
130
  bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
589
130
  bits[7]  = (unsigned char) (context->count[1] & 0xFF);
590
130
  bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
591
130
  bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
592
130
  bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
593
130
  bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
594
130
  bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
595
130
  bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
596
130
  bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
597
598
  /* Pad out to 112 mod 128.
599
   */
600
130
  index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
601
130
  padLen = (index < 112) ? (112 - index) : (240 - index);
602
130
  PHP_SHA384Update(context, PADDING, padLen);
603
604
  /* Append length (before padding) */
605
130
  PHP_SHA384Update(context, bits, 16);
606
607
  /* Store state in digest */
608
130
  SHAEncode64(digest, context->state, 48);
609
610
  /* Zeroize sensitive information.
611
   */
612
130
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
613
130
}
614
/* }}} */
615
616
const php_hash_ops php_hash_sha384_ops = {
617
  "sha384",
618
  (php_hash_init_func_t) PHP_SHA384InitArgs,
619
  (php_hash_update_func_t) PHP_SHA384Update,
620
  (php_hash_final_func_t) PHP_SHA384Final,
621
  php_hash_copy,
622
  php_hash_serialize,
623
  php_hash_unserialize,
624
  PHP_SHA384_SPEC,
625
  48,
626
  128,
627
  sizeof(PHP_SHA384_CTX),
628
  1,
629
  0
630
};
631
632
/* {{{ PHP_SHA512InitArgs
633
 * SHA512 initialization. Begins an SHA512 operation, writing a new context.
634
 */
635
PHP_HASH_API void PHP_SHA512InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
636
133
{
637
133
  context->count[0] = context->count[1] = 0;
638
  /* Load magic initialization constants.
639
   */
640
133
  context->state[0] = L64(0x6a09e667f3bcc908);
641
133
  context->state[1] = L64(0xbb67ae8584caa73b);
642
133
  context->state[2] = L64(0x3c6ef372fe94f82b);
643
133
  context->state[3] = L64(0xa54ff53a5f1d36f1);
644
133
  context->state[4] = L64(0x510e527fade682d1);
645
133
  context->state[5] = L64(0x9b05688c2b3e6c1f);
646
133
  context->state[6] = L64(0x1f83d9abfb41bd6b);
647
133
  context->state[7] = L64(0x5be0cd19137e2179);
648
133
}
649
/* }}} */
650
651
/* {{{ PHP_SHA512_256InitArgs
652
 * SHA512/245 initialization. Identical algorithm to SHA512, using alternate initval and truncation
653
 */
654
PHP_HASH_API void PHP_SHA512_256InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
655
1
{
656
1
  context->count[0] = context->count[1] = 0;
657
658
1
  context->state[0] = L64(0x22312194FC2BF72C);
659
1
  context->state[1] = L64(0x9F555FA3C84C64C2);
660
1
  context->state[2] = L64(0x2393B86B6F53B151);
661
1
  context->state[3] = L64(0x963877195940EABD);
662
1
  context->state[4] = L64(0x96283EE2A88EFFE3);
663
1
  context->state[5] = L64(0xBE5E1E2553863992);
664
1
  context->state[6] = L64(0x2B0199FC2C85B8AA);
665
1
  context->state[7] = L64(0x0EB72DDC81C52CA2);
666
1
}
667
/* }}} */
668
669
/* {{{ PHP_SHA512_224InitArgs
670
 * SHA512/224 initialization. Identical algorithm to SHA512, using alternate initval and truncation
671
 */
672
PHP_HASH_API void PHP_SHA512_224InitArgs(PHP_SHA512_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
673
1
{
674
1
        context->count[0] = context->count[1] = 0;
675
676
1
  context->state[0] = L64(0x8C3D37C819544DA2);
677
1
  context->state[1] = L64(0x73E1996689DCD4D6);
678
1
  context->state[2] = L64(0x1DFAB7AE32FF9C82);
679
1
  context->state[3] = L64(0x679DD514582F9FCF);
680
1
  context->state[4] = L64(0x0F6D2B697BD44DA8);
681
1
  context->state[5] = L64(0x77E36F7304C48942);
682
1
  context->state[6] = L64(0x3F9D85A86A1D36C8);
683
1
  context->state[7] = L64(0x1112E6AD91D692A1);
684
1
}
685
/* }}} */
686
687
/* {{{ PHP_SHA512Update
688
   SHA512 block update operation. Continues an SHA512 message-digest
689
   operation, processing another message block, and updating the
690
   context.
691
 */
692
PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char *input, size_t inputLen)
693
393
{
694
393
  unsigned int index, partLen;
695
393
  size_t i;
696
697
  /* Compute number of bytes mod 128 */
698
393
  index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
699
700
  /* Update number of bits */
701
393
  if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
702
31
    context->count[1]++;
703
31
  }
704
  /* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
705
393
  context->count[1] += (uint64_t) inputLen >> 61;
706
707
393
  partLen = 128 - index;
708
709
  /* Transform as many times as possible.
710
   */
711
393
  if (inputLen >= partLen) {
712
289
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
713
289
    SHA512Transform(context->state, context->buffer);
714
715
13.8k
    for (i = partLen; i + 127 < inputLen; i += 128) {
716
13.5k
      SHA512Transform(context->state, &input[i]);
717
13.5k
    }
718
719
289
    index = 0;
720
289
  } else {
721
104
    i = 0;
722
104
  }
723
724
  /* Buffer remaining input */
725
393
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
726
393
}
727
/* }}} */
728
729
/* {{{ PHP_SHA512Final
730
   SHA512 finalization. Ends an SHA512 message-digest operation, writing the
731
   the message digest and zeroizing the context.
732
 */
733
PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context)
734
131
{
735
131
  unsigned char bits[16];
736
131
  unsigned int index, padLen;
737
738
  /* Save number of bits */
739
131
  bits[15] = (unsigned char) (context->count[0] & 0xFF);
740
131
  bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
741
131
  bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
742
131
  bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
743
131
  bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
744
131
  bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
745
131
  bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
746
131
  bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
747
131
  bits[7]  = (unsigned char) (context->count[1] & 0xFF);
748
131
  bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
749
131
  bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
750
131
  bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
751
131
  bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
752
131
  bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
753
131
  bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
754
131
  bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
755
756
  /* Pad out to 112 mod 128.
757
   */
758
131
  index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
759
131
  padLen = (index < 112) ? (112 - index) : (240 - index);
760
131
  PHP_SHA512Update(context, PADDING, padLen);
761
762
  /* Append length (before padding) */
763
131
  PHP_SHA512Update(context, bits, 16);
764
765
  /* Store state in digest */
766
131
  SHAEncode64(digest, context->state, 64);
767
768
  /* Zeroize sensitive information.
769
   */
770
131
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
771
131
}
772
/* }}} */
773
774
/* {{{ PHP_SHA512_256Final
775
   SHA512/256 finalization. Identical to SHA512Final, but with truncation
776
 */
777
PHP_HASH_API void PHP_SHA512_256Final(unsigned char digest[32], PHP_SHA512_CTX * context)
778
1
{
779
1
  unsigned char full_digest[64];
780
1
  PHP_SHA512Final(full_digest, context);
781
1
  memcpy(digest, full_digest, 32);
782
1
}
783
/* }}} */
784
785
/* {{{ PHP_SHA512_224Final
786
   SHA512/224 finalization. Identical to SHA512Final, but with truncation
787
 */
788
PHP_HASH_API void PHP_SHA512_224Final(unsigned char digest[28], PHP_SHA512_CTX * context)
789
1
{
790
1
  unsigned char full_digest[64];
791
1
  PHP_SHA512Final(full_digest, context);
792
1
  memcpy(digest, full_digest, 28);
793
1
}
794
/* }}} */
795
796
const php_hash_ops php_hash_sha512_ops = {
797
  "sha512",
798
  (php_hash_init_func_t) PHP_SHA512InitArgs,
799
  (php_hash_update_func_t) PHP_SHA512Update,
800
  (php_hash_final_func_t) PHP_SHA512Final,
801
  php_hash_copy,
802
  php_hash_serialize,
803
  php_hash_unserialize,
804
  PHP_SHA512_SPEC,
805
  64,
806
  128,
807
  sizeof(PHP_SHA512_CTX),
808
  1,
809
  0
810
};
811
812
const php_hash_ops php_hash_sha512_256_ops = {
813
  "sha512/256",
814
  (php_hash_init_func_t) PHP_SHA512_256InitArgs,
815
  (php_hash_update_func_t) PHP_SHA512_256Update,
816
  (php_hash_final_func_t) PHP_SHA512_256Final,
817
  php_hash_copy,
818
  php_hash_serialize,
819
  php_hash_unserialize,
820
  PHP_SHA512_SPEC,
821
  32,
822
  128,
823
  sizeof(PHP_SHA512_CTX),
824
  1,
825
  0
826
};
827
828
const php_hash_ops php_hash_sha512_224_ops = {
829
  "sha512/224",
830
  (php_hash_init_func_t) PHP_SHA512_224InitArgs,
831
  (php_hash_update_func_t) PHP_SHA512_224Update,
832
  (php_hash_final_func_t) PHP_SHA512_224Final,
833
  php_hash_copy,
834
  php_hash_serialize,
835
  php_hash_unserialize,
836
  PHP_SHA512_SPEC,
837
  28,
838
  128,
839
  sizeof(PHP_SHA512_CTX),
840
  1,
841
  0
842
};