1c6672fdcSEdison Ai // SPDX-License-Identifier: Apache-2.0 2817466cbSJens Wiklander /* 3817466cbSJens Wiklander * FIPS-180-1 compliant SHA-1 implementation 4817466cbSJens Wiklander * 5817466cbSJens Wiklander * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 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 * This file is part of mbed TLS (https://tls.mbed.org) 20817466cbSJens Wiklander */ 21817466cbSJens Wiklander /* 22817466cbSJens Wiklander * The SHA-1 standard was published by NIST in 1993. 23817466cbSJens Wiklander * 24817466cbSJens Wiklander * http://www.itl.nist.gov/fipspubs/fip180-1.htm 25817466cbSJens Wiklander */ 26817466cbSJens Wiklander 27817466cbSJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE) 28817466cbSJens Wiklander #include "mbedtls/config.h" 29817466cbSJens Wiklander #else 30817466cbSJens Wiklander #include MBEDTLS_CONFIG_FILE 31817466cbSJens Wiklander #endif 32817466cbSJens Wiklander 33817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 34817466cbSJens Wiklander 35817466cbSJens Wiklander #include "mbedtls/sha1.h" 36*3d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 37817466cbSJens Wiklander 38817466cbSJens Wiklander #include <string.h> 39817466cbSJens Wiklander 40817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 41817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 42817466cbSJens Wiklander #include "mbedtls/platform.h" 43817466cbSJens Wiklander #else 44817466cbSJens Wiklander #include <stdio.h> 45817466cbSJens Wiklander #define mbedtls_printf printf 46817466cbSJens Wiklander #endif /* MBEDTLS_PLATFORM_C */ 47817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 48817466cbSJens Wiklander 49*3d3b0591SJens Wiklander #define SHA1_VALIDATE_RET(cond) \ 50*3d3b0591SJens Wiklander MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA ) 51817466cbSJens Wiklander 52*3d3b0591SJens Wiklander #define SHA1_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE( cond ) 53*3d3b0591SJens Wiklander 54*3d3b0591SJens Wiklander #if !defined(MBEDTLS_SHA1_ALT) 55817466cbSJens Wiklander 56817466cbSJens Wiklander /* 57817466cbSJens Wiklander * 32-bit integer manipulation macros (big endian) 58817466cbSJens Wiklander */ 59817466cbSJens Wiklander #ifndef GET_UINT32_BE 60817466cbSJens Wiklander #define GET_UINT32_BE(n,b,i) \ 61817466cbSJens Wiklander { \ 62817466cbSJens Wiklander (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 63817466cbSJens Wiklander | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 64817466cbSJens Wiklander | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 65817466cbSJens Wiklander | ( (uint32_t) (b)[(i) + 3] ); \ 66817466cbSJens Wiklander } 67817466cbSJens Wiklander #endif 68817466cbSJens Wiklander 69817466cbSJens Wiklander #ifndef PUT_UINT32_BE 70817466cbSJens Wiklander #define PUT_UINT32_BE(n,b,i) \ 71817466cbSJens Wiklander { \ 72817466cbSJens Wiklander (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 73817466cbSJens Wiklander (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 74817466cbSJens Wiklander (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 75817466cbSJens Wiklander (b)[(i) + 3] = (unsigned char) ( (n) ); \ 76817466cbSJens Wiklander } 77817466cbSJens Wiklander #endif 78817466cbSJens Wiklander 79817466cbSJens Wiklander void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) 80817466cbSJens Wiklander { 81*3d3b0591SJens Wiklander SHA1_VALIDATE( ctx != NULL ); 82*3d3b0591SJens Wiklander 83817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); 84817466cbSJens Wiklander } 85817466cbSJens Wiklander 86817466cbSJens Wiklander void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) 87817466cbSJens Wiklander { 88817466cbSJens Wiklander if( ctx == NULL ) 89817466cbSJens Wiklander return; 90817466cbSJens Wiklander 91*3d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); 92817466cbSJens Wiklander } 93817466cbSJens Wiklander 94817466cbSJens Wiklander void mbedtls_sha1_clone( mbedtls_sha1_context *dst, 95817466cbSJens Wiklander const mbedtls_sha1_context *src ) 96817466cbSJens Wiklander { 97*3d3b0591SJens Wiklander SHA1_VALIDATE( dst != NULL ); 98*3d3b0591SJens Wiklander SHA1_VALIDATE( src != NULL ); 99*3d3b0591SJens Wiklander 100817466cbSJens Wiklander *dst = *src; 101817466cbSJens Wiklander } 102817466cbSJens Wiklander 103817466cbSJens Wiklander /* 104817466cbSJens Wiklander * SHA-1 context setup 105817466cbSJens Wiklander */ 106*3d3b0591SJens Wiklander int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) 107817466cbSJens Wiklander { 108*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 109*3d3b0591SJens Wiklander 110817466cbSJens Wiklander ctx->total[0] = 0; 111817466cbSJens Wiklander ctx->total[1] = 0; 112817466cbSJens Wiklander 113817466cbSJens Wiklander ctx->state[0] = 0x67452301; 114817466cbSJens Wiklander ctx->state[1] = 0xEFCDAB89; 115817466cbSJens Wiklander ctx->state[2] = 0x98BADCFE; 116817466cbSJens Wiklander ctx->state[3] = 0x10325476; 117817466cbSJens Wiklander ctx->state[4] = 0xC3D2E1F0; 118*3d3b0591SJens Wiklander 119*3d3b0591SJens Wiklander return( 0 ); 120817466cbSJens Wiklander } 121817466cbSJens Wiklander 122*3d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 123*3d3b0591SJens Wiklander void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) 124*3d3b0591SJens Wiklander { 125*3d3b0591SJens Wiklander mbedtls_sha1_starts_ret( ctx ); 126*3d3b0591SJens Wiklander } 127*3d3b0591SJens Wiklander #endif 128*3d3b0591SJens Wiklander 129817466cbSJens Wiklander #if !defined(MBEDTLS_SHA1_PROCESS_ALT) 130*3d3b0591SJens Wiklander int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, 131*3d3b0591SJens Wiklander const unsigned char data[64] ) 132817466cbSJens Wiklander { 133817466cbSJens Wiklander uint32_t temp, W[16], A, B, C, D, E; 134817466cbSJens Wiklander 135*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 136*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( (const unsigned char *)data != NULL ); 137*3d3b0591SJens Wiklander 138817466cbSJens Wiklander GET_UINT32_BE( W[ 0], data, 0 ); 139817466cbSJens Wiklander GET_UINT32_BE( W[ 1], data, 4 ); 140817466cbSJens Wiklander GET_UINT32_BE( W[ 2], data, 8 ); 141817466cbSJens Wiklander GET_UINT32_BE( W[ 3], data, 12 ); 142817466cbSJens Wiklander GET_UINT32_BE( W[ 4], data, 16 ); 143817466cbSJens Wiklander GET_UINT32_BE( W[ 5], data, 20 ); 144817466cbSJens Wiklander GET_UINT32_BE( W[ 6], data, 24 ); 145817466cbSJens Wiklander GET_UINT32_BE( W[ 7], data, 28 ); 146817466cbSJens Wiklander GET_UINT32_BE( W[ 8], data, 32 ); 147817466cbSJens Wiklander GET_UINT32_BE( W[ 9], data, 36 ); 148817466cbSJens Wiklander GET_UINT32_BE( W[10], data, 40 ); 149817466cbSJens Wiklander GET_UINT32_BE( W[11], data, 44 ); 150817466cbSJens Wiklander GET_UINT32_BE( W[12], data, 48 ); 151817466cbSJens Wiklander GET_UINT32_BE( W[13], data, 52 ); 152817466cbSJens Wiklander GET_UINT32_BE( W[14], data, 56 ); 153817466cbSJens Wiklander GET_UINT32_BE( W[15], data, 60 ); 154817466cbSJens Wiklander 155817466cbSJens Wiklander #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 156817466cbSJens Wiklander 157817466cbSJens Wiklander #define R(t) \ 158817466cbSJens Wiklander ( \ 159817466cbSJens Wiklander temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ 160817466cbSJens Wiklander W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ 161817466cbSJens Wiklander ( W[t & 0x0F] = S(temp,1) ) \ 162817466cbSJens Wiklander ) 163817466cbSJens Wiklander 164817466cbSJens Wiklander #define P(a,b,c,d,e,x) \ 165817466cbSJens Wiklander { \ 166817466cbSJens Wiklander e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 167817466cbSJens Wiklander } 168817466cbSJens Wiklander 169817466cbSJens Wiklander A = ctx->state[0]; 170817466cbSJens Wiklander B = ctx->state[1]; 171817466cbSJens Wiklander C = ctx->state[2]; 172817466cbSJens Wiklander D = ctx->state[3]; 173817466cbSJens Wiklander E = ctx->state[4]; 174817466cbSJens Wiklander 175817466cbSJens Wiklander #define F(x,y,z) (z ^ (x & (y ^ z))) 176817466cbSJens Wiklander #define K 0x5A827999 177817466cbSJens Wiklander 178817466cbSJens Wiklander P( A, B, C, D, E, W[0] ); 179817466cbSJens Wiklander P( E, A, B, C, D, W[1] ); 180817466cbSJens Wiklander P( D, E, A, B, C, W[2] ); 181817466cbSJens Wiklander P( C, D, E, A, B, W[3] ); 182817466cbSJens Wiklander P( B, C, D, E, A, W[4] ); 183817466cbSJens Wiklander P( A, B, C, D, E, W[5] ); 184817466cbSJens Wiklander P( E, A, B, C, D, W[6] ); 185817466cbSJens Wiklander P( D, E, A, B, C, W[7] ); 186817466cbSJens Wiklander P( C, D, E, A, B, W[8] ); 187817466cbSJens Wiklander P( B, C, D, E, A, W[9] ); 188817466cbSJens Wiklander P( A, B, C, D, E, W[10] ); 189817466cbSJens Wiklander P( E, A, B, C, D, W[11] ); 190817466cbSJens Wiklander P( D, E, A, B, C, W[12] ); 191817466cbSJens Wiklander P( C, D, E, A, B, W[13] ); 192817466cbSJens Wiklander P( B, C, D, E, A, W[14] ); 193817466cbSJens Wiklander P( A, B, C, D, E, W[15] ); 194817466cbSJens Wiklander P( E, A, B, C, D, R(16) ); 195817466cbSJens Wiklander P( D, E, A, B, C, R(17) ); 196817466cbSJens Wiklander P( C, D, E, A, B, R(18) ); 197817466cbSJens Wiklander P( B, C, D, E, A, R(19) ); 198817466cbSJens Wiklander 199817466cbSJens Wiklander #undef K 200817466cbSJens Wiklander #undef F 201817466cbSJens Wiklander 202817466cbSJens Wiklander #define F(x,y,z) (x ^ y ^ z) 203817466cbSJens Wiklander #define K 0x6ED9EBA1 204817466cbSJens Wiklander 205817466cbSJens Wiklander P( A, B, C, D, E, R(20) ); 206817466cbSJens Wiklander P( E, A, B, C, D, R(21) ); 207817466cbSJens Wiklander P( D, E, A, B, C, R(22) ); 208817466cbSJens Wiklander P( C, D, E, A, B, R(23) ); 209817466cbSJens Wiklander P( B, C, D, E, A, R(24) ); 210817466cbSJens Wiklander P( A, B, C, D, E, R(25) ); 211817466cbSJens Wiklander P( E, A, B, C, D, R(26) ); 212817466cbSJens Wiklander P( D, E, A, B, C, R(27) ); 213817466cbSJens Wiklander P( C, D, E, A, B, R(28) ); 214817466cbSJens Wiklander P( B, C, D, E, A, R(29) ); 215817466cbSJens Wiklander P( A, B, C, D, E, R(30) ); 216817466cbSJens Wiklander P( E, A, B, C, D, R(31) ); 217817466cbSJens Wiklander P( D, E, A, B, C, R(32) ); 218817466cbSJens Wiklander P( C, D, E, A, B, R(33) ); 219817466cbSJens Wiklander P( B, C, D, E, A, R(34) ); 220817466cbSJens Wiklander P( A, B, C, D, E, R(35) ); 221817466cbSJens Wiklander P( E, A, B, C, D, R(36) ); 222817466cbSJens Wiklander P( D, E, A, B, C, R(37) ); 223817466cbSJens Wiklander P( C, D, E, A, B, R(38) ); 224817466cbSJens Wiklander P( B, C, D, E, A, R(39) ); 225817466cbSJens Wiklander 226817466cbSJens Wiklander #undef K 227817466cbSJens Wiklander #undef F 228817466cbSJens Wiklander 229817466cbSJens Wiklander #define F(x,y,z) ((x & y) | (z & (x | y))) 230817466cbSJens Wiklander #define K 0x8F1BBCDC 231817466cbSJens Wiklander 232817466cbSJens Wiklander P( A, B, C, D, E, R(40) ); 233817466cbSJens Wiklander P( E, A, B, C, D, R(41) ); 234817466cbSJens Wiklander P( D, E, A, B, C, R(42) ); 235817466cbSJens Wiklander P( C, D, E, A, B, R(43) ); 236817466cbSJens Wiklander P( B, C, D, E, A, R(44) ); 237817466cbSJens Wiklander P( A, B, C, D, E, R(45) ); 238817466cbSJens Wiklander P( E, A, B, C, D, R(46) ); 239817466cbSJens Wiklander P( D, E, A, B, C, R(47) ); 240817466cbSJens Wiklander P( C, D, E, A, B, R(48) ); 241817466cbSJens Wiklander P( B, C, D, E, A, R(49) ); 242817466cbSJens Wiklander P( A, B, C, D, E, R(50) ); 243817466cbSJens Wiklander P( E, A, B, C, D, R(51) ); 244817466cbSJens Wiklander P( D, E, A, B, C, R(52) ); 245817466cbSJens Wiklander P( C, D, E, A, B, R(53) ); 246817466cbSJens Wiklander P( B, C, D, E, A, R(54) ); 247817466cbSJens Wiklander P( A, B, C, D, E, R(55) ); 248817466cbSJens Wiklander P( E, A, B, C, D, R(56) ); 249817466cbSJens Wiklander P( D, E, A, B, C, R(57) ); 250817466cbSJens Wiklander P( C, D, E, A, B, R(58) ); 251817466cbSJens Wiklander P( B, C, D, E, A, R(59) ); 252817466cbSJens Wiklander 253817466cbSJens Wiklander #undef K 254817466cbSJens Wiklander #undef F 255817466cbSJens Wiklander 256817466cbSJens Wiklander #define F(x,y,z) (x ^ y ^ z) 257817466cbSJens Wiklander #define K 0xCA62C1D6 258817466cbSJens Wiklander 259817466cbSJens Wiklander P( A, B, C, D, E, R(60) ); 260817466cbSJens Wiklander P( E, A, B, C, D, R(61) ); 261817466cbSJens Wiklander P( D, E, A, B, C, R(62) ); 262817466cbSJens Wiklander P( C, D, E, A, B, R(63) ); 263817466cbSJens Wiklander P( B, C, D, E, A, R(64) ); 264817466cbSJens Wiklander P( A, B, C, D, E, R(65) ); 265817466cbSJens Wiklander P( E, A, B, C, D, R(66) ); 266817466cbSJens Wiklander P( D, E, A, B, C, R(67) ); 267817466cbSJens Wiklander P( C, D, E, A, B, R(68) ); 268817466cbSJens Wiklander P( B, C, D, E, A, R(69) ); 269817466cbSJens Wiklander P( A, B, C, D, E, R(70) ); 270817466cbSJens Wiklander P( E, A, B, C, D, R(71) ); 271817466cbSJens Wiklander P( D, E, A, B, C, R(72) ); 272817466cbSJens Wiklander P( C, D, E, A, B, R(73) ); 273817466cbSJens Wiklander P( B, C, D, E, A, R(74) ); 274817466cbSJens Wiklander P( A, B, C, D, E, R(75) ); 275817466cbSJens Wiklander P( E, A, B, C, D, R(76) ); 276817466cbSJens Wiklander P( D, E, A, B, C, R(77) ); 277817466cbSJens Wiklander P( C, D, E, A, B, R(78) ); 278817466cbSJens Wiklander P( B, C, D, E, A, R(79) ); 279817466cbSJens Wiklander 280817466cbSJens Wiklander #undef K 281817466cbSJens Wiklander #undef F 282817466cbSJens Wiklander 283817466cbSJens Wiklander ctx->state[0] += A; 284817466cbSJens Wiklander ctx->state[1] += B; 285817466cbSJens Wiklander ctx->state[2] += C; 286817466cbSJens Wiklander ctx->state[3] += D; 287817466cbSJens Wiklander ctx->state[4] += E; 288*3d3b0591SJens Wiklander 289*3d3b0591SJens Wiklander return( 0 ); 290817466cbSJens Wiklander } 291*3d3b0591SJens Wiklander 292*3d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 293*3d3b0591SJens Wiklander void mbedtls_sha1_process( mbedtls_sha1_context *ctx, 294*3d3b0591SJens Wiklander const unsigned char data[64] ) 295*3d3b0591SJens Wiklander { 296*3d3b0591SJens Wiklander mbedtls_internal_sha1_process( ctx, data ); 297*3d3b0591SJens Wiklander } 298*3d3b0591SJens Wiklander #endif 299817466cbSJens Wiklander #endif /* !MBEDTLS_SHA1_PROCESS_ALT */ 300817466cbSJens Wiklander 301817466cbSJens Wiklander /* 302817466cbSJens Wiklander * SHA-1 process buffer 303817466cbSJens Wiklander */ 304*3d3b0591SJens Wiklander int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, 305*3d3b0591SJens Wiklander const unsigned char *input, 306*3d3b0591SJens Wiklander size_t ilen ) 307817466cbSJens Wiklander { 308*3d3b0591SJens Wiklander int ret; 309817466cbSJens Wiklander size_t fill; 310817466cbSJens Wiklander uint32_t left; 311817466cbSJens Wiklander 312*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 313*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); 314*3d3b0591SJens Wiklander 315817466cbSJens Wiklander if( ilen == 0 ) 316*3d3b0591SJens Wiklander return( 0 ); 317817466cbSJens Wiklander 318817466cbSJens Wiklander left = ctx->total[0] & 0x3F; 319817466cbSJens Wiklander fill = 64 - left; 320817466cbSJens Wiklander 321817466cbSJens Wiklander ctx->total[0] += (uint32_t) ilen; 322817466cbSJens Wiklander ctx->total[0] &= 0xFFFFFFFF; 323817466cbSJens Wiklander 324817466cbSJens Wiklander if( ctx->total[0] < (uint32_t) ilen ) 325817466cbSJens Wiklander ctx->total[1]++; 326817466cbSJens Wiklander 327817466cbSJens Wiklander if( left && ilen >= fill ) 328817466cbSJens Wiklander { 329817466cbSJens Wiklander memcpy( (void *) (ctx->buffer + left), input, fill ); 330*3d3b0591SJens Wiklander 331*3d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 332*3d3b0591SJens Wiklander return( ret ); 333*3d3b0591SJens Wiklander 334817466cbSJens Wiklander input += fill; 335817466cbSJens Wiklander ilen -= fill; 336817466cbSJens Wiklander left = 0; 337817466cbSJens Wiklander } 338817466cbSJens Wiklander 339817466cbSJens Wiklander while( ilen >= 64 ) 340817466cbSJens Wiklander { 341*3d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) 342*3d3b0591SJens Wiklander return( ret ); 343*3d3b0591SJens Wiklander 344817466cbSJens Wiklander input += 64; 345817466cbSJens Wiklander ilen -= 64; 346817466cbSJens Wiklander } 347817466cbSJens Wiklander 348817466cbSJens Wiklander if( ilen > 0 ) 349817466cbSJens Wiklander memcpy( (void *) (ctx->buffer + left), input, ilen ); 350*3d3b0591SJens Wiklander 351*3d3b0591SJens Wiklander return( 0 ); 352817466cbSJens Wiklander } 353817466cbSJens Wiklander 354*3d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 355*3d3b0591SJens Wiklander void mbedtls_sha1_update( mbedtls_sha1_context *ctx, 356*3d3b0591SJens Wiklander const unsigned char *input, 357*3d3b0591SJens Wiklander size_t ilen ) 358817466cbSJens Wiklander { 359*3d3b0591SJens Wiklander mbedtls_sha1_update_ret( ctx, input, ilen ); 360*3d3b0591SJens Wiklander } 361*3d3b0591SJens Wiklander #endif 362817466cbSJens Wiklander 363817466cbSJens Wiklander /* 364817466cbSJens Wiklander * SHA-1 final digest 365817466cbSJens Wiklander */ 366*3d3b0591SJens Wiklander int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, 367*3d3b0591SJens Wiklander unsigned char output[20] ) 368817466cbSJens Wiklander { 369*3d3b0591SJens Wiklander int ret; 370*3d3b0591SJens Wiklander uint32_t used; 371817466cbSJens Wiklander uint32_t high, low; 372817466cbSJens Wiklander 373*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( ctx != NULL ); 374*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); 375*3d3b0591SJens Wiklander 376*3d3b0591SJens Wiklander /* 377*3d3b0591SJens Wiklander * Add padding: 0x80 then 0x00 until 8 bytes remain for the length 378*3d3b0591SJens Wiklander */ 379*3d3b0591SJens Wiklander used = ctx->total[0] & 0x3F; 380*3d3b0591SJens Wiklander 381*3d3b0591SJens Wiklander ctx->buffer[used++] = 0x80; 382*3d3b0591SJens Wiklander 383*3d3b0591SJens Wiklander if( used <= 56 ) 384*3d3b0591SJens Wiklander { 385*3d3b0591SJens Wiklander /* Enough room for padding + length in current block */ 386*3d3b0591SJens Wiklander memset( ctx->buffer + used, 0, 56 - used ); 387*3d3b0591SJens Wiklander } 388*3d3b0591SJens Wiklander else 389*3d3b0591SJens Wiklander { 390*3d3b0591SJens Wiklander /* We'll need an extra block */ 391*3d3b0591SJens Wiklander memset( ctx->buffer + used, 0, 64 - used ); 392*3d3b0591SJens Wiklander 393*3d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 394*3d3b0591SJens Wiklander return( ret ); 395*3d3b0591SJens Wiklander 396*3d3b0591SJens Wiklander memset( ctx->buffer, 0, 56 ); 397*3d3b0591SJens Wiklander } 398*3d3b0591SJens Wiklander 399*3d3b0591SJens Wiklander /* 400*3d3b0591SJens Wiklander * Add message length 401*3d3b0591SJens Wiklander */ 402817466cbSJens Wiklander high = ( ctx->total[0] >> 29 ) 403817466cbSJens Wiklander | ( ctx->total[1] << 3 ); 404817466cbSJens Wiklander low = ( ctx->total[0] << 3 ); 405817466cbSJens Wiklander 406*3d3b0591SJens Wiklander PUT_UINT32_BE( high, ctx->buffer, 56 ); 407*3d3b0591SJens Wiklander PUT_UINT32_BE( low, ctx->buffer, 60 ); 408817466cbSJens Wiklander 409*3d3b0591SJens Wiklander if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 410*3d3b0591SJens Wiklander return( ret ); 411817466cbSJens Wiklander 412*3d3b0591SJens Wiklander /* 413*3d3b0591SJens Wiklander * Output final state 414*3d3b0591SJens Wiklander */ 415817466cbSJens Wiklander PUT_UINT32_BE( ctx->state[0], output, 0 ); 416817466cbSJens Wiklander PUT_UINT32_BE( ctx->state[1], output, 4 ); 417817466cbSJens Wiklander PUT_UINT32_BE( ctx->state[2], output, 8 ); 418817466cbSJens Wiklander PUT_UINT32_BE( ctx->state[3], output, 12 ); 419817466cbSJens Wiklander PUT_UINT32_BE( ctx->state[4], output, 16 ); 420*3d3b0591SJens Wiklander 421*3d3b0591SJens Wiklander return( 0 ); 422817466cbSJens Wiklander } 423817466cbSJens Wiklander 424*3d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 425*3d3b0591SJens Wiklander void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, 426*3d3b0591SJens Wiklander unsigned char output[20] ) 427*3d3b0591SJens Wiklander { 428*3d3b0591SJens Wiklander mbedtls_sha1_finish_ret( ctx, output ); 429*3d3b0591SJens Wiklander } 430*3d3b0591SJens Wiklander #endif 431*3d3b0591SJens Wiklander 432817466cbSJens Wiklander #endif /* !MBEDTLS_SHA1_ALT */ 433817466cbSJens Wiklander 434817466cbSJens Wiklander /* 435817466cbSJens Wiklander * output = SHA-1( input buffer ) 436817466cbSJens Wiklander */ 437*3d3b0591SJens Wiklander int mbedtls_sha1_ret( const unsigned char *input, 438*3d3b0591SJens Wiklander size_t ilen, 439*3d3b0591SJens Wiklander unsigned char output[20] ) 440817466cbSJens Wiklander { 441*3d3b0591SJens Wiklander int ret; 442817466cbSJens Wiklander mbedtls_sha1_context ctx; 443817466cbSJens Wiklander 444*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( ilen == 0 || input != NULL ); 445*3d3b0591SJens Wiklander SHA1_VALIDATE_RET( (unsigned char *)output != NULL ); 446*3d3b0591SJens Wiklander 447817466cbSJens Wiklander mbedtls_sha1_init( &ctx ); 448*3d3b0591SJens Wiklander 449*3d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) 450*3d3b0591SJens Wiklander goto exit; 451*3d3b0591SJens Wiklander 452*3d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 ) 453*3d3b0591SJens Wiklander goto exit; 454*3d3b0591SJens Wiklander 455*3d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 ) 456*3d3b0591SJens Wiklander goto exit; 457*3d3b0591SJens Wiklander 458*3d3b0591SJens Wiklander exit: 459817466cbSJens Wiklander mbedtls_sha1_free( &ctx ); 460*3d3b0591SJens Wiklander 461*3d3b0591SJens Wiklander return( ret ); 462817466cbSJens Wiklander } 463817466cbSJens Wiklander 464*3d3b0591SJens Wiklander #if !defined(MBEDTLS_DEPRECATED_REMOVED) 465*3d3b0591SJens Wiklander void mbedtls_sha1( const unsigned char *input, 466*3d3b0591SJens Wiklander size_t ilen, 467*3d3b0591SJens Wiklander unsigned char output[20] ) 468*3d3b0591SJens Wiklander { 469*3d3b0591SJens Wiklander mbedtls_sha1_ret( input, ilen, output ); 470*3d3b0591SJens Wiklander } 471*3d3b0591SJens Wiklander #endif 472*3d3b0591SJens Wiklander 473817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST) 474817466cbSJens Wiklander /* 475817466cbSJens Wiklander * FIPS-180-1 test vectors 476817466cbSJens Wiklander */ 477817466cbSJens Wiklander static const unsigned char sha1_test_buf[3][57] = 478817466cbSJens Wiklander { 479817466cbSJens Wiklander { "abc" }, 480817466cbSJens Wiklander { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 481817466cbSJens Wiklander { "" } 482817466cbSJens Wiklander }; 483817466cbSJens Wiklander 484*3d3b0591SJens Wiklander static const size_t sha1_test_buflen[3] = 485817466cbSJens Wiklander { 486817466cbSJens Wiklander 3, 56, 1000 487817466cbSJens Wiklander }; 488817466cbSJens Wiklander 489817466cbSJens Wiklander static const unsigned char sha1_test_sum[3][20] = 490817466cbSJens Wiklander { 491817466cbSJens Wiklander { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 492817466cbSJens Wiklander 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, 493817466cbSJens Wiklander { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 494817466cbSJens Wiklander 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, 495817466cbSJens Wiklander { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, 496817466cbSJens Wiklander 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } 497817466cbSJens Wiklander }; 498817466cbSJens Wiklander 499817466cbSJens Wiklander /* 500817466cbSJens Wiklander * Checkup routine 501817466cbSJens Wiklander */ 502817466cbSJens Wiklander int mbedtls_sha1_self_test( int verbose ) 503817466cbSJens Wiklander { 504817466cbSJens Wiklander int i, j, buflen, ret = 0; 505817466cbSJens Wiklander unsigned char buf[1024]; 506817466cbSJens Wiklander unsigned char sha1sum[20]; 507817466cbSJens Wiklander mbedtls_sha1_context ctx; 508817466cbSJens Wiklander 509817466cbSJens Wiklander mbedtls_sha1_init( &ctx ); 510817466cbSJens Wiklander 511817466cbSJens Wiklander /* 512817466cbSJens Wiklander * SHA-1 513817466cbSJens Wiklander */ 514817466cbSJens Wiklander for( i = 0; i < 3; i++ ) 515817466cbSJens Wiklander { 516817466cbSJens Wiklander if( verbose != 0 ) 517817466cbSJens Wiklander mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); 518817466cbSJens Wiklander 519*3d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) 520*3d3b0591SJens Wiklander goto fail; 521817466cbSJens Wiklander 522817466cbSJens Wiklander if( i == 2 ) 523817466cbSJens Wiklander { 524817466cbSJens Wiklander memset( buf, 'a', buflen = 1000 ); 525817466cbSJens Wiklander 526817466cbSJens Wiklander for( j = 0; j < 1000; j++ ) 527*3d3b0591SJens Wiklander { 528*3d3b0591SJens Wiklander ret = mbedtls_sha1_update_ret( &ctx, buf, buflen ); 529*3d3b0591SJens Wiklander if( ret != 0 ) 530*3d3b0591SJens Wiklander goto fail; 531*3d3b0591SJens Wiklander } 532817466cbSJens Wiklander } 533817466cbSJens Wiklander else 534*3d3b0591SJens Wiklander { 535*3d3b0591SJens Wiklander ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i], 536817466cbSJens Wiklander sha1_test_buflen[i] ); 537*3d3b0591SJens Wiklander if( ret != 0 ) 538*3d3b0591SJens Wiklander goto fail; 539*3d3b0591SJens Wiklander } 540817466cbSJens Wiklander 541*3d3b0591SJens Wiklander if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 ) 542*3d3b0591SJens Wiklander goto fail; 543817466cbSJens Wiklander 544817466cbSJens Wiklander if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) 545817466cbSJens Wiklander { 546817466cbSJens Wiklander ret = 1; 547*3d3b0591SJens Wiklander goto fail; 548817466cbSJens Wiklander } 549817466cbSJens Wiklander 550817466cbSJens Wiklander if( verbose != 0 ) 551817466cbSJens Wiklander mbedtls_printf( "passed\n" ); 552817466cbSJens Wiklander } 553817466cbSJens Wiklander 554817466cbSJens Wiklander if( verbose != 0 ) 555817466cbSJens Wiklander mbedtls_printf( "\n" ); 556817466cbSJens Wiklander 557*3d3b0591SJens Wiklander goto exit; 558*3d3b0591SJens Wiklander 559*3d3b0591SJens Wiklander fail: 560*3d3b0591SJens Wiklander if( verbose != 0 ) 561*3d3b0591SJens Wiklander mbedtls_printf( "failed\n" ); 562*3d3b0591SJens Wiklander 563817466cbSJens Wiklander exit: 564817466cbSJens Wiklander mbedtls_sha1_free( &ctx ); 565817466cbSJens Wiklander 566817466cbSJens Wiklander return( ret ); 567817466cbSJens Wiklander } 568817466cbSJens Wiklander 569817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */ 570817466cbSJens Wiklander 571817466cbSJens Wiklander #endif /* MBEDTLS_SHA1_C */ 572