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