Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sha1.c
00001 /* 00002 * FIPS-180-1 compliant SHA-1 implementation 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The SHA-1 standard was published by NIST in 1993. 00023 * 00024 * http://www.itl.nist.gov/fipspubs/fip180-1.htm 00025 */ 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "mbedtls/config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #if defined(MBEDTLS_SHA1_C) 00034 00035 #include "mbedtls/sha1.h" 00036 #include "mbedtls/platform_util.h" 00037 00038 #include <string.h> 00039 00040 #if defined(MBEDTLS_SELF_TEST) 00041 #if defined(MBEDTLS_PLATFORM_C) 00042 #include "mbedtls/platform.h" 00043 #else 00044 #include <stdio.h> 00045 #define mbedtls_printf printf 00046 #endif /* MBEDTLS_PLATFORM_C */ 00047 #endif /* MBEDTLS_SELF_TEST */ 00048 00049 #if !defined(MBEDTLS_SHA1_ALT) 00050 00051 /* 00052 * 32-bit integer manipulation macros (big endian) 00053 */ 00054 #ifndef GET_UINT32_BE 00055 #define GET_UINT32_BE(n,b,i) \ 00056 { \ 00057 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00058 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00059 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00060 | ( (uint32_t) (b)[(i) + 3] ); \ 00061 } 00062 #endif 00063 00064 #ifndef PUT_UINT32_BE 00065 #define PUT_UINT32_BE(n,b,i) \ 00066 { \ 00067 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00068 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00069 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00070 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00071 } 00072 #endif 00073 00074 void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) 00075 { 00076 memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); 00077 } 00078 00079 void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) 00080 { 00081 if( ctx == NULL ) 00082 return; 00083 00084 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); 00085 } 00086 00087 void mbedtls_sha1_clone( mbedtls_sha1_context *dst, 00088 const mbedtls_sha1_context *src ) 00089 { 00090 *dst = *src; 00091 } 00092 00093 /* 00094 * SHA-1 context setup 00095 */ 00096 int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx ) 00097 { 00098 ctx->total [0] = 0; 00099 ctx->total [1] = 0; 00100 00101 ctx->state [0] = 0x67452301; 00102 ctx->state [1] = 0xEFCDAB89; 00103 ctx->state [2] = 0x98BADCFE; 00104 ctx->state [3] = 0x10325476; 00105 ctx->state [4] = 0xC3D2E1F0; 00106 00107 return( 0 ); 00108 } 00109 00110 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00111 void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) 00112 { 00113 mbedtls_sha1_starts_ret( ctx ); 00114 } 00115 #endif 00116 00117 #if !defined(MBEDTLS_SHA1_PROCESS_ALT) 00118 int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, 00119 const unsigned char data[64] ) 00120 { 00121 uint32_t temp, W[16], A, B, C, D, E; 00122 00123 GET_UINT32_BE( W[ 0], data, 0 ); 00124 GET_UINT32_BE( W[ 1], data, 4 ); 00125 GET_UINT32_BE( W[ 2], data, 8 ); 00126 GET_UINT32_BE( W[ 3], data, 12 ); 00127 GET_UINT32_BE( W[ 4], data, 16 ); 00128 GET_UINT32_BE( W[ 5], data, 20 ); 00129 GET_UINT32_BE( W[ 6], data, 24 ); 00130 GET_UINT32_BE( W[ 7], data, 28 ); 00131 GET_UINT32_BE( W[ 8], data, 32 ); 00132 GET_UINT32_BE( W[ 9], data, 36 ); 00133 GET_UINT32_BE( W[10], data, 40 ); 00134 GET_UINT32_BE( W[11], data, 44 ); 00135 GET_UINT32_BE( W[12], data, 48 ); 00136 GET_UINT32_BE( W[13], data, 52 ); 00137 GET_UINT32_BE( W[14], data, 56 ); 00138 GET_UINT32_BE( W[15], data, 60 ); 00139 00140 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 00141 00142 #define R(t) \ 00143 ( \ 00144 temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ 00145 W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ 00146 ( W[t & 0x0F] = S(temp,1) ) \ 00147 ) 00148 00149 #define P(a,b,c,d,e,x) \ 00150 { \ 00151 e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 00152 } 00153 00154 A = ctx->state [0]; 00155 B = ctx->state [1]; 00156 C = ctx->state [2]; 00157 D = ctx->state [3]; 00158 E = ctx->state [4]; 00159 00160 #define F(x,y,z) (z ^ (x & (y ^ z))) 00161 #define K 0x5A827999 00162 00163 P( A, B, C, D, E, W[0] ); 00164 P( E, A, B, C, D, W[1] ); 00165 P( D, E, A, B, C, W[2] ); 00166 P( C, D, E, A, B, W[3] ); 00167 P( B, C, D, E, A, W[4] ); 00168 P( A, B, C, D, E, W[5] ); 00169 P( E, A, B, C, D, W[6] ); 00170 P( D, E, A, B, C, W[7] ); 00171 P( C, D, E, A, B, W[8] ); 00172 P( B, C, D, E, A, W[9] ); 00173 P( A, B, C, D, E, W[10] ); 00174 P( E, A, B, C, D, W[11] ); 00175 P( D, E, A, B, C, W[12] ); 00176 P( C, D, E, A, B, W[13] ); 00177 P( B, C, D, E, A, W[14] ); 00178 P( A, B, C, D, E, W[15] ); 00179 P( E, A, B, C, D, R(16) ); 00180 P( D, E, A, B, C, R(17) ); 00181 P( C, D, E, A, B, R(18) ); 00182 P( B, C, D, E, A, R(19) ); 00183 00184 #undef K 00185 #undef F 00186 00187 #define F(x,y,z) (x ^ y ^ z) 00188 #define K 0x6ED9EBA1 00189 00190 P( A, B, C, D, E, R(20) ); 00191 P( E, A, B, C, D, R(21) ); 00192 P( D, E, A, B, C, R(22) ); 00193 P( C, D, E, A, B, R(23) ); 00194 P( B, C, D, E, A, R(24) ); 00195 P( A, B, C, D, E, R(25) ); 00196 P( E, A, B, C, D, R(26) ); 00197 P( D, E, A, B, C, R(27) ); 00198 P( C, D, E, A, B, R(28) ); 00199 P( B, C, D, E, A, R(29) ); 00200 P( A, B, C, D, E, R(30) ); 00201 P( E, A, B, C, D, R(31) ); 00202 P( D, E, A, B, C, R(32) ); 00203 P( C, D, E, A, B, R(33) ); 00204 P( B, C, D, E, A, R(34) ); 00205 P( A, B, C, D, E, R(35) ); 00206 P( E, A, B, C, D, R(36) ); 00207 P( D, E, A, B, C, R(37) ); 00208 P( C, D, E, A, B, R(38) ); 00209 P( B, C, D, E, A, R(39) ); 00210 00211 #undef K 00212 #undef F 00213 00214 #define F(x,y,z) ((x & y) | (z & (x | y))) 00215 #define K 0x8F1BBCDC 00216 00217 P( A, B, C, D, E, R(40) ); 00218 P( E, A, B, C, D, R(41) ); 00219 P( D, E, A, B, C, R(42) ); 00220 P( C, D, E, A, B, R(43) ); 00221 P( B, C, D, E, A, R(44) ); 00222 P( A, B, C, D, E, R(45) ); 00223 P( E, A, B, C, D, R(46) ); 00224 P( D, E, A, B, C, R(47) ); 00225 P( C, D, E, A, B, R(48) ); 00226 P( B, C, D, E, A, R(49) ); 00227 P( A, B, C, D, E, R(50) ); 00228 P( E, A, B, C, D, R(51) ); 00229 P( D, E, A, B, C, R(52) ); 00230 P( C, D, E, A, B, R(53) ); 00231 P( B, C, D, E, A, R(54) ); 00232 P( A, B, C, D, E, R(55) ); 00233 P( E, A, B, C, D, R(56) ); 00234 P( D, E, A, B, C, R(57) ); 00235 P( C, D, E, A, B, R(58) ); 00236 P( B, C, D, E, A, R(59) ); 00237 00238 #undef K 00239 #undef F 00240 00241 #define F(x,y,z) (x ^ y ^ z) 00242 #define K 0xCA62C1D6 00243 00244 P( A, B, C, D, E, R(60) ); 00245 P( E, A, B, C, D, R(61) ); 00246 P( D, E, A, B, C, R(62) ); 00247 P( C, D, E, A, B, R(63) ); 00248 P( B, C, D, E, A, R(64) ); 00249 P( A, B, C, D, E, R(65) ); 00250 P( E, A, B, C, D, R(66) ); 00251 P( D, E, A, B, C, R(67) ); 00252 P( C, D, E, A, B, R(68) ); 00253 P( B, C, D, E, A, R(69) ); 00254 P( A, B, C, D, E, R(70) ); 00255 P( E, A, B, C, D, R(71) ); 00256 P( D, E, A, B, C, R(72) ); 00257 P( C, D, E, A, B, R(73) ); 00258 P( B, C, D, E, A, R(74) ); 00259 P( A, B, C, D, E, R(75) ); 00260 P( E, A, B, C, D, R(76) ); 00261 P( D, E, A, B, C, R(77) ); 00262 P( C, D, E, A, B, R(78) ); 00263 P( B, C, D, E, A, R(79) ); 00264 00265 #undef K 00266 #undef F 00267 00268 ctx->state [0] += A; 00269 ctx->state [1] += B; 00270 ctx->state [2] += C; 00271 ctx->state [3] += D; 00272 ctx->state [4] += E; 00273 00274 return( 0 ); 00275 } 00276 00277 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00278 void mbedtls_sha1_process( mbedtls_sha1_context *ctx, 00279 const unsigned char data[64] ) 00280 { 00281 mbedtls_internal_sha1_process( ctx, data ); 00282 } 00283 #endif 00284 #endif /* !MBEDTLS_SHA1_PROCESS_ALT */ 00285 00286 /* 00287 * SHA-1 process buffer 00288 */ 00289 int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, 00290 const unsigned char *input, 00291 size_t ilen ) 00292 { 00293 int ret; 00294 size_t fill; 00295 uint32_t left; 00296 00297 if( ilen == 0 ) 00298 return( 0 ); 00299 00300 left = ctx->total [0] & 0x3F; 00301 fill = 64 - left; 00302 00303 ctx->total [0] += (uint32_t) ilen; 00304 ctx->total [0] &= 0xFFFFFFFF; 00305 00306 if( ctx->total [0] < (uint32_t) ilen ) 00307 ctx->total [1]++; 00308 00309 if( left && ilen >= fill ) 00310 { 00311 memcpy( (void *) (ctx->buffer + left), input, fill ); 00312 00313 if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 00314 return( ret ); 00315 00316 input += fill; 00317 ilen -= fill; 00318 left = 0; 00319 } 00320 00321 while( ilen >= 64 ) 00322 { 00323 if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 ) 00324 return( ret ); 00325 00326 input += 64; 00327 ilen -= 64; 00328 } 00329 00330 if( ilen > 0 ) 00331 memcpy( (void *) (ctx->buffer + left), input, ilen ); 00332 00333 return( 0 ); 00334 } 00335 00336 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00337 void mbedtls_sha1_update( mbedtls_sha1_context *ctx, 00338 const unsigned char *input, 00339 size_t ilen ) 00340 { 00341 mbedtls_sha1_update_ret( ctx, input, ilen ); 00342 } 00343 #endif 00344 00345 /* 00346 * SHA-1 final digest 00347 */ 00348 int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, 00349 unsigned char output[20] ) 00350 { 00351 int ret; 00352 uint32_t used; 00353 uint32_t high, low; 00354 00355 /* 00356 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length 00357 */ 00358 used = ctx->total [0] & 0x3F; 00359 00360 ctx->buffer [used++] = 0x80; 00361 00362 if( used <= 56 ) 00363 { 00364 /* Enough room for padding + length in current block */ 00365 memset( ctx->buffer + used, 0, 56 - used ); 00366 } 00367 else 00368 { 00369 /* We'll need an extra block */ 00370 memset( ctx->buffer + used, 0, 64 - used ); 00371 00372 if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 00373 return( ret ); 00374 00375 memset( ctx->buffer , 0, 56 ); 00376 } 00377 00378 /* 00379 * Add message length 00380 */ 00381 high = ( ctx->total [0] >> 29 ) 00382 | ( ctx->total [1] << 3 ); 00383 low = ( ctx->total [0] << 3 ); 00384 00385 PUT_UINT32_BE( high, ctx->buffer , 56 ); 00386 PUT_UINT32_BE( low, ctx->buffer , 60 ); 00387 00388 if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) 00389 return( ret ); 00390 00391 /* 00392 * Output final state 00393 */ 00394 PUT_UINT32_BE( ctx->state [0], output, 0 ); 00395 PUT_UINT32_BE( ctx->state [1], output, 4 ); 00396 PUT_UINT32_BE( ctx->state [2], output, 8 ); 00397 PUT_UINT32_BE( ctx->state [3], output, 12 ); 00398 PUT_UINT32_BE( ctx->state [4], output, 16 ); 00399 00400 return( 0 ); 00401 } 00402 00403 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00404 void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, 00405 unsigned char output[20] ) 00406 { 00407 mbedtls_sha1_finish_ret( ctx, output ); 00408 } 00409 #endif 00410 00411 #endif /* !MBEDTLS_SHA1_ALT */ 00412 00413 /* 00414 * output = SHA-1( input buffer ) 00415 */ 00416 int mbedtls_sha1_ret( const unsigned char *input, 00417 size_t ilen, 00418 unsigned char output[20] ) 00419 { 00420 int ret; 00421 mbedtls_sha1_context ctx; 00422 00423 mbedtls_sha1_init( &ctx ); 00424 00425 if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) 00426 goto exit; 00427 00428 if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 ) 00429 goto exit; 00430 00431 if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 ) 00432 goto exit; 00433 00434 exit: 00435 mbedtls_sha1_free( &ctx ); 00436 00437 return( ret ); 00438 } 00439 00440 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00441 void mbedtls_sha1( const unsigned char *input, 00442 size_t ilen, 00443 unsigned char output[20] ) 00444 { 00445 mbedtls_sha1_ret( input, ilen, output ); 00446 } 00447 #endif 00448 00449 #if defined(MBEDTLS_SELF_TEST) 00450 /* 00451 * FIPS-180-1 test vectors 00452 */ 00453 static const unsigned char sha1_test_buf[3][57] = 00454 { 00455 { "abc" }, 00456 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 00457 { "" } 00458 }; 00459 00460 static const size_t sha1_test_buflen[3] = 00461 { 00462 3, 56, 1000 00463 }; 00464 00465 static const unsigned char sha1_test_sum[3][20] = 00466 { 00467 { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 00468 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, 00469 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 00470 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, 00471 { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, 00472 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } 00473 }; 00474 00475 /* 00476 * Checkup routine 00477 */ 00478 int mbedtls_sha1_self_test( int verbose ) 00479 { 00480 int i, j, buflen, ret = 0; 00481 unsigned char buf[1024]; 00482 unsigned char sha1sum[20]; 00483 mbedtls_sha1_context ctx; 00484 00485 mbedtls_sha1_init( &ctx ); 00486 00487 /* 00488 * SHA-1 00489 */ 00490 for( i = 0; i < 3; i++ ) 00491 { 00492 if( verbose != 0 ) 00493 mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); 00494 00495 if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 ) 00496 goto fail; 00497 00498 if( i == 2 ) 00499 { 00500 memset( buf, 'a', buflen = 1000 ); 00501 00502 for( j = 0; j < 1000; j++ ) 00503 { 00504 ret = mbedtls_sha1_update_ret( &ctx, buf, buflen ); 00505 if( ret != 0 ) 00506 goto fail; 00507 } 00508 } 00509 else 00510 { 00511 ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i], 00512 sha1_test_buflen[i] ); 00513 if( ret != 0 ) 00514 goto fail; 00515 } 00516 00517 if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 ) 00518 goto fail; 00519 00520 if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) 00521 { 00522 ret = 1; 00523 goto fail; 00524 } 00525 00526 if( verbose != 0 ) 00527 mbedtls_printf( "passed\n" ); 00528 } 00529 00530 if( verbose != 0 ) 00531 mbedtls_printf( "\n" ); 00532 00533 goto exit; 00534 00535 fail: 00536 if( verbose != 0 ) 00537 mbedtls_printf( "failed\n" ); 00538 00539 exit: 00540 mbedtls_sha1_free( &ctx ); 00541 00542 return( ret ); 00543 } 00544 00545 #endif /* MBEDTLS_SELF_TEST */ 00546 00547 #endif /* MBEDTLS_SHA1_C */
Generated on Tue Aug 9 2022 00:37:19 by
1.7.2