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 #if defined(MBEDTLS_SELF_TEST) 36817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 37817466cbSJens Wiklander #include "mbedtls/platform.h" 38817466cbSJens Wiklander #else 39817466cbSJens Wiklander #include <stdio.h> 40817466cbSJens Wiklander #define mbedtls_printf printf 41817466cbSJens Wiklander #endif /* MBEDTLS_PLATFORM_C */ 42817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 43817466cbSJens Wiklander 443d3b0591SJens Wiklander #define SHA1_VALIDATE_RET(cond) \ 453d3b0591SJens Wiklander MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) 46817466cbSJens Wiklander 473d3b0591SJens Wiklander #define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) 483d3b0591SJens Wiklander 493d3b0591SJens Wiklander #if !defined(MBEDTLS_SHA1_ALT) 50817466cbSJens Wiklander 51817466cbSJens Wiklander void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) 52817466cbSJens Wiklander { 533d3b0591SJens Wiklander SHA1_VALIDATE( ctx != NULL ); 543d3b0591SJens Wiklander 55817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); 56817466cbSJens Wiklander } 57817466cbSJens Wiklander 58817466cbSJens Wiklander void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) 59817466cbSJens Wiklander { 60817466cbSJens Wiklander if( ctx == NULL ) 61817466cbSJens Wiklander return; 62817466cbSJens Wiklander 633d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); 64817466cbSJens Wiklander } 65817466cbSJens Wiklander 66817466cbSJens Wiklander void mbedtls_sha1_clone( mbedtls_sha1_context *dst, 67817466cbSJens Wiklander const mbedtls_sha1_context *src ) 68817466cbSJens Wiklander { 693d3b0591SJens Wiklander SHA1_VALIDATE( dst != NULL ); 703d3b0591SJens Wiklander SHA1_VALIDATE( src != NULL ); 713d3b0591SJens Wiklander 72817466cbSJens Wiklander *dst = *src; 73817466cbSJens Wiklander } 74817466cbSJens Wiklander 75817466cbSJens Wiklander /* 76817466cbSJens Wiklander * SHA-1 context setup 77817466cbSJens Wiklander */ 783d3b0591SJens Wiklander int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) 79817466cbSJens Wiklander { 803d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 813d3b0591SJens Wiklander 82817466cbSJens Wiklander ctx->total[0] = 0; 83817466cbSJens Wiklander ctx->total[1] = 0; 84817466cbSJens Wiklander 85817466cbSJens Wiklander ctx->state[0] = 0x67452301; 86817466cbSJens Wiklander ctx->state[1] = 0xEFCDAB89; 87817466cbSJens Wiklander ctx->state[2] = 0x98BADCFE; 88817466cbSJens Wiklander ctx->state[3] = 0x10325476; 89817466cbSJens Wiklander ctx->state[4] = 0xC3D2E1F0; 903d3b0591SJens Wiklander 913d3b0591SJens Wiklander return( 0 ); 92817466cbSJens Wiklander } 93817466cbSJens Wiklander 943d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 953d3b0591SJens Wiklander void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) 963d3b0591SJens Wiklander { 973d3b0591SJens Wiklander mbedtls_sha1_starts_ret( ctx ); 983d3b0591SJens Wiklander } 993d3b0591SJens Wiklander #endif 1003d3b0591SJens Wiklander 101817466cbSJens Wiklander #if !defined(MBEDTLS_SHA1_PROCESS_ALT) 1023d3b0591SJens Wiklander int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, 1033d3b0591SJens Wiklander const unsigned char data[64] ) 104817466cbSJens Wiklander { 1057901324dSJerome Forissier struct 1067901324dSJerome Forissier { 107817466cbSJens Wiklander uint32_t temp, W[16], A, B, C, D, E; 1087901324dSJerome Forissier } local; 109817466cbSJens Wiklander 1103d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 1113d3b0591SJens Wiklander SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); 1123d3b0591SJens Wiklander 113*039e02dfSJerome Forissier local.W[ 0] = MBEDTLS_GET_UINT32_BE( data, 0 ); 114*039e02dfSJerome Forissier local.W[ 1] = MBEDTLS_GET_UINT32_BE( data, 4 ); 115*039e02dfSJerome Forissier local.W[ 2] = MBEDTLS_GET_UINT32_BE( data, 8 ); 116*039e02dfSJerome Forissier local.W[ 3] = MBEDTLS_GET_UINT32_BE( data, 12 ); 117*039e02dfSJerome Forissier local.W[ 4] = MBEDTLS_GET_UINT32_BE( data, 16 ); 118*039e02dfSJerome Forissier local.W[ 5] = MBEDTLS_GET_UINT32_BE( data, 20 ); 119*039e02dfSJerome Forissier local.W[ 6] = MBEDTLS_GET_UINT32_BE( data, 24 ); 120*039e02dfSJerome Forissier local.W[ 7] = MBEDTLS_GET_UINT32_BE( data, 28 ); 121*039e02dfSJerome Forissier local.W[ 8] = MBEDTLS_GET_UINT32_BE( data, 32 ); 122*039e02dfSJerome Forissier local.W[ 9] = MBEDTLS_GET_UINT32_BE( data, 36 ); 123*039e02dfSJerome Forissier local.W[10] = MBEDTLS_GET_UINT32_BE( data, 40 ); 124*039e02dfSJerome Forissier local.W[11] = MBEDTLS_GET_UINT32_BE( data, 44 ); 125*039e02dfSJerome Forissier local.W[12] = MBEDTLS_GET_UINT32_BE( data, 48 ); 126*039e02dfSJerome Forissier local.W[13] = MBEDTLS_GET_UINT32_BE( data, 52 ); 127*039e02dfSJerome Forissier local.W[14] = MBEDTLS_GET_UINT32_BE( data, 56 ); 128*039e02dfSJerome Forissier local.W[15] = MBEDTLS_GET_UINT32_BE( data, 60 ); 129817466cbSJens Wiklander 1305b25c76aSJerome Forissier #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) 131817466cbSJens Wiklander 132817466cbSJens Wiklander #define R(t) \ 133817466cbSJens Wiklander ( \ 1347901324dSJerome Forissier local.temp = local.W[( (t) - 3 ) & 0x0F] ^ \ 1357901324dSJerome Forissier local.W[( (t) - 8 ) & 0x0F] ^ \ 1367901324dSJerome Forissier local.W[( (t) - 14 ) & 0x0F] ^ \ 1377901324dSJerome Forissier local.W[ (t) & 0x0F], \ 1387901324dSJerome Forissier ( local.W[(t) & 0x0F] = S(local.temp,1) ) \ 139817466cbSJens Wiklander ) 140817466cbSJens Wiklander 141817466cbSJens Wiklander #define P(a,b,c,d,e,x) \ 1425b25c76aSJerome Forissier do \ 143817466cbSJens Wiklander { \ 1445b25c76aSJerome Forissier (e) += S((a),5) + F((b),(c),(d)) + K + (x); \ 1455b25c76aSJerome Forissier (b) = S((b),30); \ 1465b25c76aSJerome Forissier } while( 0 ) 147817466cbSJens Wiklander 1487901324dSJerome Forissier local.A = ctx->state[0]; 1497901324dSJerome Forissier local.B = ctx->state[1]; 1507901324dSJerome Forissier local.C = ctx->state[2]; 1517901324dSJerome Forissier local.D = ctx->state[3]; 1527901324dSJerome Forissier local.E = ctx->state[4]; 153817466cbSJens Wiklander 1545b25c76aSJerome Forissier #define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) 155817466cbSJens Wiklander #define K 0x5A827999 156817466cbSJens Wiklander 1577901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, local.W[0] ); 1587901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, local.W[1] ); 1597901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, local.W[2] ); 1607901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, local.W[3] ); 1617901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, local.W[4] ); 1627901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, local.W[5] ); 1637901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, local.W[6] ); 1647901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, local.W[7] ); 1657901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, local.W[8] ); 1667901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, local.W[9] ); 1677901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, local.W[10] ); 1687901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, local.W[11] ); 1697901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, local.W[12] ); 1707901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, local.W[13] ); 1717901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, local.W[14] ); 1727901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, local.W[15] ); 1737901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(16) ); 1747901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(17) ); 1757901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(18) ); 1767901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(19) ); 177817466cbSJens Wiklander 178817466cbSJens Wiklander #undef K 179817466cbSJens Wiklander #undef F 180817466cbSJens Wiklander 1815b25c76aSJerome Forissier #define F(x,y,z) ((x) ^ (y) ^ (z)) 182817466cbSJens Wiklander #define K 0x6ED9EBA1 183817466cbSJens Wiklander 1847901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(20) ); 1857901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(21) ); 1867901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(22) ); 1877901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(23) ); 1887901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(24) ); 1897901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(25) ); 1907901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(26) ); 1917901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(27) ); 1927901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(28) ); 1937901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(29) ); 1947901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(30) ); 1957901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(31) ); 1967901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(32) ); 1977901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(33) ); 1987901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(34) ); 1997901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(35) ); 2007901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(36) ); 2017901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(37) ); 2027901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(38) ); 2037901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(39) ); 204817466cbSJens Wiklander 205817466cbSJens Wiklander #undef K 206817466cbSJens Wiklander #undef F 207817466cbSJens Wiklander 2085b25c76aSJerome Forissier #define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) 209817466cbSJens Wiklander #define K 0x8F1BBCDC 210817466cbSJens Wiklander 2117901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(40) ); 2127901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(41) ); 2137901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(42) ); 2147901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(43) ); 2157901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(44) ); 2167901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(45) ); 2177901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(46) ); 2187901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(47) ); 2197901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(48) ); 2207901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(49) ); 2217901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(50) ); 2227901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(51) ); 2237901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(52) ); 2247901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(53) ); 2257901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(54) ); 2267901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(55) ); 2277901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(56) ); 2287901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(57) ); 2297901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(58) ); 2307901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(59) ); 231817466cbSJens Wiklander 232817466cbSJens Wiklander #undef K 233817466cbSJens Wiklander #undef F 234817466cbSJens Wiklander 2355b25c76aSJerome Forissier #define F(x,y,z) ((x) ^ (y) ^ (z)) 236817466cbSJens Wiklander #define K 0xCA62C1D6 237817466cbSJens Wiklander 2387901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(60) ); 2397901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(61) ); 2407901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(62) ); 2417901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(63) ); 2427901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(64) ); 2437901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(65) ); 2447901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(66) ); 2457901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(67) ); 2467901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(68) ); 2477901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(69) ); 2487901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(70) ); 2497901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(71) ); 2507901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(72) ); 2517901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(73) ); 2527901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(74) ); 2537901324dSJerome Forissier P( local.A, local.B, local.C, local.D, local.E, R(75) ); 2547901324dSJerome Forissier P( local.E, local.A, local.B, local.C, local.D, R(76) ); 2557901324dSJerome Forissier P( local.D, local.E, local.A, local.B, local.C, R(77) ); 2567901324dSJerome Forissier P( local.C, local.D, local.E, local.A, local.B, R(78) ); 2577901324dSJerome Forissier P( local.B, local.C, local.D, local.E, local.A, R(79) ); 258817466cbSJens Wiklander 259817466cbSJens Wiklander #undef K 260817466cbSJens Wiklander #undef F 261817466cbSJens Wiklander 2627901324dSJerome Forissier ctx->state[0] += local.A; 2637901324dSJerome Forissier ctx->state[1] += local.B; 2647901324dSJerome Forissier ctx->state[2] += local.C; 2657901324dSJerome Forissier ctx->state[3] += local.D; 2667901324dSJerome Forissier ctx->state[4] += local.E; 2677901324dSJerome Forissier 2687901324dSJerome Forissier /* Zeroise buffers and variables to clear sensitive data from memory. */ 2697901324dSJerome Forissier mbedtls_platform_zeroize( &local, sizeof( local ) ); 2703d3b0591SJens Wiklander 2713d3b0591SJens Wiklander return( 0 ); 272817466cbSJens Wiklander } 2733d3b0591SJens Wiklander 2743d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 2753d3b0591SJens Wiklander void mbedtls_sha1_process( mbedtls_sha1_context *ctx, 2763d3b0591SJens Wiklander const unsigned char data[64] ) 2773d3b0591SJens Wiklander { 2783d3b0591SJens Wiklander mbedtls_internal_sha1_process( ctx, data ); 2793d3b0591SJens Wiklander } 2803d3b0591SJens Wiklander #endif 281817466cbSJens Wiklander #endif /* !MBEDTLS_SHA1_PROCESS_ALT */ 282817466cbSJens Wiklander 283817466cbSJens Wiklander /* 284817466cbSJens Wiklander * SHA-1 process buffer 285817466cbSJens Wiklander */ 2863d3b0591SJens Wiklander int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, 2873d3b0591SJens Wiklander const unsigned char *input, 2883d3b0591SJens Wiklander size_t ilen ) 289817466cbSJens Wiklander { 29011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 291817466cbSJens Wiklander size_t fill; 292817466cbSJens Wiklander uint32_t left; 293817466cbSJens Wiklander 2943d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 2953d3b0591SJens Wiklander SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); 2963d3b0591SJens Wiklander 297817466cbSJens Wiklander if( ilen == 0 ) 2983d3b0591SJens Wiklander return( 0 ); 299817466cbSJens Wiklander 300817466cbSJens Wiklander left = ctx->total[0] & 0x3F; 301817466cbSJens Wiklander fill = 64 - left; 302817466cbSJens Wiklander 303817466cbSJens Wiklander ctx->total[0] += (uint32_t) ilen; 304817466cbSJens Wiklander ctx->total[0] &= 0xFFFFFFFF; 305817466cbSJens Wiklander 306817466cbSJens Wiklander if( ctx->total[0] < (uint32_t) ilen ) 307817466cbSJens Wiklander ctx->total[1]++; 308817466cbSJens Wiklander 309817466cbSJens Wiklander if( left && ilen >= fill ) 310817466cbSJens Wiklander { 311817466cbSJens Wiklander memcpy( (void *) (ctx->buffer + left), input, fill ); 3123d3b0591SJens Wiklander 3133d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 3143d3b0591SJens Wiklander return( ret ); 3153d3b0591SJens Wiklander 316817466cbSJens Wiklander input += fill; 317817466cbSJens Wiklander ilen -= fill; 318817466cbSJens Wiklander left = 0; 319817466cbSJens Wiklander } 320817466cbSJens Wiklander 321817466cbSJens Wiklander while( ilen >= 64 ) 322817466cbSJens Wiklander { 3233d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) 3243d3b0591SJens Wiklander return( ret ); 3253d3b0591SJens Wiklander 326817466cbSJens Wiklander input += 64; 327817466cbSJens Wiklander ilen -= 64; 328817466cbSJens Wiklander } 329817466cbSJens Wiklander 330817466cbSJens Wiklander if( ilen > 0 ) 331817466cbSJens Wiklander memcpy( (void *) (ctx->buffer + left), input, ilen ); 3323d3b0591SJens Wiklander 3333d3b0591SJens Wiklander return( 0 ); 334817466cbSJens Wiklander } 335817466cbSJens Wiklander 3363d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 3373d3b0591SJens Wiklander void mbedtls_sha1_update( mbedtls_sha1_context *ctx, 3383d3b0591SJens Wiklander const unsigned char *input, 3393d3b0591SJens Wiklander size_t ilen ) 340817466cbSJens Wiklander { 3413d3b0591SJens Wiklander mbedtls_sha1_update_ret( ctx, input, ilen ); 3423d3b0591SJens Wiklander } 3433d3b0591SJens Wiklander #endif 344817466cbSJens Wiklander 345817466cbSJens Wiklander /* 346817466cbSJens Wiklander * SHA-1 final digest 347817466cbSJens Wiklander */ 3483d3b0591SJens Wiklander int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, 3493d3b0591SJens Wiklander unsigned char output[20] ) 350817466cbSJens Wiklander { 35111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3523d3b0591SJens Wiklander uint32_t used; 353817466cbSJens Wiklander uint32_t high, low; 354817466cbSJens Wiklander 3553d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 3563d3b0591SJens Wiklander SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); 3573d3b0591SJens Wiklander 3583d3b0591SJens Wiklander /* 3593d3b0591SJens Wiklander * Add padding: 0x80 then 0x00 until 8 bytes remain for the length 3603d3b0591SJens Wiklander */ 3613d3b0591SJens Wiklander used = ctx->total[0] & 0x3F; 3623d3b0591SJens Wiklander 3633d3b0591SJens Wiklander ctx->buffer[used++] = 0x80; 3643d3b0591SJens Wiklander 3653d3b0591SJens Wiklander if( used <= 56 ) 3663d3b0591SJens Wiklander { 3673d3b0591SJens Wiklander /* Enough room for padding + length in current block */ 3683d3b0591SJens Wiklander memset( ctx->buffer + used, 0, 56 - used ); 3693d3b0591SJens Wiklander } 3703d3b0591SJens Wiklander else 3713d3b0591SJens Wiklander { 3723d3b0591SJens Wiklander /* We'll need an extra block */ 3733d3b0591SJens Wiklander memset( ctx->buffer + used, 0, 64 - used ); 3743d3b0591SJens Wiklander 3753d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 3763d3b0591SJens Wiklander return( ret ); 3773d3b0591SJens Wiklander 3783d3b0591SJens Wiklander memset( ctx->buffer, 0, 56 ); 3793d3b0591SJens Wiklander } 3803d3b0591SJens Wiklander 3813d3b0591SJens Wiklander /* 3823d3b0591SJens Wiklander * Add message length 3833d3b0591SJens Wiklander */ 384817466cbSJens Wiklander high = ( ctx->total[0] >> 29 ) 385817466cbSJens Wiklander | ( ctx->total[1] << 3 ); 386817466cbSJens Wiklander low = ( ctx->total[0] << 3 ); 387817466cbSJens Wiklander 388*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 ); 389*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 ); 390817466cbSJens Wiklander 3913d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 3923d3b0591SJens Wiklander return( ret ); 393817466cbSJens Wiklander 3943d3b0591SJens Wiklander /* 3953d3b0591SJens Wiklander * Output final state 3963d3b0591SJens Wiklander */ 397*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 ); 398*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 ); 399*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 ); 400*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 ); 401*039e02dfSJerome Forissier MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 ); 4023d3b0591SJens Wiklander 4033d3b0591SJens Wiklander return( 0 ); 404817466cbSJens Wiklander } 405817466cbSJens Wiklander 4063d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 4073d3b0591SJens Wiklander void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, 4083d3b0591SJens Wiklander unsigned char output[20] ) 4093d3b0591SJens Wiklander { 4103d3b0591SJens Wiklander mbedtls_sha1_finish_ret( ctx, output ); 4113d3b0591SJens Wiklander } 4123d3b0591SJens Wiklander #endif 4133d3b0591SJens Wiklander 414817466cbSJens Wiklander #endif /* !MBEDTLS_SHA1_ALT */ 415817466cbSJens Wiklander 416817466cbSJens Wiklander /* 417817466cbSJens Wiklander * output = SHA-1( input buffer ) 418817466cbSJens Wiklander */ 4193d3b0591SJens Wiklander int mbedtls_sha1_ret( const unsigned char *input, 4203d3b0591SJens Wiklander size_t ilen, 4213d3b0591SJens Wiklander unsigned char output[20] ) 422817466cbSJens Wiklander { 42311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 424817466cbSJens Wiklander mbedtls_sha1_context ctx; 425817466cbSJens Wiklander 4263d3b0591SJens Wiklander SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); 4273d3b0591SJens Wiklander SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); 4283d3b0591SJens Wiklander 429817466cbSJens Wiklander mbedtls_sha1_init( &ctx ); 4303d3b0591SJens Wiklander 4313d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) 4323d3b0591SJens Wiklander goto exit; 4333d3b0591SJens Wiklander 4343d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 ) 4353d3b0591SJens Wiklander goto exit; 4363d3b0591SJens Wiklander 4373d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 ) 4383d3b0591SJens Wiklander goto exit; 4393d3b0591SJens Wiklander 4403d3b0591SJens Wiklander exit: 441817466cbSJens Wiklander mbedtls_sha1_free( &ctx ); 4423d3b0591SJens Wiklander 4433d3b0591SJens Wiklander return( ret ); 444817466cbSJens Wiklander } 445817466cbSJens Wiklander 4463d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 4473d3b0591SJens Wiklander void mbedtls_sha1( const unsigned char *input, 4483d3b0591SJens Wiklander size_t ilen, 4493d3b0591SJens Wiklander unsigned char output[20] ) 4503d3b0591SJens Wiklander { 4513d3b0591SJens Wiklander mbedtls_sha1_ret( input, ilen, output ); 4523d3b0591SJens Wiklander } 4533d3b0591SJens Wiklander #endif 4543d3b0591SJens Wiklander 455817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 456817466cbSJens Wiklander /* 457817466cbSJens Wiklander * FIPS-180-1 test vectors 458817466cbSJens Wiklander */ 459817466cbSJens Wiklander static const unsigned char sha1_test_buf[3][57] = 460817466cbSJens Wiklander { 461817466cbSJens Wiklander { "abc" }, 462817466cbSJens Wiklander { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 463817466cbSJens Wiklander { "" } 464817466cbSJens Wiklander }; 465817466cbSJens Wiklander 4663d3b0591SJens Wiklander static const size_t sha1_test_buflen[3] = 467817466cbSJens Wiklander { 468817466cbSJens Wiklander 3, 56, 1000 469817466cbSJens Wiklander }; 470817466cbSJens Wiklander 471817466cbSJens Wiklander static const unsigned char sha1_test_sum[3][20] = 472817466cbSJens Wiklander { 473817466cbSJens Wiklander { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 474817466cbSJens Wiklander 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, 475817466cbSJens Wiklander { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 476817466cbSJens Wiklander 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, 477817466cbSJens Wiklander { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, 478817466cbSJens Wiklander 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } 479817466cbSJens Wiklander }; 480817466cbSJens Wiklander 481817466cbSJens Wiklander /* 482817466cbSJens Wiklander * Checkup routine 483817466cbSJens Wiklander */ 484817466cbSJens Wiklander int mbedtls_sha1_self_test( int verbose ) 485817466cbSJens Wiklander { 486817466cbSJens Wiklander int i, j, buflen, ret = 0; 487817466cbSJens Wiklander unsigned char buf[1024]; 488817466cbSJens Wiklander unsigned char sha1sum[20]; 489817466cbSJens Wiklander mbedtls_sha1_context ctx; 490817466cbSJens Wiklander 491817466cbSJens Wiklander mbedtls_sha1_init( &ctx ); 492817466cbSJens Wiklander 493817466cbSJens Wiklander /* 494817466cbSJens Wiklander * SHA-1 495817466cbSJens Wiklander */ 496817466cbSJens Wiklander for( i = 0; i < 3; i++ ) 497817466cbSJens Wiklander { 498817466cbSJens Wiklander if( verbose != 0 ) 499817466cbSJens Wiklander mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); 500817466cbSJens Wiklander 5013d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) 5023d3b0591SJens Wiklander goto fail; 503817466cbSJens Wiklander 504817466cbSJens Wiklander if( i == 2 ) 505817466cbSJens Wiklander { 506817466cbSJens Wiklander memset( buf, 'a', buflen = 1000 ); 507817466cbSJens Wiklander 508817466cbSJens Wiklander for( j = 0; j < 1000; j++ ) 5093d3b0591SJens Wiklander { 5103d3b0591SJens Wiklander ret = mbedtls_sha1_update_ret( &ctx, buf, buflen ); 5113d3b0591SJens Wiklander if( ret != 0 ) 5123d3b0591SJens Wiklander goto fail; 5133d3b0591SJens Wiklander } 514817466cbSJens Wiklander } 515817466cbSJens Wiklander else 5163d3b0591SJens Wiklander { 5173d3b0591SJens Wiklander ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i], 518817466cbSJens Wiklander sha1_test_buflen[i] ); 5193d3b0591SJens Wiklander if( ret != 0 ) 5203d3b0591SJens Wiklander goto fail; 5213d3b0591SJens Wiklander } 522817466cbSJens Wiklander 5233d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 ) 5243d3b0591SJens Wiklander goto fail; 525817466cbSJens Wiklander 526817466cbSJens Wiklander if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) 527817466cbSJens Wiklander { 528817466cbSJens Wiklander ret = 1; 5293d3b0591SJens Wiklander goto fail; 530817466cbSJens Wiklander } 531817466cbSJens Wiklander 532817466cbSJens Wiklander if( verbose != 0 ) 533817466cbSJens Wiklander mbedtls_printf( "passed\n" ); 534817466cbSJens Wiklander } 535817466cbSJens Wiklander 536817466cbSJens Wiklander if( verbose != 0 ) 537817466cbSJens Wiklander mbedtls_printf( "\n" ); 538817466cbSJens Wiklander 5393d3b0591SJens Wiklander goto exit; 5403d3b0591SJens Wiklander 5413d3b0591SJens Wiklander fail: 5423d3b0591SJens Wiklander if( verbose != 0 ) 5433d3b0591SJens Wiklander mbedtls_printf( "failed\n" ); 5443d3b0591SJens Wiklander 545817466cbSJens Wiklander exit: 546817466cbSJens Wiklander mbedtls_sha1_free( &ctx ); 547817466cbSJens Wiklander 548817466cbSJens Wiklander return( ret ); 549817466cbSJens Wiklander } 550817466cbSJens Wiklander 551817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 552817466cbSJens Wiklander 553817466cbSJens Wiklander #endif /* MBEDTLS_SHA1_C */ 554