Coverage Report

Created: 2026-06-13 07:01

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
242k
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
113
242k
#define G(x, y, z) ((x) ^ (y) ^ (z))
114
242k
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
115
242k
#define I(x, y, z) ((x) ^ (y) ^ (z))
116
117
/* ROTATE_LEFT rotates x left n bits.
118
 */
119
1.93M
#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
242k
#define FF(a, b, c, d, e, w) { \
129
242k
 (e) += F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \
130
242k
 (e) += ROTATE_LEFT ((a), 5); \
131
242k
 (b) = ROTATE_LEFT((b), 30); \
132
242k
  }
133
242k
#define GG(a, b, c, d, e, w) { \
134
242k
 (e) += G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \
135
242k
 (e) += ROTATE_LEFT ((a), 5); \
136
242k
 (b) = ROTATE_LEFT((b), 30); \
137
242k
  }
138
242k
#define HH(a, b, c, d, e, w) { \
139
242k
 (e) += H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \
140
242k
 (e) += ROTATE_LEFT ((a), 5); \
141
242k
 (b) = ROTATE_LEFT((b), 30); \
142
242k
  }
143
242k
#define II(a, b, c, d, e, w) { \
144
242k
 (e) += I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \
145
242k
 (e) += ROTATE_LEFT ((a), 5); \
146
242k
 (b) = ROTATE_LEFT((b), 30); \
147
242k
  }
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
85
{
155
85
  context->count[0] = context->count[1] = 0;
156
  /* Load magic initialization constants.
157
   */
158
85
  context->state[0] = 0x67452301;
159
85
  context->state[1] = 0xefcdab89;
160
85
  context->state[2] = 0x98badcfe;
161
85
  context->state[3] = 0x10325476;
162
85
  context->state[4] = 0xc3d2e1f0;
163
85
}
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
249
{
174
249
  unsigned int index, partLen;
175
249
  size_t i;
176
177
  /* Compute number of bytes mod 64 */
178
249
  index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
179
180
  /* Update number of bits */
181
249
  if ((context->count[0] += ((uint32_t) inputLen << 3))
182
249
    < ((uint32_t) inputLen << 3))
183
6
    context->count[1]++;
184
249
  context->count[1] += (uint32_t) (inputLen >> 29);
185
186
249
  partLen = 64 - index;
187
188
  /* Transform as many times as possible.
189
   */
190
249
  if (inputLen >= partLen) {
191
173
    memcpy
192
173
      ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
193
173
    SHA1Transform(context->state, context->buffer);
194
195
12.1k
    for (i = partLen; i + 63 < inputLen; i += 64)
196
11.9k
      SHA1Transform(context->state, &input[i]);
197
198
173
    index = 0;
199
173
  } else
200
76
    i = 0;
201
202
  /* Buffer remaining input */
203
249
  memcpy
204
249
    ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
205
249
     inputLen - i);
206
249
}
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
83
{
215
83
  unsigned char bits[8];
216
83
  unsigned int index, padLen;
217
218
  /* Save number of bits */
219
83
  bits[7] = context->count[0] & 0xFF;
220
83
  bits[6] = (context->count[0] >> 8) & 0xFF;
221
83
  bits[5] = (context->count[0] >> 16) & 0xFF;
222
83
  bits[4] = (context->count[0] >> 24) & 0xFF;
223
83
  bits[3] = context->count[1] & 0xFF;
224
83
  bits[2] = (context->count[1] >> 8) & 0xFF;
225
83
  bits[1] = (context->count[1] >> 16) & 0xFF;
226
83
  bits[0] = (context->count[1] >> 24) & 0xFF;
227
228
  /* Pad out to 56 mod 64.
229
   */
230
83
  index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
231
83
  padLen = (index < 56) ? (56 - index) : (120 - index);
232
83
  PHP_SHA1Update(context, PADDING, padLen);
233
234
  /* Append length (before padding) */
235
83
  PHP_SHA1Update(context, bits, 8);
236
237
  /* Store state in digest */
238
83
  SHA1Encode(digest, context->state, 20);
239
240
  /* Zeroize sensitive information.
241
   */
242
83
  ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
243
83
}
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
12.1k
{
251
12.1k
  uint32_t a = state[0], b = state[1], c = state[2];
252
12.1k
  uint32_t d = state[3], e = state[4], x[16], tmp;
253
254
12.1k
  SHA1Decode(x, block, 64);
255
256
  /* Round 1 */
257
12.1k
  FF(a, b, c, d, e, x[0]);   /* 1 */
258
12.1k
  FF(e, a, b, c, d, x[1]);   /* 2 */
259
12.1k
  FF(d, e, a, b, c, x[2]);   /* 3 */
260
12.1k
  FF(c, d, e, a, b, x[3]);   /* 4 */
261
12.1k
  FF(b, c, d, e, a, x[4]);   /* 5 */
262
12.1k
  FF(a, b, c, d, e, x[5]);   /* 6 */
263
12.1k
  FF(e, a, b, c, d, x[6]);   /* 7 */
264
12.1k
  FF(d, e, a, b, c, x[7]);   /* 8 */
265
12.1k
  FF(c, d, e, a, b, x[8]);   /* 9 */
266
12.1k
  FF(b, c, d, e, a, x[9]);   /* 10 */
267
12.1k
  FF(a, b, c, d, e, x[10]);  /* 11 */
268
12.1k
  FF(e, a, b, c, d, x[11]);  /* 12 */
269
12.1k
  FF(d, e, a, b, c, x[12]);  /* 13 */
270
12.1k
  FF(c, d, e, a, b, x[13]);  /* 14 */
271
12.1k
  FF(b, c, d, e, a, x[14]);  /* 15 */
272
12.1k
  FF(a, b, c, d, e, x[15]);  /* 16 */
273
12.1k
  FF(e, a, b, c, d, W(16));  /* 17 */
274
12.1k
  FF(d, e, a, b, c, W(17));  /* 18 */
275
12.1k
  FF(c, d, e, a, b, W(18));  /* 19 */
276
12.1k
  FF(b, c, d, e, a, W(19));  /* 20 */
277
278
  /* Round 2 */
279
12.1k
  GG(a, b, c, d, e, W(20));  /* 21 */
280
12.1k
  GG(e, a, b, c, d, W(21));  /* 22 */
281
12.1k
  GG(d, e, a, b, c, W(22));  /* 23 */
282
12.1k
  GG(c, d, e, a, b, W(23));  /* 24 */
283
12.1k
  GG(b, c, d, e, a, W(24));  /* 25 */
284
12.1k
  GG(a, b, c, d, e, W(25));  /* 26 */
285
12.1k
  GG(e, a, b, c, d, W(26));  /* 27 */
286
12.1k
  GG(d, e, a, b, c, W(27));  /* 28 */
287
12.1k
  GG(c, d, e, a, b, W(28));  /* 29 */
288
12.1k
  GG(b, c, d, e, a, W(29));  /* 30 */
289
12.1k
  GG(a, b, c, d, e, W(30));  /* 31 */
290
12.1k
  GG(e, a, b, c, d, W(31));  /* 32 */
291
12.1k
  GG(d, e, a, b, c, W(32));  /* 33 */
292
12.1k
  GG(c, d, e, a, b, W(33));  /* 34 */
293
12.1k
  GG(b, c, d, e, a, W(34));  /* 35 */
294
12.1k
  GG(a, b, c, d, e, W(35));  /* 36 */
295
12.1k
  GG(e, a, b, c, d, W(36));  /* 37 */
296
12.1k
  GG(d, e, a, b, c, W(37));  /* 38 */
297
12.1k
  GG(c, d, e, a, b, W(38));  /* 39 */
298
12.1k
  GG(b, c, d, e, a, W(39));  /* 40 */
299
300
  /* Round 3 */
301
12.1k
  HH(a, b, c, d, e, W(40));  /* 41 */
302
12.1k
  HH(e, a, b, c, d, W(41));  /* 42 */
303
12.1k
  HH(d, e, a, b, c, W(42));  /* 43 */
304
12.1k
  HH(c, d, e, a, b, W(43));  /* 44 */
305
12.1k
  HH(b, c, d, e, a, W(44));  /* 45 */
306
12.1k
  HH(a, b, c, d, e, W(45));  /* 46 */
307
12.1k
  HH(e, a, b, c, d, W(46));  /* 47 */
308
12.1k
  HH(d, e, a, b, c, W(47));  /* 48 */
309
12.1k
  HH(c, d, e, a, b, W(48));  /* 49 */
310
12.1k
  HH(b, c, d, e, a, W(49));  /* 50 */
311
12.1k
  HH(a, b, c, d, e, W(50));  /* 51 */
312
12.1k
  HH(e, a, b, c, d, W(51));  /* 52 */
313
12.1k
  HH(d, e, a, b, c, W(52));  /* 53 */
314
12.1k
  HH(c, d, e, a, b, W(53));  /* 54 */
315
12.1k
  HH(b, c, d, e, a, W(54));  /* 55 */
316
12.1k
  HH(a, b, c, d, e, W(55));  /* 56 */
317
12.1k
  HH(e, a, b, c, d, W(56));  /* 57 */
318
12.1k
  HH(d, e, a, b, c, W(57));  /* 58 */
319
12.1k
  HH(c, d, e, a, b, W(58));  /* 59 */
320
12.1k
  HH(b, c, d, e, a, W(59));  /* 60 */
321
322
  /* Round 4 */
323
12.1k
  II(a, b, c, d, e, W(60));  /* 61 */
324
12.1k
  II(e, a, b, c, d, W(61));  /* 62 */
325
12.1k
  II(d, e, a, b, c, W(62));  /* 63 */
326
12.1k
  II(c, d, e, a, b, W(63));  /* 64 */
327
12.1k
  II(b, c, d, e, a, W(64));  /* 65 */
328
12.1k
  II(a, b, c, d, e, W(65));  /* 66 */
329
12.1k
  II(e, a, b, c, d, W(66));  /* 67 */
330
12.1k
  II(d, e, a, b, c, W(67));  /* 68 */
331
12.1k
  II(c, d, e, a, b, W(68));  /* 69 */
332
12.1k
  II(b, c, d, e, a, W(69));  /* 70 */
333
12.1k
  II(a, b, c, d, e, W(70));  /* 71 */
334
12.1k
  II(e, a, b, c, d, W(71));  /* 72 */
335
12.1k
  II(d, e, a, b, c, W(72));  /* 73 */
336
12.1k
  II(c, d, e, a, b, W(73));  /* 74 */
337
12.1k
  II(b, c, d, e, a, W(74));  /* 75 */
338
12.1k
  II(a, b, c, d, e, W(75));  /* 76 */
339
12.1k
  II(e, a, b, c, d, W(76));  /* 77 */
340
12.1k
  II(d, e, a, b, c, W(77));  /* 78 */
341
12.1k
  II(c, d, e, a, b, W(78));  /* 79 */
342
12.1k
  II(b, c, d, e, a, W(79));  /* 80 */
343
344
12.1k
  state[0] += a;
345
12.1k
  state[1] += b;
346
12.1k
  state[2] += c;
347
12.1k
  state[3] += d;
348
12.1k
  state[4] += e;
349
350
  /* Zeroize sensitive information. */
351
12.1k
  ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
352
12.1k
}
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
83
{
361
83
  unsigned int i, j;
362
363
498
  for (i = 0, j = 0; j < len; i++, j += 4) {
364
415
    output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
365
415
    output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
366
415
    output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
367
415
    output[j + 3] = (unsigned char) (input[i] & 0xff);
368
415
  }
369
83
}
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
12.1k
{
378
12.1k
  unsigned int i, j;
379
380
206k
  for (i = 0, j = 0; j < len; i++, j += 4)
381
193k
    output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
382
193k
      (((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
383
12.1k
}
384
/* }}} */