Coverage Report

Created: 2026-07-25 06:39

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
493
{
38
493
  unsigned int i, j;
39
40
4.40k
  for (i = 0, j = 0; j < len; i++, j += 4) {
41
3.91k
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
42
3.91k
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
43
3.91k
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
44
3.91k
    output[j + 3] = (unsigned char) (input[i] & 0xff);
45
3.91k
  }
46
493
}
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
31.7M
#define ROTR64(b,x)   ((x >> b) | (x << (64 - b)))
116
5.52M
#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
463
{
146
463
  context->count[0] = context->count[1] = 0;
147
  /* Load magic initialization constants.
148
   */
149
463
  context->state[0] = 0x6a09e667;
150
463
  context->state[1] = 0xbb67ae85;
151
463
  context->state[2] = 0x3c6ef372;
152
463
  context->state[3] = 0xa54ff53a;
153
463
  context->state[4] = 0x510e527f;
154
463
  context->state[5] = 0x9b05688c;
155
463
  context->state[6] = 0x1f83d9ab;
156
463
  context->state[7] = 0x5be0cd19;
157
463
}
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
57.2k
{
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
57.2k
  if (zend_cpu_supports(ZEND_CPU_FEATURE_SSSE3) && zend_cpu_supports(ZEND_CPU_FEATURE_SHA)) {
170
57.2k
    SHA256_Transform_shani(state, block);
171
57.2k
    return;
172
57.2k
  }
173
0
#endif
174
175
0
#if defined(__SSE2__)
176
0
  uint32_t tmp32[72];
177
178
0
  SHA256_Transform_sse2(state, block, &tmp32[0], &tmp32[64]);
179
0
  ZEND_SECURE_ZERO((unsigned char*) tmp32, sizeof(tmp32));
180
0
  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
35
{
224
35
  context->count[0] = context->count[1] = 0;
225
  /* Load magic initialization constants.
226
   */
227
35
  context->state[0] = 0xc1059ed8;
228
35
  context->state[1] = 0x367cd507;
229
35
  context->state[2] = 0x3070dd17;
230
35
  context->state[3] = 0xf70e5939;
231
35
  context->state[4] = 0xffc00b31;
232
35
  context->state[5] = 0x68581511;
233
35
  context->state[6] = 0x64f98fa7;
234
35
  context->state[7] = 0xbefa4fa4;
235
35
}
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
99
{
245
99
  unsigned int index, partLen;
246
99
  size_t i;
247
248
  /* Compute number of bytes mod 64 */
249
99
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
250
251
  /* Update number of bits */
252
99
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
253
31
    context->count[1]++;
254
31
  }
255
99
  context->count[1] += (uint32_t) (inputLen >> 29);
256
257
99
  partLen = 64 - index;
258
259
  /* Transform as many times as possible.
260
   */
261
99
  if (inputLen >= partLen) {
262
77
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
263
77
    SHA256Transform(context->state, context->buffer);
264
265
5.06k
    for (i = partLen; i + 63 < inputLen; i += 64) {
266
4.98k
      SHA256Transform(context->state, &input[i]);
267
4.98k
    }
268
269
77
    index = 0;
270
77
  } else {
271
22
    i = 0;
272
22
  }
273
274
  /* Buffer remaining input */
275
99
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
276
99
}
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
33
{
285
33
  unsigned char bits[8];
286
33
  unsigned int index, padLen;
287
288
  /* Save number of bits */
289
33
  bits[7] = (unsigned char) (context->count[0] & 0xFF);
290
33
  bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
291
33
  bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
292
33
  bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
293
33
  bits[3] = (unsigned char) (context->count[1] & 0xFF);
294
33
  bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
295
33
  bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
296
33
  bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
297
298
  /* Pad out to 56 mod 64.
299
   */
300
33
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
301
33
  padLen = (index < 56) ? (56 - index) : (120 - index);
302
33
  PHP_SHA224Update(context, PADDING, padLen);
303
304
  /* Append length (before padding) */
305
33
  PHP_SHA224Update(context, bits, 8);
306
307
  /* Store state in digest */
308
33
  SHAEncode32(digest, context->state, 28);
309
310
  /* Zeroize sensitive information.
311
   */
312
33
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
313
33
}
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.77k
{
323
1.77k
  unsigned int index, partLen;
324
1.77k
  size_t i;
325
326
  /* Compute number of bytes mod 64 */
327
1.77k
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
328
329
  /* Update number of bits */
330
1.77k
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
331
54
    context->count[1]++;
332
54
  }
333
1.77k
  context->count[1] += (uint32_t) (inputLen >> 29);
334
335
1.77k
  partLen = 64 - index;
336
337
  /* Transform as many times as possible.
338
   */
339
1.77k
  if (inputLen >= partLen) {
340
941
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
341
941
    SHA256Transform(context->state, context->buffer);
342
343
52.1k
    for (i = partLen; i + 63 < inputLen; i += 64) {
344
51.2k
      SHA256Transform(context->state, &input[i]);
345
51.2k
    }
346
347
941
    index = 0;
348
941
  } else {
349
835
    i = 0;
350
835
  }
351
352
  /* Buffer remaining input */
353
1.77k
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
354
1.77k
}
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
460
{
363
460
  unsigned char bits[8];
364
460
  unsigned int index, padLen;
365
366
  /* Save number of bits */
367
460
  bits[7] = (unsigned char) (context->count[0] & 0xFF);
368
460
  bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
369
460
  bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
370
460
  bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
371
460
  bits[3] = (unsigned char) (context->count[1] & 0xFF);
372
460
  bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
373
460
  bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
374
460
  bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
375
376
  /* Pad out to 56 mod 64.
377
   */
378
460
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
379
460
  padLen = (index < 56) ? (56 - index) : (120 - index);
380
460
  PHP_SHA256Update(context, PADDING, padLen);
381
382
  /* Append length (before padding) */
383
460
  PHP_SHA256Update(context, bits, 8);
384
385
  /* Store state in digest */
386
460
  SHAEncode32(digest, context->state, 32);
387
388
  /* Zeroize sensitive information.
389
   */
390
460
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
391
460
}
392
/* }}} */
393
394
/* sha384/sha512 */
395
396
/* Ch */
397
3.45M
#define SHA512_F0(x,y,z)    (((x) & (y)) ^ ((~(x)) & (z)))
398
/* Maj */
399
3.45M
#define SHA512_F1(x,y,z)    (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
400
/* SUM0 */
401
3.45M
#define SHA512_F2(x)      (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
402
/* SUM1 */
403
3.45M
#define SHA512_F3(x)      (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
404
/* OM0 */
405
2.76M
#define SHA512_F4(x)      (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
406
/* OM1 */
407
2.76M
#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
335
{
437
335
  unsigned int i, j;
438
439
2.69k
  for (i = 0, j = 0; j < len; i++, j += 8) {
440
2.36k
    output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
441
2.36k
    output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
442
2.36k
    output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
443
2.36k
    output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
444
2.36k
    output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
445
2.36k
    output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
446
2.36k
    output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
447
2.36k
    output[j + 7] = (unsigned char) (input[i] & 0xff);
448
2.36k
  }
449
335
}
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
43.1k
{
459
43.1k
  unsigned int i, j;
460
461
733k
  for (i = 0, j = 0; j < len; i++, j += 8)
462
690k
    output[i] =
463
690k
      ((uint64_t) input[j + 7]) | (((uint64_t) input[j + 6]) << 8) |
464
690k
      (((uint64_t) input[j + 5]) << 16) | (((uint64_t) input[j + 4]) << 24) |
465
690k
      (((uint64_t) input[j + 3]) << 32) | (((uint64_t) input[j + 2]) << 40) |
466
690k
      (((uint64_t) input[j + 1]) << 48) | (((uint64_t) input[j]) << 56);
467
43.1k
}
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
158
{
475
158
  context->count[0] = context->count[1] = 0;
476
  /* Load magic initialization constants.
477
   */
478
158
  context->state[0] = L64(0xcbbb9d5dc1059ed8);
479
158
  context->state[1] = L64(0x629a292a367cd507);
480
158
  context->state[2] = L64(0x9159015a3070dd17);
481
158
  context->state[3] = L64(0x152fecd8f70e5939);
482
158
  context->state[4] = L64(0x67332667ffc00b31);
483
158
  context->state[5] = L64(0x8eb44a8768581511);
484
158
  context->state[6] = L64(0xdb0c2e0d64f98fa7);
485
158
  context->state[7] = L64(0x47b5481dbefa4fa4);
486
158
}
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
43.1k
{
495
43.1k
  uint64_t a = state[0], b = state[1], c = state[2], d = state[3];
496
43.1k
  uint64_t e = state[4], f = state[5], g = state[6], h = state[7];
497
43.1k
  uint64_t x[16], T1, T2, W[80];
498
43.1k
  int i;
499
500
43.1k
  SHADecode64(x, block, 128);
501
502
  /* Schedule */
503
733k
  for(i = 0; i < 16; i++) {
504
690k
    W[i] = x[i];
505
690k
  }
506
2.80M
  for(i = 16; i < 80; i++) {
507
2.76M
    W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
508
2.76M
  }
509
510
3.49M
  for (i = 0; i < 80; i++) {
511
3.45M
    T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
512
3.45M
    T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
513
3.45M
    h = g; g = f; f = e; e = d + T1;
514
3.45M
    d = c; c = b; b = a; a = T1 + T2;
515
3.45M
  }
516
517
43.1k
  state[0] += a;
518
43.1k
  state[1] += b;
519
43.1k
  state[2] += c;
520
43.1k
  state[3] += d;
521
43.1k
  state[4] += e;
522
43.1k
  state[5] += f;
523
43.1k
  state[6] += g;
524
43.1k
  state[7] += h;
525
526
  /* Zeroize sensitive information. */
527
43.1k
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
528
43.1k
}
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
474
{
538
474
  unsigned int index, partLen;
539
474
  size_t i = 0;
540
541
  /* Compute number of bytes mod 128 */
542
474
  index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
543
544
  /* Update number of bits */
545
474
  if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
546
26
    context->count[1]++;
547
26
  }
548
  /* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
549
474
  context->count[1] += (uint64_t) inputLen >> 61;
550
551
474
  partLen = 128 - index;
552
553
  /* Transform as many times as possible.
554
   */
555
474
  if (inputLen >= partLen) {
556
273
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
557
273
    SHA512Transform(context->state, context->buffer);
558
559
15.3k
    for (i = partLen; i + 127 < inputLen; i += 128) {
560
15.0k
      SHA512Transform(context->state, &input[i]);
561
15.0k
    }
562
563
273
    index = 0;
564
273
  }
565
566
  /* Buffer remaining input */
567
474
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
568
474
}
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
158
{
577
158
  unsigned char bits[16];
578
158
  unsigned int index, padLen;
579
580
  /* Save number of bits */
581
158
  bits[15] = (unsigned char) (context->count[0] & 0xFF);
582
158
  bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
583
158
  bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
584
158
  bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
585
158
  bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
586
158
  bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
587
158
  bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
588
158
  bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
589
158
  bits[7]  = (unsigned char) (context->count[1] & 0xFF);
590
158
  bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
591
158
  bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
592
158
  bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
593
158
  bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
594
158
  bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
595
158
  bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
596
158
  bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
597
598
  /* Pad out to 112 mod 128.
599
   */
600
158
  index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
601
158
  padLen = (index < 112) ? (112 - index) : (240 - index);
602
158
  PHP_SHA384Update(context, PADDING, padLen);
603
604
  /* Append length (before padding) */
605
158
  PHP_SHA384Update(context, bits, 16);
606
607
  /* Store state in digest */
608
158
  SHAEncode64(digest, context->state, 48);
609
610
  /* Zeroize sensitive information.
611
   */
612
158
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
613
158
}
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
178
{
637
178
  context->count[0] = context->count[1] = 0;
638
  /* Load magic initialization constants.
639
   */
640
178
  context->state[0] = L64(0x6a09e667f3bcc908);
641
178
  context->state[1] = L64(0xbb67ae8584caa73b);
642
178
  context->state[2] = L64(0x3c6ef372fe94f82b);
643
178
  context->state[3] = L64(0xa54ff53a5f1d36f1);
644
178
  context->state[4] = L64(0x510e527fade682d1);
645
178
  context->state[5] = L64(0x9b05688c2b3e6c1f);
646
178
  context->state[6] = L64(0x1f83d9abfb41bd6b);
647
178
  context->state[7] = L64(0x5be0cd19137e2179);
648
178
}
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
2
{
674
2
        context->count[0] = context->count[1] = 0;
675
676
2
  context->state[0] = L64(0x8C3D37C819544DA2);
677
2
  context->state[1] = L64(0x73E1996689DCD4D6);
678
2
  context->state[2] = L64(0x1DFAB7AE32FF9C82);
679
2
  context->state[3] = L64(0x679DD514582F9FCF);
680
2
  context->state[4] = L64(0x0F6D2B697BD44DA8);
681
2
  context->state[5] = L64(0x77E36F7304C48942);
682
2
  context->state[6] = L64(0x3F9D85A86A1D36C8);
683
2
  context->state[7] = L64(0x1112E6AD91D692A1);
684
2
}
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
531
{
694
531
  unsigned int index, partLen;
695
531
  size_t i;
696
697
  /* Compute number of bytes mod 128 */
698
531
  index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
699
700
  /* Update number of bits */
701
531
  if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
702
26
    context->count[1]++;
703
26
  }
704
  /* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
705
531
  context->count[1] += (uint64_t) inputLen >> 61;
706
707
531
  partLen = 128 - index;
708
709
  /* Transform as many times as possible.
710
   */
711
531
  if (inputLen >= partLen) {
712
344
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
713
344
    SHA512Transform(context->state, context->buffer);
714
715
27.7k
    for (i = partLen; i + 127 < inputLen; i += 128) {
716
27.4k
      SHA512Transform(context->state, &input[i]);
717
27.4k
    }
718
719
344
    index = 0;
720
344
  } else {
721
187
    i = 0;
722
187
  }
723
724
  /* Buffer remaining input */
725
531
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
726
531
}
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
177
{
735
177
  unsigned char bits[16];
736
177
  unsigned int index, padLen;
737
738
  /* Save number of bits */
739
177
  bits[15] = (unsigned char) (context->count[0] & 0xFF);
740
177
  bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
741
177
  bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
742
177
  bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
743
177
  bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
744
177
  bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
745
177
  bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
746
177
  bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
747
177
  bits[7]  = (unsigned char) (context->count[1] & 0xFF);
748
177
  bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
749
177
  bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
750
177
  bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
751
177
  bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
752
177
  bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
753
177
  bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
754
177
  bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
755
756
  /* Pad out to 112 mod 128.
757
   */
758
177
  index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
759
177
  padLen = (index < 112) ? (112 - index) : (240 - index);
760
177
  PHP_SHA512Update(context, PADDING, padLen);
761
762
  /* Append length (before padding) */
763
177
  PHP_SHA512Update(context, bits, 16);
764
765
  /* Store state in digest */
766
177
  SHAEncode64(digest, context->state, 64);
767
768
  /* Zeroize sensitive information.
769
   */
770
177
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
771
177
}
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
};