Coverage Report

Created: 2026-07-25 06:39

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