Coverage Report

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