Coverage Report

Created: 2026-06-02 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
0
{
38
0
  unsigned int i, j;
39
40
0
  for (i = 0, j = 0; j < len; i++, j += 4) {
41
0
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
42
0
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
43
0
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
44
0
    output[j + 3] = (unsigned char) (input[i] & 0xff);
45
0
  }
46
0
}
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
0
#define ROTR64(b,x)   ((x >> b) | (x << (64 - b)))
113
0
#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
0
{
143
0
  context->count[0] = context->count[1] = 0;
144
  /* Load magic initialization constants.
145
   */
146
0
  context->state[0] = 0x6a09e667;
147
0
  context->state[1] = 0xbb67ae85;
148
0
  context->state[2] = 0x3c6ef372;
149
0
  context->state[3] = 0xa54ff53a;
150
0
  context->state[4] = 0x510e527f;
151
0
  context->state[5] = 0x9b05688c;
152
0
  context->state[6] = 0x1f83d9ab;
153
0
  context->state[7] = 0x5be0cd19;
154
0
}
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
0
{
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
0
  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
0
#endif
171
172
0
#if defined(__SSE2__)
173
0
  uint32_t tmp32[72];
174
175
0
  SHA256_Transform_sse2(state, block, &tmp32[0], &tmp32[64]);
176
0
  ZEND_SECURE_ZERO((unsigned char*) tmp32, sizeof(tmp32));
177
0
  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
0
{
221
0
  context->count[0] = context->count[1] = 0;
222
  /* Load magic initialization constants.
223
   */
224
0
  context->state[0] = 0xc1059ed8;
225
0
  context->state[1] = 0x367cd507;
226
0
  context->state[2] = 0x3070dd17;
227
0
  context->state[3] = 0xf70e5939;
228
0
  context->state[4] = 0xffc00b31;
229
0
  context->state[5] = 0x68581511;
230
0
  context->state[6] = 0x64f98fa7;
231
0
  context->state[7] = 0xbefa4fa4;
232
0
}
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
0
{
242
0
  unsigned int index, partLen;
243
0
  size_t i;
244
245
  /* Compute number of bytes mod 64 */
246
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
247
248
  /* Update number of bits */
249
0
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
250
0
    context->count[1]++;
251
0
  }
252
0
  context->count[1] += (uint32_t) (inputLen >> 29);
253
254
0
  partLen = 64 - index;
255
256
  /* Transform as many times as possible.
257
   */
258
0
  if (inputLen >= partLen) {
259
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
260
0
    SHA256Transform(context->state, context->buffer);
261
262
0
    for (i = partLen; i + 63 < inputLen; i += 64) {
263
0
      SHA256Transform(context->state, &input[i]);
264
0
    }
265
266
0
    index = 0;
267
0
  } else {
268
0
    i = 0;
269
0
  }
270
271
  /* Buffer remaining input */
272
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
273
0
}
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
0
{
282
0
  unsigned char bits[8];
283
0
  unsigned int index, padLen;
284
285
  /* Save number of bits */
286
0
  bits[7] = (unsigned char) (context->count[0] & 0xFF);
287
0
  bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
288
0
  bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
289
0
  bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
290
0
  bits[3] = (unsigned char) (context->count[1] & 0xFF);
291
0
  bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
292
0
  bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
293
0
  bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
294
295
  /* Pad out to 56 mod 64.
296
   */
297
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
298
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
299
0
  PHP_SHA224Update(context, PADDING, padLen);
300
301
  /* Append length (before padding) */
302
0
  PHP_SHA224Update(context, bits, 8);
303
304
  /* Store state in digest */
305
0
  SHAEncode32(digest, context->state, 28);
306
307
  /* Zeroize sensitive information.
308
   */
309
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
310
0
}
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
0
{
320
0
  unsigned int index, partLen;
321
0
  size_t i;
322
323
  /* Compute number of bytes mod 64 */
324
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
325
326
  /* Update number of bits */
327
0
  if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
328
0
    context->count[1]++;
329
0
  }
330
0
  context->count[1] += (uint32_t) (inputLen >> 29);
331
332
0
  partLen = 64 - index;
333
334
  /* Transform as many times as possible.
335
   */
336
0
  if (inputLen >= partLen) {
337
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
338
0
    SHA256Transform(context->state, context->buffer);
339
340
0
    for (i = partLen; i + 63 < inputLen; i += 64) {
341
0
      SHA256Transform(context->state, &input[i]);
342
0
    }
343
344
0
    index = 0;
345
0
  } else {
346
0
    i = 0;
347
0
  }
348
349
  /* Buffer remaining input */
350
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
351
0
}
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
0
{
360
0
  unsigned char bits[8];
361
0
  unsigned int index, padLen;
362
363
  /* Save number of bits */
364
0
  bits[7] = (unsigned char) (context->count[0] & 0xFF);
365
0
  bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
366
0
  bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
367
0
  bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
368
0
  bits[3] = (unsigned char) (context->count[1] & 0xFF);
369
0
  bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
370
0
  bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
371
0
  bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
372
373
  /* Pad out to 56 mod 64.
374
   */
375
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
376
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
377
0
  PHP_SHA256Update(context, PADDING, padLen);
378
379
  /* Append length (before padding) */
380
0
  PHP_SHA256Update(context, bits, 8);
381
382
  /* Store state in digest */
383
0
  SHAEncode32(digest, context->state, 32);
384
385
  /* Zeroize sensitive information.
386
   */
387
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
388
0
}
389
/* }}} */
390
391
/* sha384/sha512 */
392
393
/* Ch */
394
0
#define SHA512_F0(x,y,z)    (((x) & (y)) ^ ((~(x)) & (z)))
395
/* Maj */
396
0
#define SHA512_F1(x,y,z)    (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
397
/* SUM0 */
398
0
#define SHA512_F2(x)      (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
399
/* SUM1 */
400
0
#define SHA512_F3(x)      (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
401
/* OM0 */
402
0
#define SHA512_F4(x)      (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
403
/* OM1 */
404
0
#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
0
{
434
0
  unsigned int i, j;
435
436
0
  for (i = 0, j = 0; j < len; i++, j += 8) {
437
0
    output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
438
0
    output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
439
0
    output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
440
0
    output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
441
0
    output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
442
0
    output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
443
0
    output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
444
0
    output[j + 7] = (unsigned char) (input[i] & 0xff);
445
0
  }
446
0
}
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
0
{
456
0
  unsigned int i, j;
457
458
0
  for (i = 0, j = 0; j < len; i++, j += 8)
459
0
    output[i] =
460
0
      ((uint64_t) input[j + 7]) | (((uint64_t) input[j + 6]) << 8) |
461
0
      (((uint64_t) input[j + 5]) << 16) | (((uint64_t) input[j + 4]) << 24) |
462
0
      (((uint64_t) input[j + 3]) << 32) | (((uint64_t) input[j + 2]) << 40) |
463
0
      (((uint64_t) input[j + 1]) << 48) | (((uint64_t) input[j]) << 56);
464
0
}
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
0
{
472
0
  context->count[0] = context->count[1] = 0;
473
  /* Load magic initialization constants.
474
   */
475
0
  context->state[0] = L64(0xcbbb9d5dc1059ed8);
476
0
  context->state[1] = L64(0x629a292a367cd507);
477
0
  context->state[2] = L64(0x9159015a3070dd17);
478
0
  context->state[3] = L64(0x152fecd8f70e5939);
479
0
  context->state[4] = L64(0x67332667ffc00b31);
480
0
  context->state[5] = L64(0x8eb44a8768581511);
481
0
  context->state[6] = L64(0xdb0c2e0d64f98fa7);
482
0
  context->state[7] = L64(0x47b5481dbefa4fa4);
483
0
}
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
0
{
492
0
  uint64_t a = state[0], b = state[1], c = state[2], d = state[3];
493
0
  uint64_t e = state[4], f = state[5], g = state[6], h = state[7];
494
0
  uint64_t x[16], T1, T2, W[80];
495
0
  int i;
496
497
0
  SHADecode64(x, block, 128);
498
499
  /* Schedule */
500
0
  for(i = 0; i < 16; i++) {
501
0
    W[i] = x[i];
502
0
  }
503
0
  for(i = 16; i < 80; i++) {
504
0
    W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
505
0
  }
506
507
0
  for (i = 0; i < 80; i++) {
508
0
    T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
509
0
    T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
510
0
    h = g; g = f; f = e; e = d + T1;
511
0
    d = c; c = b; b = a; a = T1 + T2;
512
0
  }
513
514
0
  state[0] += a;
515
0
  state[1] += b;
516
0
  state[2] += c;
517
0
  state[3] += d;
518
0
  state[4] += e;
519
0
  state[5] += f;
520
0
  state[6] += g;
521
0
  state[7] += h;
522
523
  /* Zeroize sensitive information. */
524
0
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
525
0
}
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
0
{
535
0
  unsigned int index, partLen;
536
0
  size_t i = 0;
537
538
  /* Compute number of bytes mod 128 */
539
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
540
541
  /* Update number of bits */
542
0
  if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
543
0
    context->count[1]++;
544
0
  }
545
  /* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
546
0
  context->count[1] += (uint64_t) inputLen >> 61;
547
548
0
  partLen = 128 - index;
549
550
  /* Transform as many times as possible.
551
   */
552
0
  if (inputLen >= partLen) {
553
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
554
0
    SHA512Transform(context->state, context->buffer);
555
556
0
    for (i = partLen; i + 127 < inputLen; i += 128) {
557
0
      SHA512Transform(context->state, &input[i]);
558
0
    }
559
560
0
    index = 0;
561
0
  }
562
563
  /* Buffer remaining input */
564
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
565
0
}
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
0
{
574
0
  unsigned char bits[16];
575
0
  unsigned int index, padLen;
576
577
  /* Save number of bits */
578
0
  bits[15] = (unsigned char) (context->count[0] & 0xFF);
579
0
  bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
580
0
  bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
581
0
  bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
582
0
  bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
583
0
  bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
584
0
  bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
585
0
  bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
586
0
  bits[7]  = (unsigned char) (context->count[1] & 0xFF);
587
0
  bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
588
0
  bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
589
0
  bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
590
0
  bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
591
0
  bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
592
0
  bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
593
0
  bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
594
595
  /* Pad out to 112 mod 128.
596
   */
597
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
598
0
  padLen = (index < 112) ? (112 - index) : (240 - index);
599
0
  PHP_SHA384Update(context, PADDING, padLen);
600
601
  /* Append length (before padding) */
602
0
  PHP_SHA384Update(context, bits, 16);
603
604
  /* Store state in digest */
605
0
  SHAEncode64(digest, context->state, 48);
606
607
  /* Zeroize sensitive information.
608
   */
609
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
610
0
}
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
0
{
633
0
  context->count[0] = context->count[1] = 0;
634
  /* Load magic initialization constants.
635
   */
636
0
  context->state[0] = L64(0x6a09e667f3bcc908);
637
0
  context->state[1] = L64(0xbb67ae8584caa73b);
638
0
  context->state[2] = L64(0x3c6ef372fe94f82b);
639
0
  context->state[3] = L64(0xa54ff53a5f1d36f1);
640
0
  context->state[4] = L64(0x510e527fade682d1);
641
0
  context->state[5] = L64(0x9b05688c2b3e6c1f);
642
0
  context->state[6] = L64(0x1f83d9abfb41bd6b);
643
0
  context->state[7] = L64(0x5be0cd19137e2179);
644
0
}
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
0
{
652
0
  context->count[0] = context->count[1] = 0;
653
654
0
  context->state[0] = L64(0x22312194FC2BF72C);
655
0
  context->state[1] = L64(0x9F555FA3C84C64C2);
656
0
  context->state[2] = L64(0x2393B86B6F53B151);
657
0
  context->state[3] = L64(0x963877195940EABD);
658
0
  context->state[4] = L64(0x96283EE2A88EFFE3);
659
0
  context->state[5] = L64(0xBE5E1E2553863992);
660
0
  context->state[6] = L64(0x2B0199FC2C85B8AA);
661
0
  context->state[7] = L64(0x0EB72DDC81C52CA2);
662
0
}
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
0
{
670
0
        context->count[0] = context->count[1] = 0;
671
672
0
  context->state[0] = L64(0x8C3D37C819544DA2);
673
0
  context->state[1] = L64(0x73E1996689DCD4D6);
674
0
  context->state[2] = L64(0x1DFAB7AE32FF9C82);
675
0
  context->state[3] = L64(0x679DD514582F9FCF);
676
0
  context->state[4] = L64(0x0F6D2B697BD44DA8);
677
0
  context->state[5] = L64(0x77E36F7304C48942);
678
0
  context->state[6] = L64(0x3F9D85A86A1D36C8);
679
0
  context->state[7] = L64(0x1112E6AD91D692A1);
680
0
}
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
0
{
690
0
  unsigned int index, partLen;
691
0
  size_t i;
692
693
  /* Compute number of bytes mod 128 */
694
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
695
696
  /* Update number of bits */
697
0
  if ((context->count[0] += ((uint64_t) inputLen << 3)) < ((uint64_t) inputLen << 3)) {
698
0
    context->count[1]++;
699
0
  }
700
  /* The cast may seem unnecessary, but on 32-bit this makes sure the result is 0 without invoking undefined behaviour. */
701
0
  context->count[1] += (uint64_t) inputLen >> 61;
702
703
0
  partLen = 128 - index;
704
705
  /* Transform as many times as possible.
706
   */
707
0
  if (inputLen >= partLen) {
708
0
    memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
709
0
    SHA512Transform(context->state, context->buffer);
710
711
0
    for (i = partLen; i + 127 < inputLen; i += 128) {
712
0
      SHA512Transform(context->state, &input[i]);
713
0
    }
714
715
0
    index = 0;
716
0
  } else {
717
0
    i = 0;
718
0
  }
719
720
  /* Buffer remaining input */
721
0
  memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
722
0
}
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
0
{
731
0
  unsigned char bits[16];
732
0
  unsigned int index, padLen;
733
734
  /* Save number of bits */
735
0
  bits[15] = (unsigned char) (context->count[0] & 0xFF);
736
0
  bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
737
0
  bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
738
0
  bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
739
0
  bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
740
0
  bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
741
0
  bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
742
0
  bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
743
0
  bits[7]  = (unsigned char) (context->count[1] & 0xFF);
744
0
  bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
745
0
  bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
746
0
  bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
747
0
  bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
748
0
  bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
749
0
  bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
750
0
  bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
751
752
  /* Pad out to 112 mod 128.
753
   */
754
0
  index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
755
0
  padLen = (index < 112) ? (112 - index) : (240 - index);
756
0
  PHP_SHA512Update(context, PADDING, padLen);
757
758
  /* Append length (before padding) */
759
0
  PHP_SHA512Update(context, bits, 16);
760
761
  /* Store state in digest */
762
0
  SHAEncode64(digest, context->state, 64);
763
764
  /* Zeroize sensitive information.
765
   */
766
0
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
767
0
}
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
0
{
775
0
  unsigned char full_digest[64];
776
0
  PHP_SHA512Final(full_digest, context);
777
0
  memcpy(digest, full_digest, 32);
778
0
}
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
0
{
786
0
  unsigned char full_digest[64];
787
0
  PHP_SHA512Final(full_digest, context);
788
0
  memcpy(digest, full_digest, 28);
789
0
}
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
};