Coverage Report

Created: 2026-06-02 06:36

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