1817466cbSJens Wiklander /* 2817466cbSJens Wiklander * FIPS-180-1 compliant SHA-1 implementation 3817466cbSJens Wiklander * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8817466cbSJens Wiklander * not use this file except in compliance with the License. 9817466cbSJens Wiklander * You may obtain a copy of the License at 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12817466cbSJens Wiklander * 13817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 14817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16817466cbSJens Wiklander * See the License for the specific language governing permissions and 17817466cbSJens Wiklander * limitations under the License. 18817466cbSJens Wiklander */ 19817466cbSJens Wiklander /* 20817466cbSJens Wiklander * The SHA-1 standard was published by NIST in 1993. 21817466cbSJens Wiklander * 22817466cbSJens Wiklander * http://www.itl.nist.gov/fipspubs/fip180-1.htm 23817466cbSJens Wiklander */ 24817466cbSJens Wiklander 257901324dSJerome Forissier #include "common.h" 26817466cbSJens Wiklander 27817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 28817466cbSJens Wiklander 29817466cbSJens Wiklander #include "mbedtls/sha1.h" 303d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 3111fa71b9SJerome Forissier #include "mbedtls/error.h" 32817466cbSJens Wiklander 33817466cbSJens Wiklander #include <string.h> 34817466cbSJens Wiklander 35817466cbSJens Wiklander #include "mbedtls/platform.h" 363d3b0591SJens Wiklander 373d3b0591SJens Wiklander #if !defined(MBEDTLS_SHA1_ALT) 38817466cbSJens Wiklander 39817466cbSJens Wiklander void mbedtls_sha1_init(mbedtls_sha1_context *ctx) 40817466cbSJens Wiklander { 41817466cbSJens Wiklander memset(ctx, 0, sizeof(mbedtls_sha1_context)); 42817466cbSJens Wiklander } 43817466cbSJens Wiklander 44817466cbSJens Wiklander void mbedtls_sha1_free(mbedtls_sha1_context *ctx) 45817466cbSJens Wiklander { 46*32b31808SJens Wiklander if (ctx == NULL) { 47817466cbSJens Wiklander return; 48*32b31808SJens Wiklander } 49817466cbSJens Wiklander 503d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha1_context)); 51817466cbSJens Wiklander } 52817466cbSJens Wiklander 53817466cbSJens Wiklander void mbedtls_sha1_clone(mbedtls_sha1_context *dst, 54817466cbSJens Wiklander const mbedtls_sha1_context *src) 55817466cbSJens Wiklander { 56817466cbSJens Wiklander *dst = *src; 57817466cbSJens Wiklander } 58817466cbSJens Wiklander 59817466cbSJens Wiklander /* 60817466cbSJens Wiklander * SHA-1 context setup 61817466cbSJens Wiklander */ 62*32b31808SJens Wiklander int mbedtls_sha1_starts(mbedtls_sha1_context *ctx) 63817466cbSJens Wiklander { 64817466cbSJens Wiklander ctx->total[0] = 0; 65817466cbSJens Wiklander ctx->total[1] = 0; 66817466cbSJens Wiklander 67817466cbSJens Wiklander ctx->state[0] = 0x67452301; 68817466cbSJens Wiklander ctx->state[1] = 0xEFCDAB89; 69817466cbSJens Wiklander ctx->state[2] = 0x98BADCFE; 70817466cbSJens Wiklander ctx->state[3] = 0x10325476; 71817466cbSJens Wiklander ctx->state[4] = 0xC3D2E1F0; 723d3b0591SJens Wiklander 73*32b31808SJens Wiklander return 0; 74817466cbSJens Wiklander } 75817466cbSJens Wiklander 76817466cbSJens Wiklander #if !defined(MBEDTLS_SHA1_PROCESS_ALT) 773d3b0591SJens Wiklander int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, 783d3b0591SJens Wiklander const unsigned char data[64]) 79817466cbSJens Wiklander { 80*32b31808SJens Wiklander struct { 81817466cbSJens Wiklander uint32_t temp, W[16], A, B, C, D, E; 827901324dSJerome Forissier } local; 83817466cbSJens Wiklander 84039e02dfSJerome Forissier local.W[0] = MBEDTLS_GET_UINT32_BE(data, 0); 85039e02dfSJerome Forissier local.W[1] = MBEDTLS_GET_UINT32_BE(data, 4); 86039e02dfSJerome Forissier local.W[2] = MBEDTLS_GET_UINT32_BE(data, 8); 87039e02dfSJerome Forissier local.W[3] = MBEDTLS_GET_UINT32_BE(data, 12); 88039e02dfSJerome Forissier local.W[4] = MBEDTLS_GET_UINT32_BE(data, 16); 89039e02dfSJerome Forissier local.W[5] = MBEDTLS_GET_UINT32_BE(data, 20); 90039e02dfSJerome Forissier local.W[6] = MBEDTLS_GET_UINT32_BE(data, 24); 91039e02dfSJerome Forissier local.W[7] = MBEDTLS_GET_UINT32_BE(data, 28); 92039e02dfSJerome Forissier local.W[8] = MBEDTLS_GET_UINT32_BE(data, 32); 93039e02dfSJerome Forissier local.W[9] = MBEDTLS_GET_UINT32_BE(data, 36); 94039e02dfSJerome Forissier local.W[10] = MBEDTLS_GET_UINT32_BE(data, 40); 95039e02dfSJerome Forissier local.W[11] = MBEDTLS_GET_UINT32_BE(data, 44); 96039e02dfSJerome Forissier local.W[12] = MBEDTLS_GET_UINT32_BE(data, 48); 97039e02dfSJerome Forissier local.W[13] = MBEDTLS_GET_UINT32_BE(data, 52); 98039e02dfSJerome Forissier local.W[14] = MBEDTLS_GET_UINT32_BE(data, 56); 99039e02dfSJerome Forissier local.W[15] = MBEDTLS_GET_UINT32_BE(data, 60); 100817466cbSJens Wiklander 1015b25c76aSJerome Forissier #define S(x, n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) 102817466cbSJens Wiklander 103817466cbSJens Wiklander #define R(t) \ 104817466cbSJens Wiklander ( \ 1057901324dSJerome Forissier local.temp = local.W[((t) - 3) & 0x0F] ^ \ 1067901324dSJerome Forissier local.W[((t) - 8) & 0x0F] ^ \ 1077901324dSJerome Forissier local.W[((t) - 14) & 0x0F] ^ \ 1087901324dSJerome Forissier local.W[(t) & 0x0F], \ 1097901324dSJerome Forissier (local.W[(t) & 0x0F] = S(local.temp, 1)) \ 110817466cbSJens Wiklander ) 111817466cbSJens Wiklander 112817466cbSJens Wiklander #define P(a, b, c, d, e, x) \ 1135b25c76aSJerome Forissier do \ 114817466cbSJens Wiklander { \ 1155b25c76aSJerome Forissier (e) += S((a), 5) + F((b), (c), (d)) + K + (x); \ 1165b25c76aSJerome Forissier (b) = S((b), 30); \ 1175b25c76aSJerome Forissier } while (0) 118817466cbSJens Wiklander 1197901324dSJerome Forissier local.A = ctx->state[0]; 1207901324dSJerome Forissier local.B = ctx->state[1]; 1217901324dSJerome Forissier local.C = ctx->state[2]; 1227901324dSJerome Forissier local.D = ctx->state[3]; 1237901324dSJerome Forissier local.E = ctx->state[4]; 124817466cbSJens Wiklander 1255b25c76aSJerome Forissier #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 126817466cbSJens Wiklander #define K 0x5A827999 127817466cbSJens Wiklander 1287901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, local.W[0]); 1297901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, local.W[1]); 1307901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, local.W[2]); 1317901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, local.W[3]); 1327901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, local.W[4]); 1337901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, local.W[5]); 1347901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, local.W[6]); 1357901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, local.W[7]); 1367901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, local.W[8]); 1377901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, local.W[9]); 1387901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, local.W[10]); 1397901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, local.W[11]); 1407901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, local.W[12]); 1417901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, local.W[13]); 1427901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, local.W[14]); 1437901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, local.W[15]); 1447901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(16)); 1457901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(17)); 1467901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(18)); 1477901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(19)); 148817466cbSJens Wiklander 149817466cbSJens Wiklander #undef K 150817466cbSJens Wiklander #undef F 151817466cbSJens Wiklander 1525b25c76aSJerome Forissier #define F(x, y, z) ((x) ^ (y) ^ (z)) 153817466cbSJens Wiklander #define K 0x6ED9EBA1 154817466cbSJens Wiklander 1557901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(20)); 1567901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(21)); 1577901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(22)); 1587901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(23)); 1597901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(24)); 1607901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(25)); 1617901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(26)); 1627901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(27)); 1637901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(28)); 1647901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(29)); 1657901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(30)); 1667901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(31)); 1677901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(32)); 1687901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(33)); 1697901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(34)); 1707901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(35)); 1717901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(36)); 1727901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(37)); 1737901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(38)); 1747901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(39)); 175817466cbSJens Wiklander 176817466cbSJens Wiklander #undef K 177817466cbSJens Wiklander #undef F 178817466cbSJens Wiklander 1795b25c76aSJerome Forissier #define F(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) 180817466cbSJens Wiklander #define K 0x8F1BBCDC 181817466cbSJens Wiklander 1827901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(40)); 1837901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(41)); 1847901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(42)); 1857901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(43)); 1867901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(44)); 1877901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(45)); 1887901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(46)); 1897901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(47)); 1907901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(48)); 1917901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(49)); 1927901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(50)); 1937901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(51)); 1947901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(52)); 1957901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(53)); 1967901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(54)); 1977901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(55)); 1987901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(56)); 1997901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(57)); 2007901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(58)); 2017901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(59)); 202817466cbSJens Wiklander 203817466cbSJens Wiklander #undef K 204817466cbSJens Wiklander #undef F 205817466cbSJens Wiklander 2065b25c76aSJerome Forissier #define F(x, y, z) ((x) ^ (y) ^ (z)) 207817466cbSJens Wiklander #define K 0xCA62C1D6 208817466cbSJens Wiklander 2097901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(60)); 2107901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(61)); 2117901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(62)); 2127901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(63)); 2137901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(64)); 2147901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(65)); 2157901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(66)); 2167901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(67)); 2177901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(68)); 2187901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(69)); 2197901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(70)); 2207901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(71)); 2217901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(72)); 2227901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(73)); 2237901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(74)); 2247901324dSJerome Forissier P(local.A, local.B, local.C, local.D, local.E, R(75)); 2257901324dSJerome Forissier P(local.E, local.A, local.B, local.C, local.D, R(76)); 2267901324dSJerome Forissier P(local.D, local.E, local.A, local.B, local.C, R(77)); 2277901324dSJerome Forissier P(local.C, local.D, local.E, local.A, local.B, R(78)); 2287901324dSJerome Forissier P(local.B, local.C, local.D, local.E, local.A, R(79)); 229817466cbSJens Wiklander 230817466cbSJens Wiklander #undef K 231817466cbSJens Wiklander #undef F 232817466cbSJens Wiklander 2337901324dSJerome Forissier ctx->state[0] += local.A; 2347901324dSJerome Forissier ctx->state[1] += local.B; 2357901324dSJerome Forissier ctx->state[2] += local.C; 2367901324dSJerome Forissier ctx->state[3] += local.D; 2377901324dSJerome Forissier ctx->state[4] += local.E; 2387901324dSJerome Forissier 2397901324dSJerome Forissier /* Zeroise buffers and variables to clear sensitive data from memory. */ 2407901324dSJerome Forissier mbedtls_platform_zeroize(&local, sizeof(local)); 2413d3b0591SJens Wiklander 242*32b31808SJens Wiklander return 0; 243817466cbSJens Wiklander } 2443d3b0591SJens Wiklander 245817466cbSJens Wiklander #endif /* !MBEDTLS_SHA1_PROCESS_ALT */ 246817466cbSJens Wiklander 247817466cbSJens Wiklander /* 248817466cbSJens Wiklander * SHA-1 process buffer 249817466cbSJens Wiklander */ 250*32b31808SJens Wiklander int mbedtls_sha1_update(mbedtls_sha1_context *ctx, 2513d3b0591SJens Wiklander const unsigned char *input, 2523d3b0591SJens Wiklander size_t ilen) 253817466cbSJens Wiklander { 25411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 255817466cbSJens Wiklander size_t fill; 256817466cbSJens Wiklander uint32_t left; 257817466cbSJens Wiklander 258*32b31808SJens Wiklander if (ilen == 0) { 259*32b31808SJens Wiklander return 0; 260*32b31808SJens Wiklander } 261817466cbSJens Wiklander 262817466cbSJens Wiklander left = ctx->total[0] & 0x3F; 263817466cbSJens Wiklander fill = 64 - left; 264817466cbSJens Wiklander 265817466cbSJens Wiklander ctx->total[0] += (uint32_t) ilen; 266817466cbSJens Wiklander ctx->total[0] &= 0xFFFFFFFF; 267817466cbSJens Wiklander 268*32b31808SJens Wiklander if (ctx->total[0] < (uint32_t) ilen) { 269817466cbSJens Wiklander ctx->total[1]++; 270*32b31808SJens Wiklander } 271817466cbSJens Wiklander 272*32b31808SJens Wiklander if (left && ilen >= fill) { 273817466cbSJens Wiklander memcpy((void *) (ctx->buffer + left), input, fill); 2743d3b0591SJens Wiklander 275*32b31808SJens Wiklander if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0) { 276*32b31808SJens Wiklander return ret; 277*32b31808SJens Wiklander } 2783d3b0591SJens Wiklander 279817466cbSJens Wiklander input += fill; 280817466cbSJens Wiklander ilen -= fill; 281817466cbSJens Wiklander left = 0; 282817466cbSJens Wiklander } 283817466cbSJens Wiklander 284*32b31808SJens Wiklander while (ilen >= 64) { 285*32b31808SJens Wiklander if ((ret = mbedtls_internal_sha1_process(ctx, input)) != 0) { 286*32b31808SJens Wiklander return ret; 287*32b31808SJens Wiklander } 2883d3b0591SJens Wiklander 289817466cbSJens Wiklander input += 64; 290817466cbSJens Wiklander ilen -= 64; 291817466cbSJens Wiklander } 292817466cbSJens Wiklander 293*32b31808SJens Wiklander if (ilen > 0) { 294817466cbSJens Wiklander memcpy((void *) (ctx->buffer + left), input, ilen); 295817466cbSJens Wiklander } 296817466cbSJens Wiklander 297*32b31808SJens Wiklander return 0; 2983d3b0591SJens Wiklander } 299817466cbSJens Wiklander 300817466cbSJens Wiklander /* 301817466cbSJens Wiklander * SHA-1 final digest 302817466cbSJens Wiklander */ 303*32b31808SJens Wiklander int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, 3043d3b0591SJens Wiklander unsigned char output[20]) 305817466cbSJens Wiklander { 30611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3073d3b0591SJens Wiklander uint32_t used; 308817466cbSJens Wiklander uint32_t high, low; 309817466cbSJens Wiklander 3103d3b0591SJens Wiklander /* 3113d3b0591SJens Wiklander * Add padding: 0x80 then 0x00 until 8 bytes remain for the length 3123d3b0591SJens Wiklander */ 3133d3b0591SJens Wiklander used = ctx->total[0] & 0x3F; 3143d3b0591SJens Wiklander 3153d3b0591SJens Wiklander ctx->buffer[used++] = 0x80; 3163d3b0591SJens Wiklander 317*32b31808SJens Wiklander if (used <= 56) { 3183d3b0591SJens Wiklander /* Enough room for padding + length in current block */ 3193d3b0591SJens Wiklander memset(ctx->buffer + used, 0, 56 - used); 320*32b31808SJens Wiklander } else { 3213d3b0591SJens Wiklander /* We'll need an extra block */ 3223d3b0591SJens Wiklander memset(ctx->buffer + used, 0, 64 - used); 3233d3b0591SJens Wiklander 324*32b31808SJens Wiklander if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0) { 325*32b31808SJens Wiklander return ret; 326*32b31808SJens Wiklander } 3273d3b0591SJens Wiklander 3283d3b0591SJens Wiklander memset(ctx->buffer, 0, 56); 3293d3b0591SJens Wiklander } 3303d3b0591SJens Wiklander 3313d3b0591SJens Wiklander /* 3323d3b0591SJens Wiklander * Add message length 3333d3b0591SJens Wiklander */ 334817466cbSJens Wiklander high = (ctx->total[0] >> 29) 335817466cbSJens Wiklander | (ctx->total[1] << 3); 336817466cbSJens Wiklander low = (ctx->total[0] << 3); 337817466cbSJens Wiklander 338039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56); 339039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60); 340817466cbSJens Wiklander 341*32b31808SJens Wiklander if ((ret = mbedtls_internal_sha1_process(ctx, ctx->buffer)) != 0) { 342*32b31808SJens Wiklander return ret; 343*32b31808SJens Wiklander } 344817466cbSJens Wiklander 3453d3b0591SJens Wiklander /* 3463d3b0591SJens Wiklander * Output final state 3473d3b0591SJens Wiklander */ 348039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0); 349039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4); 350039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8); 351039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12); 352039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16); 3533d3b0591SJens Wiklander 354*32b31808SJens Wiklander return 0; 355817466cbSJens Wiklander } 356817466cbSJens Wiklander 357817466cbSJens Wiklander #endif /* !MBEDTLS_SHA1_ALT */ 358817466cbSJens Wiklander 359817466cbSJens Wiklander /* 360817466cbSJens Wiklander * output = SHA-1( input buffer ) 361817466cbSJens Wiklander */ 362*32b31808SJens Wiklander int mbedtls_sha1(const unsigned char *input, 3633d3b0591SJens Wiklander size_t ilen, 3643d3b0591SJens Wiklander unsigned char output[20]) 365817466cbSJens Wiklander { 36611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 367817466cbSJens Wiklander mbedtls_sha1_context ctx; 368817466cbSJens Wiklander 369817466cbSJens Wiklander mbedtls_sha1_init(&ctx); 3703d3b0591SJens Wiklander 371*32b31808SJens Wiklander if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { 3723d3b0591SJens Wiklander goto exit; 373*32b31808SJens Wiklander } 3743d3b0591SJens Wiklander 375*32b31808SJens Wiklander if ((ret = mbedtls_sha1_update(&ctx, input, ilen)) != 0) { 3763d3b0591SJens Wiklander goto exit; 377*32b31808SJens Wiklander } 3783d3b0591SJens Wiklander 379*32b31808SJens Wiklander if ((ret = mbedtls_sha1_finish(&ctx, output)) != 0) { 3803d3b0591SJens Wiklander goto exit; 381*32b31808SJens Wiklander } 3823d3b0591SJens Wiklander 3833d3b0591SJens Wiklander exit: 384817466cbSJens Wiklander mbedtls_sha1_free(&ctx); 3853d3b0591SJens Wiklander 386*32b31808SJens Wiklander return ret; 387817466cbSJens Wiklander } 388817466cbSJens Wiklander 389817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 390817466cbSJens Wiklander /* 391817466cbSJens Wiklander * FIPS-180-1 test vectors 392817466cbSJens Wiklander */ 393817466cbSJens Wiklander static const unsigned char sha1_test_buf[3][57] = 394817466cbSJens Wiklander { 395817466cbSJens Wiklander { "abc" }, 396817466cbSJens Wiklander { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 397817466cbSJens Wiklander { "" } 398817466cbSJens Wiklander }; 399817466cbSJens Wiklander 4003d3b0591SJens Wiklander static const size_t sha1_test_buflen[3] = 401817466cbSJens Wiklander { 402817466cbSJens Wiklander 3, 56, 1000 403817466cbSJens Wiklander }; 404817466cbSJens Wiklander 405817466cbSJens Wiklander static const unsigned char sha1_test_sum[3][20] = 406817466cbSJens Wiklander { 407817466cbSJens Wiklander { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 408817466cbSJens Wiklander 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, 409817466cbSJens Wiklander { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 410817466cbSJens Wiklander 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, 411817466cbSJens Wiklander { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, 412817466cbSJens Wiklander 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } 413817466cbSJens Wiklander }; 414817466cbSJens Wiklander 415817466cbSJens Wiklander /* 416817466cbSJens Wiklander * Checkup routine 417817466cbSJens Wiklander */ 418817466cbSJens Wiklander int mbedtls_sha1_self_test(int verbose) 419817466cbSJens Wiklander { 420817466cbSJens Wiklander int i, j, buflen, ret = 0; 421817466cbSJens Wiklander unsigned char buf[1024]; 422817466cbSJens Wiklander unsigned char sha1sum[20]; 423817466cbSJens Wiklander mbedtls_sha1_context ctx; 424817466cbSJens Wiklander 425817466cbSJens Wiklander mbedtls_sha1_init(&ctx); 426817466cbSJens Wiklander 427817466cbSJens Wiklander /* 428817466cbSJens Wiklander * SHA-1 429817466cbSJens Wiklander */ 430*32b31808SJens Wiklander for (i = 0; i < 3; i++) { 431*32b31808SJens Wiklander if (verbose != 0) { 432817466cbSJens Wiklander mbedtls_printf(" SHA-1 test #%d: ", i + 1); 433*32b31808SJens Wiklander } 434817466cbSJens Wiklander 435*32b31808SJens Wiklander if ((ret = mbedtls_sha1_starts(&ctx)) != 0) { 4363d3b0591SJens Wiklander goto fail; 437*32b31808SJens Wiklander } 438817466cbSJens Wiklander 439*32b31808SJens Wiklander if (i == 2) { 440817466cbSJens Wiklander memset(buf, 'a', buflen = 1000); 441817466cbSJens Wiklander 442*32b31808SJens Wiklander for (j = 0; j < 1000; j++) { 443*32b31808SJens Wiklander ret = mbedtls_sha1_update(&ctx, buf, buflen); 444*32b31808SJens Wiklander if (ret != 0) { 4453d3b0591SJens Wiklander goto fail; 4463d3b0591SJens Wiklander } 447817466cbSJens Wiklander } 448*32b31808SJens Wiklander } else { 449*32b31808SJens Wiklander ret = mbedtls_sha1_update(&ctx, sha1_test_buf[i], 450817466cbSJens Wiklander sha1_test_buflen[i]); 451*32b31808SJens Wiklander if (ret != 0) { 452*32b31808SJens Wiklander goto fail; 453*32b31808SJens Wiklander } 454*32b31808SJens Wiklander } 455*32b31808SJens Wiklander 456*32b31808SJens Wiklander if ((ret = mbedtls_sha1_finish(&ctx, sha1sum)) != 0) { 4573d3b0591SJens Wiklander goto fail; 4583d3b0591SJens Wiklander } 459817466cbSJens Wiklander 460*32b31808SJens Wiklander if (memcmp(sha1sum, sha1_test_sum[i], 20) != 0) { 461817466cbSJens Wiklander ret = 1; 4623d3b0591SJens Wiklander goto fail; 463817466cbSJens Wiklander } 464817466cbSJens Wiklander 465*32b31808SJens Wiklander if (verbose != 0) { 466817466cbSJens Wiklander mbedtls_printf("passed\n"); 467817466cbSJens Wiklander } 468*32b31808SJens Wiklander } 469817466cbSJens Wiklander 470*32b31808SJens Wiklander if (verbose != 0) { 471817466cbSJens Wiklander mbedtls_printf("\n"); 472*32b31808SJens Wiklander } 473817466cbSJens Wiklander 4743d3b0591SJens Wiklander goto exit; 4753d3b0591SJens Wiklander 4763d3b0591SJens Wiklander fail: 477*32b31808SJens Wiklander if (verbose != 0) { 4783d3b0591SJens Wiklander mbedtls_printf("failed\n"); 479*32b31808SJens Wiklander } 4803d3b0591SJens Wiklander 481817466cbSJens Wiklander exit: 482817466cbSJens Wiklander mbedtls_sha1_free(&ctx); 483817466cbSJens Wiklander 484*32b31808SJens Wiklander return ret; 485817466cbSJens Wiklander } 486817466cbSJens Wiklander 487817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 488817466cbSJens Wiklander 489817466cbSJens Wiklander #endif /* MBEDTLS_SHA1_C */ 490