Coverage Report

Created: 2026-09-14 06:25

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