Hannes Tschofenig
/
aes-gcm-test-program
Example program to test AES-GCM functionality. Used for a workshop
Embed:
(wiki syntax)
Show/hide line numbers
md4.c
00001 /* 00002 * RFC 1186/1320 compliant MD4 implementation 00003 * 00004 * Copyright (C) 2006-2014, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 /* 00026 * The MD4 algorithm was designed by Ron Rivest in 1990. 00027 * 00028 * http://www.ietf.org/rfc/rfc1186.txt 00029 * http://www.ietf.org/rfc/rfc1320.txt 00030 */ 00031 00032 #if !defined(POLARSSL_CONFIG_FILE) 00033 #include "polarssl/config.h" 00034 #else 00035 #include POLARSSL_CONFIG_FILE 00036 #endif 00037 00038 #if defined(POLARSSL_MD4_C) 00039 00040 #include "polarssl/md4.h" 00041 00042 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) 00043 #include <stdio.h> 00044 #endif 00045 00046 #if defined(POLARSSL_PLATFORM_C) 00047 #include "polarssl/platform.h" 00048 #else 00049 #define polarssl_printf printf 00050 #endif 00051 00052 #if !defined(POLARSSL_MD4_ALT) 00053 00054 /* 00055 * 32-bit integer manipulation macros (little endian) 00056 */ 00057 #ifndef GET_UINT32_LE 00058 #define GET_UINT32_LE(n,b,i) \ 00059 { \ 00060 (n) = ( (uint32_t) (b)[(i) ] ) \ 00061 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 00062 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 00063 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 00064 } 00065 #endif 00066 00067 #ifndef PUT_UINT32_LE 00068 #define PUT_UINT32_LE(n,b,i) \ 00069 { \ 00070 (b)[(i) ] = (unsigned char) ( (n) ); \ 00071 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ 00072 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ 00073 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ 00074 } 00075 #endif 00076 00077 /* 00078 * MD4 context setup 00079 */ 00080 void md4_starts( md4_context *ctx ) 00081 { 00082 ctx->total [0] = 0; 00083 ctx->total [1] = 0; 00084 00085 ctx->state [0] = 0x67452301; 00086 ctx->state [1] = 0xEFCDAB89; 00087 ctx->state [2] = 0x98BADCFE; 00088 ctx->state [3] = 0x10325476; 00089 } 00090 00091 void md4_process( md4_context *ctx, const unsigned char data[64] ) 00092 { 00093 uint32_t X[16], A, B, C, D; 00094 00095 GET_UINT32_LE( X[ 0], data, 0 ); 00096 GET_UINT32_LE( X[ 1], data, 4 ); 00097 GET_UINT32_LE( X[ 2], data, 8 ); 00098 GET_UINT32_LE( X[ 3], data, 12 ); 00099 GET_UINT32_LE( X[ 4], data, 16 ); 00100 GET_UINT32_LE( X[ 5], data, 20 ); 00101 GET_UINT32_LE( X[ 6], data, 24 ); 00102 GET_UINT32_LE( X[ 7], data, 28 ); 00103 GET_UINT32_LE( X[ 8], data, 32 ); 00104 GET_UINT32_LE( X[ 9], data, 36 ); 00105 GET_UINT32_LE( X[10], data, 40 ); 00106 GET_UINT32_LE( X[11], data, 44 ); 00107 GET_UINT32_LE( X[12], data, 48 ); 00108 GET_UINT32_LE( X[13], data, 52 ); 00109 GET_UINT32_LE( X[14], data, 56 ); 00110 GET_UINT32_LE( X[15], data, 60 ); 00111 00112 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 00113 00114 A = ctx->state [0]; 00115 B = ctx->state [1]; 00116 C = ctx->state [2]; 00117 D = ctx->state [3]; 00118 00119 #define F(x, y, z) ((x & y) | ((~x) & z)) 00120 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } 00121 00122 P( A, B, C, D, X[ 0], 3 ); 00123 P( D, A, B, C, X[ 1], 7 ); 00124 P( C, D, A, B, X[ 2], 11 ); 00125 P( B, C, D, A, X[ 3], 19 ); 00126 P( A, B, C, D, X[ 4], 3 ); 00127 P( D, A, B, C, X[ 5], 7 ); 00128 P( C, D, A, B, X[ 6], 11 ); 00129 P( B, C, D, A, X[ 7], 19 ); 00130 P( A, B, C, D, X[ 8], 3 ); 00131 P( D, A, B, C, X[ 9], 7 ); 00132 P( C, D, A, B, X[10], 11 ); 00133 P( B, C, D, A, X[11], 19 ); 00134 P( A, B, C, D, X[12], 3 ); 00135 P( D, A, B, C, X[13], 7 ); 00136 P( C, D, A, B, X[14], 11 ); 00137 P( B, C, D, A, X[15], 19 ); 00138 00139 #undef P 00140 #undef F 00141 00142 #define F(x,y,z) ((x & y) | (x & z) | (y & z)) 00143 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } 00144 00145 P( A, B, C, D, X[ 0], 3 ); 00146 P( D, A, B, C, X[ 4], 5 ); 00147 P( C, D, A, B, X[ 8], 9 ); 00148 P( B, C, D, A, X[12], 13 ); 00149 P( A, B, C, D, X[ 1], 3 ); 00150 P( D, A, B, C, X[ 5], 5 ); 00151 P( C, D, A, B, X[ 9], 9 ); 00152 P( B, C, D, A, X[13], 13 ); 00153 P( A, B, C, D, X[ 2], 3 ); 00154 P( D, A, B, C, X[ 6], 5 ); 00155 P( C, D, A, B, X[10], 9 ); 00156 P( B, C, D, A, X[14], 13 ); 00157 P( A, B, C, D, X[ 3], 3 ); 00158 P( D, A, B, C, X[ 7], 5 ); 00159 P( C, D, A, B, X[11], 9 ); 00160 P( B, C, D, A, X[15], 13 ); 00161 00162 #undef P 00163 #undef F 00164 00165 #define F(x,y,z) (x ^ y ^ z) 00166 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } 00167 00168 P( A, B, C, D, X[ 0], 3 ); 00169 P( D, A, B, C, X[ 8], 9 ); 00170 P( C, D, A, B, X[ 4], 11 ); 00171 P( B, C, D, A, X[12], 15 ); 00172 P( A, B, C, D, X[ 2], 3 ); 00173 P( D, A, B, C, X[10], 9 ); 00174 P( C, D, A, B, X[ 6], 11 ); 00175 P( B, C, D, A, X[14], 15 ); 00176 P( A, B, C, D, X[ 1], 3 ); 00177 P( D, A, B, C, X[ 9], 9 ); 00178 P( C, D, A, B, X[ 5], 11 ); 00179 P( B, C, D, A, X[13], 15 ); 00180 P( A, B, C, D, X[ 3], 3 ); 00181 P( D, A, B, C, X[11], 9 ); 00182 P( C, D, A, B, X[ 7], 11 ); 00183 P( B, C, D, A, X[15], 15 ); 00184 00185 #undef F 00186 #undef P 00187 00188 ctx->state [0] += A; 00189 ctx->state [1] += B; 00190 ctx->state [2] += C; 00191 ctx->state [3] += D; 00192 } 00193 00194 /* 00195 * MD4 process buffer 00196 */ 00197 void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) 00198 { 00199 size_t fill; 00200 uint32_t left; 00201 00202 if( ilen <= 0 ) 00203 return; 00204 00205 left = ctx->total [0] & 0x3F; 00206 fill = 64 - left; 00207 00208 ctx->total [0] += (uint32_t) ilen; 00209 ctx->total [0] &= 0xFFFFFFFF; 00210 00211 if( ctx->total [0] < (uint32_t) ilen ) 00212 ctx->total [1]++; 00213 00214 if( left && ilen >= fill ) 00215 { 00216 memcpy( (void *) (ctx->buffer + left), 00217 (void *) input, fill ); 00218 md4_process( ctx, ctx->buffer ); 00219 input += fill; 00220 ilen -= fill; 00221 left = 0; 00222 } 00223 00224 while( ilen >= 64 ) 00225 { 00226 md4_process( ctx, input ); 00227 input += 64; 00228 ilen -= 64; 00229 } 00230 00231 if( ilen > 0 ) 00232 { 00233 memcpy( (void *) (ctx->buffer + left), 00234 (void *) input, ilen ); 00235 } 00236 } 00237 00238 static const unsigned char md4_padding[64] = 00239 { 00240 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00244 }; 00245 00246 /* 00247 * MD4 final digest 00248 */ 00249 void md4_finish( md4_context *ctx, unsigned char output[16] ) 00250 { 00251 uint32_t last, padn; 00252 uint32_t high, low; 00253 unsigned char msglen[8]; 00254 00255 high = ( ctx->total [0] >> 29 ) 00256 | ( ctx->total [1] << 3 ); 00257 low = ( ctx->total [0] << 3 ); 00258 00259 PUT_UINT32_LE( low, msglen, 0 ); 00260 PUT_UINT32_LE( high, msglen, 4 ); 00261 00262 last = ctx->total [0] & 0x3F; 00263 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00264 00265 md4_update( ctx, (unsigned char *) md4_padding, padn ); 00266 md4_update( ctx, msglen, 8 ); 00267 00268 PUT_UINT32_LE( ctx->state [0], output, 0 ); 00269 PUT_UINT32_LE( ctx->state [1], output, 4 ); 00270 PUT_UINT32_LE( ctx->state [2], output, 8 ); 00271 PUT_UINT32_LE( ctx->state [3], output, 12 ); 00272 } 00273 00274 #endif /* !POLARSSL_MD4_ALT */ 00275 00276 /* 00277 * output = MD4( input buffer ) 00278 */ 00279 void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) 00280 { 00281 md4_context ctx; 00282 00283 md4_starts( &ctx ); 00284 md4_update( &ctx, input, ilen ); 00285 md4_finish( &ctx, output ); 00286 00287 memset( &ctx, 0, sizeof( md4_context ) ); 00288 } 00289 00290 #if defined(POLARSSL_FS_IO) 00291 /* 00292 * output = MD4( file contents ) 00293 */ 00294 int md4_file( const char *path, unsigned char output[16] ) 00295 { 00296 FILE *f; 00297 size_t n; 00298 md4_context ctx; 00299 unsigned char buf[1024]; 00300 00301 if( ( f = fopen( path, "rb" ) ) == NULL ) 00302 return( POLARSSL_ERR_MD4_FILE_IO_ERROR ); 00303 00304 md4_starts( &ctx ); 00305 00306 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 00307 md4_update( &ctx, buf, n ); 00308 00309 md4_finish( &ctx, output ); 00310 00311 memset( &ctx, 0, sizeof( md4_context ) ); 00312 00313 if( ferror( f ) != 0 ) 00314 { 00315 fclose( f ); 00316 return( POLARSSL_ERR_MD4_FILE_IO_ERROR ); 00317 } 00318 00319 fclose( f ); 00320 return( 0 ); 00321 } 00322 #endif /* POLARSSL_FS_IO */ 00323 00324 /* 00325 * MD4 HMAC context setup 00326 */ 00327 void md4_hmac_starts( md4_context *ctx, const unsigned char *key, 00328 size_t keylen ) 00329 { 00330 size_t i; 00331 unsigned char sum[16]; 00332 00333 if( keylen > 64 ) 00334 { 00335 md4( key, keylen, sum ); 00336 keylen = 16; 00337 key = sum; 00338 } 00339 00340 memset( ctx->ipad , 0x36, 64 ); 00341 memset( ctx->opad , 0x5C, 64 ); 00342 00343 for( i = 0; i < keylen; i++ ) 00344 { 00345 ctx->ipad [i] = (unsigned char)( ctx->ipad [i] ^ key[i] ); 00346 ctx->opad [i] = (unsigned char)( ctx->opad [i] ^ key[i] ); 00347 } 00348 00349 md4_starts( ctx ); 00350 md4_update( ctx, ctx->ipad , 64 ); 00351 00352 memset( sum, 0, sizeof( sum ) ); 00353 } 00354 00355 /* 00356 * MD4 HMAC process buffer 00357 */ 00358 void md4_hmac_update( md4_context *ctx, const unsigned char *input, 00359 size_t ilen ) 00360 { 00361 md4_update( ctx, input, ilen ); 00362 } 00363 00364 /* 00365 * MD4 HMAC final digest 00366 */ 00367 void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ) 00368 { 00369 unsigned char tmpbuf[16]; 00370 00371 md4_finish( ctx, tmpbuf ); 00372 md4_starts( ctx ); 00373 md4_update( ctx, ctx->opad , 64 ); 00374 md4_update( ctx, tmpbuf, 16 ); 00375 md4_finish( ctx, output ); 00376 00377 memset( tmpbuf, 0, sizeof( tmpbuf ) ); 00378 } 00379 00380 /* 00381 * MD4 HMAC context reset 00382 */ 00383 void md4_hmac_reset( md4_context *ctx ) 00384 { 00385 md4_starts( ctx ); 00386 md4_update( ctx, ctx->ipad , 64 ); 00387 } 00388 00389 /* 00390 * output = HMAC-MD4( hmac key, input buffer ) 00391 */ 00392 void md4_hmac( const unsigned char *key, size_t keylen, 00393 const unsigned char *input, size_t ilen, 00394 unsigned char output[16] ) 00395 { 00396 md4_context ctx; 00397 00398 md4_hmac_starts( &ctx, key, keylen ); 00399 md4_hmac_update( &ctx, input, ilen ); 00400 md4_hmac_finish( &ctx, output ); 00401 00402 memset( &ctx, 0, sizeof( md4_context ) ); 00403 } 00404 00405 #if defined(POLARSSL_SELF_TEST) 00406 00407 /* 00408 * RFC 1320 test vectors 00409 */ 00410 static const char md4_test_str[7][81] = 00411 { 00412 { "" }, 00413 { "a" }, 00414 { "abc" }, 00415 { "message digest" }, 00416 { "abcdefghijklmnopqrstuvwxyz" }, 00417 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 00418 { "12345678901234567890123456789012345678901234567890123456789012" \ 00419 "345678901234567890" } 00420 }; 00421 00422 static const unsigned char md4_test_sum[7][16] = 00423 { 00424 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, 00425 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, 00426 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, 00427 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, 00428 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, 00429 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, 00430 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, 00431 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, 00432 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, 00433 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, 00434 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, 00435 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, 00436 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, 00437 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } 00438 }; 00439 00440 /* 00441 * Checkup routine 00442 */ 00443 int md4_self_test( int verbose ) 00444 { 00445 int i; 00446 unsigned char md4sum[16]; 00447 00448 for( i = 0; i < 7; i++ ) 00449 { 00450 if( verbose != 0 ) 00451 polarssl_printf( " MD4 test #%d: ", i + 1 ); 00452 00453 md4( (unsigned char *) md4_test_str[i], 00454 strlen( md4_test_str[i] ), md4sum ); 00455 00456 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) 00457 { 00458 if( verbose != 0 ) 00459 polarssl_printf( "failed\n" ); 00460 00461 return( 1 ); 00462 } 00463 00464 if( verbose != 0 ) 00465 polarssl_printf( "passed\n" ); 00466 } 00467 00468 if( verbose != 0 ) 00469 polarssl_printf( "\n" ); 00470 00471 return( 0 ); 00472 } 00473 00474 #endif /* POLARSSL_SELF_TEST */ 00475 00476 #endif /* POLARSSL_MD4_C */ 00477 00478
Generated on Tue Jul 12 2022 19:40:15 by 1.7.2