1/* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 *  FIPS-180-1 compliant SHA-1 implementation
18 *
19 *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
20 *  SPDX-License-Identifier: Apache-2.0
21 *
22 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
23 *  not use this file except in compliance with the License.
24 *  You may obtain a copy of the License at
25 *
26 *  http://www.apache.org/licenses/LICENSE-2.0
27 *
28 *  Unless required by applicable law or agreed to in writing, software
29 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
30 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 *  See the License for the specific language governing permissions and
32 *  limitations under the License.
33 *
34 *  This file is part of mbed TLS (https://tls.mbed.org)
35 */
36
37/*
38 *  The SHA-1 standard was published by NIST in 1993.
39 *
40 *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
41 */
42
43#include "debugger-sha1.h"
44#include "jext-common.h"
45
46#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
47
48/**
49 * SHA-1 context structure.
50 */
51typedef struct
52{
53  uint32_t total[2]; /**< number of bytes processed */
54  uint32_t state[5]; /**< intermediate digest state */
55  uint8_t buffer[64]; /**< data block being processed */
56} jerryx_sha1_context;
57
58/* 32-bit integer manipulation macros (big endian). */
59
60#define JERRYX_SHA1_GET_UINT32_BE(n, b, i) \
61{ \
62  (n) = (((uint32_t) (b)[(i) + 0]) << 24) \
63        | (((uint32_t) (b)[(i) + 1]) << 16) \
64        | (((uint32_t) (b)[(i) + 2]) << 8) \
65        | ((uint32_t) (b)[(i) + 3]); \
66}
67
68#define JERRYX_SHA1_PUT_UINT32_BE(n, b, i) \
69{ \
70  (b)[(i) + 0] = (uint8_t) ((n) >> 24); \
71  (b)[(i) + 1] = (uint8_t) ((n) >> 16); \
72  (b)[(i) + 2] = (uint8_t) ((n) >> 8); \
73  (b)[(i) + 3] = (uint8_t) ((n)); \
74}
75
76/**
77 * Initialize SHA-1 context.
78 */
79static void
80jerryx_sha1_init (jerryx_sha1_context *sha1_context_p) /**< SHA-1 context */
81{
82  memset (sha1_context_p, 0, sizeof (jerryx_sha1_context));
83
84  sha1_context_p->total[0] = 0;
85  sha1_context_p->total[1] = 0;
86
87  sha1_context_p->state[0] = 0x67452301;
88  sha1_context_p->state[1] = 0xEFCDAB89;
89  sha1_context_p->state[2] = 0x98BADCFE;
90  sha1_context_p->state[3] = 0x10325476;
91  sha1_context_p->state[4] = 0xC3D2E1F0;
92} /* jerryx_sha1_init */
93
94#define JERRYX_SHA1_P(a, b, c, d, e, x) \
95do { \
96  e += JERRYX_SHA1_SHIFT (a, 5) + JERRYX_SHA1_F (b, c, d) + K + x; \
97  b = JERRYX_SHA1_SHIFT (b, 30); \
98} while (0)
99
100/**
101 * Update SHA-1 internal buffer status.
102 */
103static void
104jerryx_sha1_process (jerryx_sha1_context *sha1_context_p, /**< SHA-1 context */
105                     const uint8_t data[64]) /**< data buffer */
106{
107  uint32_t temp, W[16], A, B, C, D, E;
108
109  JERRYX_SHA1_GET_UINT32_BE (W[0], data, 0);
110  JERRYX_SHA1_GET_UINT32_BE (W[1], data, 4);
111  JERRYX_SHA1_GET_UINT32_BE (W[2], data, 8);
112  JERRYX_SHA1_GET_UINT32_BE (W[3], data, 12);
113  JERRYX_SHA1_GET_UINT32_BE (W[4], data, 16);
114  JERRYX_SHA1_GET_UINT32_BE (W[5], data, 20);
115  JERRYX_SHA1_GET_UINT32_BE (W[6], data, 24);
116  JERRYX_SHA1_GET_UINT32_BE (W[7], data, 28);
117  JERRYX_SHA1_GET_UINT32_BE (W[8], data, 32);
118  JERRYX_SHA1_GET_UINT32_BE (W[9], data, 36);
119  JERRYX_SHA1_GET_UINT32_BE (W[10], data, 40);
120  JERRYX_SHA1_GET_UINT32_BE (W[11], data, 44);
121  JERRYX_SHA1_GET_UINT32_BE (W[12], data, 48);
122  JERRYX_SHA1_GET_UINT32_BE (W[13], data, 52);
123  JERRYX_SHA1_GET_UINT32_BE (W[14], data, 56);
124  JERRYX_SHA1_GET_UINT32_BE (W[15], data, 60);
125
126#define JERRYX_SHA1_SHIFT(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
127
128#define JERRYX_SHA1_R(t) \
129( \
130  temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], \
131  W[t & 0x0F] = JERRYX_SHA1_SHIFT (temp, 1) \
132)
133
134  A = sha1_context_p->state[0];
135  B = sha1_context_p->state[1];
136  C = sha1_context_p->state[2];
137  D = sha1_context_p->state[3];
138  E = sha1_context_p->state[4];
139
140  uint32_t K = 0x5A827999;
141
142#define JERRYX_SHA1_F(x, y, z) (z ^ (x & (y ^ z)))
143
144  JERRYX_SHA1_P (A, B, C, D, E, W[0]);
145  JERRYX_SHA1_P (E, A, B, C, D, W[1]);
146  JERRYX_SHA1_P (D, E, A, B, C, W[2]);
147  JERRYX_SHA1_P (C, D, E, A, B, W[3]);
148  JERRYX_SHA1_P (B, C, D, E, A, W[4]);
149  JERRYX_SHA1_P (A, B, C, D, E, W[5]);
150  JERRYX_SHA1_P (E, A, B, C, D, W[6]);
151  JERRYX_SHA1_P (D, E, A, B, C, W[7]);
152  JERRYX_SHA1_P (C, D, E, A, B, W[8]);
153  JERRYX_SHA1_P (B, C, D, E, A, W[9]);
154  JERRYX_SHA1_P (A, B, C, D, E, W[10]);
155  JERRYX_SHA1_P (E, A, B, C, D, W[11]);
156  JERRYX_SHA1_P (D, E, A, B, C, W[12]);
157  JERRYX_SHA1_P (C, D, E, A, B, W[13]);
158  JERRYX_SHA1_P (B, C, D, E, A, W[14]);
159  JERRYX_SHA1_P (A, B, C, D, E, W[15]);
160  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (16));
161  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (17));
162  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (18));
163  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (19));
164
165#undef JERRYX_SHA1_F
166
167  K = 0x6ED9EBA1;
168
169#define JERRYX_SHA1_F(x, y, z) (x ^ y ^ z)
170
171  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (20));
172  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (21));
173  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (22));
174  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (23));
175  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (24));
176  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (25));
177  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (26));
178  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (27));
179  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (28));
180  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (29));
181  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (30));
182  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (31));
183  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (32));
184  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (33));
185  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (34));
186  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (35));
187  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (36));
188  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (37));
189  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (38));
190  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (39));
191
192#undef JERRYX_SHA1_F
193
194  K = 0x8F1BBCDC;
195
196#define JERRYX_SHA1_F(x, y, z) ((x & y) | (z & (x | y)))
197
198  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (40));
199  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (41));
200  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (42));
201  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (43));
202  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (44));
203  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (45));
204  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (46));
205  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (47));
206  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (48));
207  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (49));
208  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (50));
209  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (51));
210  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (52));
211  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (53));
212  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (54));
213  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (55));
214  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (56));
215  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (57));
216  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (58));
217  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (59));
218
219#undef JERRYX_SHA1_F
220
221  K = 0xCA62C1D6;
222
223#define JERRYX_SHA1_F(x, y, z) (x ^ y ^ z)
224
225  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (60));
226  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (61));
227  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (62));
228  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (63));
229  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (64));
230  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (65));
231  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (66));
232  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (67));
233  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (68));
234  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (69));
235  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (70));
236  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (71));
237  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (72));
238  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (73));
239  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (74));
240  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (75));
241  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (76));
242  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (77));
243  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (78));
244  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (79));
245
246#undef JERRYX_SHA1_F
247
248  sha1_context_p->state[0] += A;
249  sha1_context_p->state[1] += B;
250  sha1_context_p->state[2] += C;
251  sha1_context_p->state[3] += D;
252  sha1_context_p->state[4] += E;
253
254#undef JERRYX_SHA1_SHIFT
255#undef JERRYX_SHA1_R
256} /* jerryx_sha1_process */
257
258#undef JERRYX_SHA1_P
259
260/**
261 * SHA-1 update buffer.
262 */
263static void
264jerryx_sha1_update (jerryx_sha1_context *sha1_context_p, /**< SHA-1 context */
265                    const uint8_t *source_p, /**< source buffer */
266                    size_t source_length) /**< length of source buffer */
267{
268  size_t fill;
269  uint32_t left;
270
271  if (source_length == 0)
272  {
273    return;
274  }
275
276  left = sha1_context_p->total[0] & 0x3F;
277  fill = 64 - left;
278
279  sha1_context_p->total[0] += (uint32_t) source_length;
280
281  /* Check overflow. */
282  if (sha1_context_p->total[0] < (uint32_t) source_length)
283  {
284    sha1_context_p->total[1]++;
285  }
286
287  if (left && source_length >= fill)
288  {
289    memcpy ((void *) (sha1_context_p->buffer + left), source_p, fill);
290    jerryx_sha1_process (sha1_context_p, sha1_context_p->buffer);
291    source_p += fill;
292    source_length -= fill;
293    left = 0;
294  }
295
296  while (source_length >= 64)
297  {
298    jerryx_sha1_process (sha1_context_p, source_p);
299    source_p += 64;
300    source_length -= 64;
301  }
302
303  if (source_length > 0)
304  {
305    memcpy ((void *) (sha1_context_p->buffer + left), source_p, source_length);
306  }
307} /* jerryx_sha1_update */
308
309/**
310 * SHA-1 final digest.
311 */
312static void
313jerryx_sha1_finish (jerryx_sha1_context *sha1_context_p, /**< SHA-1 context */
314                    uint8_t destination_p[20]) /**< result */
315{
316  uint8_t buffer[16];
317
318  uint32_t high = (sha1_context_p->total[0] >> 29) | (sha1_context_p->total[1] << 3);
319  uint32_t low = (sha1_context_p->total[0] << 3);
320
321  uint32_t last = sha1_context_p->total[0] & 0x3F;
322  uint32_t padn = (last < 56) ? (56 - last) : (120 - last);
323
324  memset (buffer, 0, sizeof (buffer));
325  buffer[0] = 0x80;
326
327  while (padn > sizeof (buffer))
328  {
329    jerryx_sha1_update (sha1_context_p, buffer, sizeof (buffer));
330    buffer[0] = 0;
331    padn -= (uint32_t) sizeof (buffer);
332  }
333
334  jerryx_sha1_update (sha1_context_p, buffer, padn);
335
336  JERRYX_SHA1_PUT_UINT32_BE (high, buffer, 0);
337  JERRYX_SHA1_PUT_UINT32_BE (low, buffer, 4);
338
339  jerryx_sha1_update (sha1_context_p, buffer, 8);
340
341  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[0], destination_p, 0);
342  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[1], destination_p, 4);
343  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[2], destination_p, 8);
344  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[3], destination_p, 12);
345  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[4], destination_p, 16);
346} /* jerryx_sha1_finish */
347
348#undef JERRYX_SHA1_GET_UINT32_BE
349#undef JERRYX_SHA1_PUT_UINT32_BE
350
351/**
352 * Computes the SHA-1 value of the combination of the two input buffers.
353 */
354void
355jerryx_debugger_compute_sha1 (const uint8_t *source1_p, /**< first part of the input */
356                              size_t source1_length, /**< length of the first part */
357                              const uint8_t *source2_p, /**< second part of the input */
358                              size_t source2_length, /**< length of the second part */
359                              uint8_t destination_p[20]) /**< result */
360{
361  jerryx_sha1_context sha1_context;
362
363  jerryx_sha1_init (&sha1_context);
364  jerryx_sha1_update (&sha1_context, source1_p, source1_length);
365  jerryx_sha1_update (&sha1_context, source2_p, source2_length);
366  jerryx_sha1_finish (&sha1_context, destination_p);
367} /* jerryx_debugger_compute_sha1 */
368
369#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
370