Coverage Report

Created: 2026-04-01 06:49

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