Coverage Report

Created: 2026-10-28 06:20

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