Coverage Report

Created: 2026-10-28 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/standard/sha1.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
   | Author: Stefan Esser <sesser@php.net>                                |
12
   +----------------------------------------------------------------------+
13
*/
14
15
#include "php.h"
16
17
/* This code is heavily based on the PHP md5 implementation */
18
19
#include "sha1.h"
20
#include "md5.h"
21
22
PHPAPI void make_sha1_digest(char *sha1str, const unsigned char *digest)
23
0
{
24
0
  make_digest_ex(sha1str, digest, 20);
25
0
}
26
27
/* {{{ Calculate the sha1 hash of a string */
28
PHP_FUNCTION(sha1)
29
0
{
30
0
  zend_string *arg;
31
0
  bool raw_output = 0;
32
0
  PHP_SHA1_CTX context;
33
0
  unsigned char digest[20];
34
35
0
  ZEND_PARSE_PARAMETERS_START(1, 2)
36
0
    Z_PARAM_STR(arg)
37
0
    Z_PARAM_OPTIONAL
38
0
    Z_PARAM_BOOL(raw_output)
39
0
  ZEND_PARSE_PARAMETERS_END();
40
41
0
  PHP_SHA1Init(&context);
42
0
  PHP_SHA1Update(&context, (unsigned char *) ZSTR_VAL(arg), ZSTR_LEN(arg));
43
0
  PHP_SHA1Final(digest, &context);
44
0
  if (raw_output) {
45
0
    RETURN_STRINGL((char *) digest, 20);
46
0
  } else {
47
0
    RETVAL_NEW_STR(zend_string_alloc(40, 0));
48
0
    make_digest_ex(Z_STRVAL_P(return_value), digest, 20);
49
0
  }
50
51
0
}
52
53
/* }}} */
54
55
56
/* {{{ Calculate the sha1 hash of given filename */
57
PHP_FUNCTION(sha1_file)
58
0
{
59
0
  char          *arg;
60
0
  size_t           arg_len;
61
0
  bool raw_output = 0;
62
0
  unsigned char buf[1024];
63
0
  unsigned char digest[20];
64
0
  PHP_SHA1_CTX   context;
65
0
  ssize_t        n;
66
0
  php_stream    *stream;
67
68
0
  ZEND_PARSE_PARAMETERS_START(1, 2)
69
0
    Z_PARAM_PATH(arg, arg_len)
70
0
    Z_PARAM_OPTIONAL
71
0
    Z_PARAM_BOOL(raw_output)
72
0
  ZEND_PARSE_PARAMETERS_END();
73
74
0
  stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, NULL);
75
0
  if (!stream) {
76
0
    RETURN_FALSE;
77
0
  }
78
79
0
  PHP_SHA1Init(&context);
80
81
0
  while ((n = php_stream_read(stream, (char *) buf, sizeof(buf))) > 0) {
82
0
    PHP_SHA1Update(&context, buf, n);
83
0
  }
84
85
0
  bool failed = n < 0 || !php_stream_eof(stream);
86
87
0
  PHP_SHA1Final(digest, &context);
88
89
0
  php_stream_close(stream);
90
91
0
  if (failed) {
92
0
    RETURN_FALSE;
93
0
  }
94
95
0
  if (raw_output) {
96
0
    RETURN_STRINGL((char *) digest, 20);
97
0
  } else {
98
0
    RETVAL_NEW_STR(zend_string_alloc(40, 0));
99
0
    make_digest_ex(Z_STRVAL_P(return_value), digest, 20);
100
0
  }
101
0
}
102
/* }}} */
103
104
105
static void SHA1Transform(uint32_t[5], const unsigned char[64]);
106
static void SHA1Encode(unsigned char *, uint32_t *, unsigned int);
107
static void SHA1Decode(uint32_t *, const unsigned char *, unsigned int);
108
109
static const unsigned char PADDING[64] =
110
{
111
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
114
};
115
116
/* F, G, H and I are basic SHA1 functions.
117
 */
118
673k
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
119
673k
#define G(x, y, z) ((x) ^ (y) ^ (z))
120
673k
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
121
673k
#define I(x, y, z) ((x) ^ (y) ^ (z))
122
123
/* ROTATE_LEFT rotates x left n bits.
124
 */
125
5.38M
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
126
127
/* W[i]
128
 */
129
#define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
130
  (x[i&15]=ROTATE_LEFT(tmp, 1)) )
131
132
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
133
 */
134
673k
#define FF(a, b, c, d, e, w) { \
135
673k
 (e) += F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \
136
673k
 (e) += ROTATE_LEFT ((a), 5); \
137
673k
 (b) = ROTATE_LEFT((b), 30); \
138
673k
  }
139
673k
#define GG(a, b, c, d, e, w) { \
140
673k
 (e) += G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \
141
673k
 (e) += ROTATE_LEFT ((a), 5); \
142
673k
 (b) = ROTATE_LEFT((b), 30); \
143
673k
  }
144
673k
#define HH(a, b, c, d, e, w) { \
145
673k
 (e) += H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \
146
673k
 (e) += ROTATE_LEFT ((a), 5); \
147
673k
 (b) = ROTATE_LEFT((b), 30); \
148
673k
  }
149
673k
#define II(a, b, c, d, e, w) { \
150
673k
 (e) += I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \
151
673k
 (e) += ROTATE_LEFT ((a), 5); \
152
673k
 (b) = ROTATE_LEFT((b), 30); \
153
673k
  }
154
155
156
/* {{{ PHP_SHA1Init
157
 * SHA1 initialization. Begins an SHA1 operation, writing a new context.
158
 */
159
PHPAPI void PHP_SHA1InitArgs(PHP_SHA1_CTX * context, ZEND_ATTRIBUTE_UNUSED HashTable *args)
160
116
{
161
116
  context->count[0] = context->count[1] = 0;
162
  /* Load magic initialization constants.
163
   */
164
116
  context->state[0] = 0x67452301;
165
116
  context->state[1] = 0xefcdab89;
166
116
  context->state[2] = 0x98badcfe;
167
116
  context->state[3] = 0x10325476;
168
116
  context->state[4] = 0xc3d2e1f0;
169
116
}
170
/* }}} */
171
172
/* {{{ PHP_SHA1Update
173
   SHA1 block update operation. Continues an SHA1 message-digest
174
   operation, processing another message block, and updating the
175
   context.
176
 */
177
PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
178
         size_t inputLen)
179
345
{
180
345
  unsigned int index, partLen;
181
345
  size_t i;
182
183
  /* Compute number of bytes mod 64 */
184
345
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
185
186
  /* Update number of bits */
187
345
  if ((context->count[0] += ((uint32_t) inputLen << 3))
188
345
    < ((uint32_t) inputLen << 3))
189
8
    context->count[1]++;
190
345
  context->count[1] += (uint32_t) (inputLen >> 29);
191
192
345
  partLen = 64 - index;
193
194
  /* Transform as many times as possible.
195
   */
196
345
  if (inputLen >= partLen) {
197
224
    memcpy
198
224
      ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
199
224
    SHA1Transform(context->state, context->buffer);
200
201
33.6k
    for (i = partLen; i + 63 < inputLen; i += 64)
202
33.4k
      SHA1Transform(context->state, &input[i]);
203
204
224
    index = 0;
205
224
  } else
206
121
    i = 0;
207
208
  /* Buffer remaining input */
209
345
  memcpy
210
345
    ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
211
345
     inputLen - i);
212
345
}
213
/* }}} */
214
215
/* {{{ PHP_SHA1Final
216
   SHA1 finalization. Ends an SHA1 message-digest operation, writing the
217
   the message digest and zeroizing the context.
218
 */
219
PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
220
115
{
221
115
  unsigned char bits[8];
222
115
  unsigned int index, padLen;
223
224
  /* Save number of bits */
225
115
  bits[7] = context->count[0] & 0xFF;
226
115
  bits[6] = (context->count[0] >> 8) & 0xFF;
227
115
  bits[5] = (context->count[0] >> 16) & 0xFF;
228
115
  bits[4] = (context->count[0] >> 24) & 0xFF;
229
115
  bits[3] = context->count[1] & 0xFF;
230
115
  bits[2] = (context->count[1] >> 8) & 0xFF;
231
115
  bits[1] = (context->count[1] >> 16) & 0xFF;
232
115
  bits[0] = (context->count[1] >> 24) & 0xFF;
233
234
  /* Pad out to 56 mod 64.
235
   */
236
115
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
237
115
  padLen = (index < 56) ? (56 - index) : (120 - index);
238
115
  PHP_SHA1Update(context, PADDING, padLen);
239
240
  /* Append length (before padding) */
241
115
  PHP_SHA1Update(context, bits, 8);
242
243
  /* Store state in digest */
244
115
  SHA1Encode(digest, context->state, 20);
245
246
  /* Zeroize sensitive information.
247
   */
248
115
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
249
115
}
250
/* }}} */
251
252
/* {{{ SHA1Transform
253
 * SHA1 basic transformation. Transforms state based on block.
254
 */
255
static void SHA1Transform(uint32_t state[5], const unsigned char block[64])
256
33.6k
{
257
33.6k
  uint32_t a = state[0], b = state[1], c = state[2];
258
33.6k
  uint32_t d = state[3], e = state[4], x[16], tmp;
259
260
33.6k
  SHA1Decode(x, block, 64);
261
262
  /* Round 1 */
263
33.6k
  FF(a, b, c, d, e, x[0]);   /* 1 */
264
33.6k
  FF(e, a, b, c, d, x[1]);   /* 2 */
265
33.6k
  FF(d, e, a, b, c, x[2]);   /* 3 */
266
33.6k
  FF(c, d, e, a, b, x[3]);   /* 4 */
267
33.6k
  FF(b, c, d, e, a, x[4]);   /* 5 */
268
33.6k
  FF(a, b, c, d, e, x[5]);   /* 6 */
269
33.6k
  FF(e, a, b, c, d, x[6]);   /* 7 */
270
33.6k
  FF(d, e, a, b, c, x[7]);   /* 8 */
271
33.6k
  FF(c, d, e, a, b, x[8]);   /* 9 */
272
33.6k
  FF(b, c, d, e, a, x[9]);   /* 10 */
273
33.6k
  FF(a, b, c, d, e, x[10]);  /* 11 */
274
33.6k
  FF(e, a, b, c, d, x[11]);  /* 12 */
275
33.6k
  FF(d, e, a, b, c, x[12]);  /* 13 */
276
33.6k
  FF(c, d, e, a, b, x[13]);  /* 14 */
277
33.6k
  FF(b, c, d, e, a, x[14]);  /* 15 */
278
33.6k
  FF(a, b, c, d, e, x[15]);  /* 16 */
279
33.6k
  FF(e, a, b, c, d, W(16));  /* 17 */
280
33.6k
  FF(d, e, a, b, c, W(17));  /* 18 */
281
33.6k
  FF(c, d, e, a, b, W(18));  /* 19 */
282
33.6k
  FF(b, c, d, e, a, W(19));  /* 20 */
283
284
  /* Round 2 */
285
33.6k
  GG(a, b, c, d, e, W(20));  /* 21 */
286
33.6k
  GG(e, a, b, c, d, W(21));  /* 22 */
287
33.6k
  GG(d, e, a, b, c, W(22));  /* 23 */
288
33.6k
  GG(c, d, e, a, b, W(23));  /* 24 */
289
33.6k
  GG(b, c, d, e, a, W(24));  /* 25 */
290
33.6k
  GG(a, b, c, d, e, W(25));  /* 26 */
291
33.6k
  GG(e, a, b, c, d, W(26));  /* 27 */
292
33.6k
  GG(d, e, a, b, c, W(27));  /* 28 */
293
33.6k
  GG(c, d, e, a, b, W(28));  /* 29 */
294
33.6k
  GG(b, c, d, e, a, W(29));  /* 30 */
295
33.6k
  GG(a, b, c, d, e, W(30));  /* 31 */
296
33.6k
  GG(e, a, b, c, d, W(31));  /* 32 */
297
33.6k
  GG(d, e, a, b, c, W(32));  /* 33 */
298
33.6k
  GG(c, d, e, a, b, W(33));  /* 34 */
299
33.6k
  GG(b, c, d, e, a, W(34));  /* 35 */
300
33.6k
  GG(a, b, c, d, e, W(35));  /* 36 */
301
33.6k
  GG(e, a, b, c, d, W(36));  /* 37 */
302
33.6k
  GG(d, e, a, b, c, W(37));  /* 38 */
303
33.6k
  GG(c, d, e, a, b, W(38));  /* 39 */
304
33.6k
  GG(b, c, d, e, a, W(39));  /* 40 */
305
306
  /* Round 3 */
307
33.6k
  HH(a, b, c, d, e, W(40));  /* 41 */
308
33.6k
  HH(e, a, b, c, d, W(41));  /* 42 */
309
33.6k
  HH(d, e, a, b, c, W(42));  /* 43 */
310
33.6k
  HH(c, d, e, a, b, W(43));  /* 44 */
311
33.6k
  HH(b, c, d, e, a, W(44));  /* 45 */
312
33.6k
  HH(a, b, c, d, e, W(45));  /* 46 */
313
33.6k
  HH(e, a, b, c, d, W(46));  /* 47 */
314
33.6k
  HH(d, e, a, b, c, W(47));  /* 48 */
315
33.6k
  HH(c, d, e, a, b, W(48));  /* 49 */
316
33.6k
  HH(b, c, d, e, a, W(49));  /* 50 */
317
33.6k
  HH(a, b, c, d, e, W(50));  /* 51 */
318
33.6k
  HH(e, a, b, c, d, W(51));  /* 52 */
319
33.6k
  HH(d, e, a, b, c, W(52));  /* 53 */
320
33.6k
  HH(c, d, e, a, b, W(53));  /* 54 */
321
33.6k
  HH(b, c, d, e, a, W(54));  /* 55 */
322
33.6k
  HH(a, b, c, d, e, W(55));  /* 56 */
323
33.6k
  HH(e, a, b, c, d, W(56));  /* 57 */
324
33.6k
  HH(d, e, a, b, c, W(57));  /* 58 */
325
33.6k
  HH(c, d, e, a, b, W(58));  /* 59 */
326
33.6k
  HH(b, c, d, e, a, W(59));  /* 60 */
327
328
  /* Round 4 */
329
33.6k
  II(a, b, c, d, e, W(60));  /* 61 */
330
33.6k
  II(e, a, b, c, d, W(61));  /* 62 */
331
33.6k
  II(d, e, a, b, c, W(62));  /* 63 */
332
33.6k
  II(c, d, e, a, b, W(63));  /* 64 */
333
33.6k
  II(b, c, d, e, a, W(64));  /* 65 */
334
33.6k
  II(a, b, c, d, e, W(65));  /* 66 */
335
33.6k
  II(e, a, b, c, d, W(66));  /* 67 */
336
33.6k
  II(d, e, a, b, c, W(67));  /* 68 */
337
33.6k
  II(c, d, e, a, b, W(68));  /* 69 */
338
33.6k
  II(b, c, d, e, a, W(69));  /* 70 */
339
33.6k
  II(a, b, c, d, e, W(70));  /* 71 */
340
33.6k
  II(e, a, b, c, d, W(71));  /* 72 */
341
33.6k
  II(d, e, a, b, c, W(72));  /* 73 */
342
33.6k
  II(c, d, e, a, b, W(73));  /* 74 */
343
33.6k
  II(b, c, d, e, a, W(74));  /* 75 */
344
33.6k
  II(a, b, c, d, e, W(75));  /* 76 */
345
33.6k
  II(e, a, b, c, d, W(76));  /* 77 */
346
33.6k
  II(d, e, a, b, c, W(77));  /* 78 */
347
33.6k
  II(c, d, e, a, b, W(78));  /* 79 */
348
33.6k
  II(b, c, d, e, a, W(79));  /* 80 */
349
350
33.6k
  state[0] += a;
351
33.6k
  state[1] += b;
352
33.6k
  state[2] += c;
353
33.6k
  state[3] += d;
354
33.6k
  state[4] += e;
355
356
  /* Zeroize sensitive information. */
357
33.6k
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
358
33.6k
}
359
/* }}} */
360
361
/* {{{ SHA1Encode
362
   Encodes input (uint32_t) into output (unsigned char). Assumes len is
363
   a multiple of 4.
364
 */
365
static void SHA1Encode(unsigned char *output, uint32_t *input, unsigned int len)
366
115
{
367
115
  unsigned int i, j;
368
369
690
  for (i = 0, j = 0; j < len; i++, j += 4) {
370
575
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
371
575
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
372
575
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
373
575
    output[j + 3] = (unsigned char) (input[i] & 0xff);
374
575
  }
375
115
}
376
/* }}} */
377
378
/* {{{ SHA1Decode
379
   Decodes input (unsigned char) into output (uint32_t). Assumes len is
380
   a multiple of 4.
381
 */
382
static void SHA1Decode(uint32_t *output, const unsigned char *input, unsigned int len)
383
33.6k
{
384
33.6k
  unsigned int i, j;
385
386
572k
  for (i = 0, j = 0; j < len; i++, j += 4)
387
538k
    output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
388
538k
      (((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
389
33.6k
}
390
/* }}} */