Coverage Report

Created: 2025-07-23 06:33

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