Coverage Report

Created: 2026-06-13 07:01

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