| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifdef HAVE_CONFIG_H |
| | # include <config.h> |
| | #endif |
| |
|
| | #include <stdio.h> |
| | #include <stdlib.h> |
| |
|
| | #include "blake2.h" |
| |
|
| | #if 0 |
| | |
| | int blake2s_stream( FILE *stream, void *resstream, size_t outbytes ) |
| | { |
| | int ret = -1; |
| | size_t sum, n; |
| | blake2s_state S[1]; |
| | static const size_t buffer_length = 32768; |
| | uint8_t *buffer = ( uint8_t * )malloc( buffer_length ); |
| |
|
| | if( !buffer ) return -1; |
| |
|
| | blake2s_init( S, outbytes ); |
| |
|
| | while( 1 ) |
| | { |
| | sum = 0; |
| |
|
| | while( 1 ) |
| | { |
| | n = fread( buffer + sum, 1, buffer_length - sum, stream ); |
| | sum += n; |
| |
|
| | if( buffer_length == sum ) |
| | break; |
| |
|
| | if( 0 == n ) |
| | { |
| | if( ferror( stream ) ) |
| | goto cleanup_buffer; |
| |
|
| | goto final_process; |
| | } |
| |
|
| | if( feof( stream ) ) |
| | goto final_process; |
| | } |
| |
|
| | blake2s_update( S, buffer, buffer_length ); |
| | } |
| |
|
| | final_process:; |
| |
|
| | if( sum > 0 ) blake2s_update( S, buffer, sum ); |
| |
|
| | blake2s_final( S, resstream, outbytes ); |
| | ret = 0; |
| | cleanup_buffer: |
| | free( buffer ); |
| | return ret; |
| | } |
| | #endif |
| |
|
| | int blake2b_stream( FILE *stream, void *resstream, size_t outbytes ) |
| | { |
| | int ret = -1; |
| | size_t sum, n; |
| | blake2b_state S[1]; |
| | static const size_t buffer_length = 32768; |
| | uint8_t *buffer = ( uint8_t * )malloc( buffer_length ); |
| |
|
| | if( !buffer ) return -1; |
| |
|
| | blake2b_init( S, outbytes ); |
| |
|
| | while( 1 ) |
| | { |
| | sum = 0; |
| |
|
| | while( 1 ) |
| | { |
| | n = fread( buffer + sum, 1, buffer_length - sum, stream ); |
| | sum += n; |
| |
|
| | if( buffer_length == sum ) |
| | break; |
| |
|
| | if( 0 == n ) |
| | { |
| | if( ferror( stream ) ) |
| | goto cleanup_buffer; |
| |
|
| | goto final_process; |
| | } |
| |
|
| | if( feof( stream ) ) |
| | goto final_process; |
| | } |
| |
|
| | blake2b_update( S, buffer, buffer_length ); |
| | } |
| |
|
| | final_process:; |
| |
|
| | if( sum > 0 ) blake2b_update( S, buffer, sum ); |
| |
|
| | blake2b_final( S, resstream, outbytes ); |
| | ret = 0; |
| | cleanup_buffer: |
| | free( buffer ); |
| | return ret; |
| | } |
| |
|
| | #if 0 |
| |
|
| | #include <errno.h> |
| | #include <getopt.h> |
| | #include <string.h> |
| | #include <unistd.h> |
| |
|
| | int blake2sp_stream( FILE *stream, void *resstream, size_t outbytes ) |
| | { |
| | int ret = -1; |
| | size_t sum, n; |
| | blake2sp_state S[1]; |
| | static const size_t buffer_length = 16 * ( 1UL << 20 ); |
| | uint8_t *buffer = ( uint8_t * )malloc( buffer_length ); |
| |
|
| | if( !buffer ) return -1; |
| |
|
| | blake2sp_init( S, outbytes ); |
| |
|
| | while( 1 ) |
| | { |
| | sum = 0; |
| |
|
| | while( 1 ) |
| | { |
| | n = fread( buffer + sum, 1, buffer_length - sum, stream ); |
| | sum += n; |
| |
|
| | if( buffer_length == sum ) |
| | break; |
| |
|
| | if( 0 == n ) |
| | { |
| | if( ferror( stream ) ) |
| | goto cleanup_buffer; |
| |
|
| | goto final_process; |
| | } |
| |
|
| | if( feof( stream ) ) |
| | goto final_process; |
| | } |
| |
|
| | blake2sp_update( S, buffer, buffer_length ); |
| | } |
| |
|
| | final_process:; |
| |
|
| | if( sum > 0 ) blake2sp_update( S, buffer, sum ); |
| |
|
| | blake2sp_final( S, resstream, outbytes ); |
| | ret = 0; |
| | cleanup_buffer: |
| | free( buffer ); |
| | return ret; |
| | } |
| |
|
| |
|
| | int blake2bp_stream( FILE *stream, void *resstream, size_t outbytes ) |
| | { |
| | int ret = -1; |
| | size_t sum, n; |
| | blake2bp_state S[1]; |
| | static const size_t buffer_length = 16 * ( 1UL << 20 ); |
| | uint8_t *buffer = ( uint8_t * )malloc( buffer_length ); |
| |
|
| | if( !buffer ) return -1; |
| |
|
| | blake2bp_init( S, outbytes ); |
| |
|
| | while( 1 ) |
| | { |
| | sum = 0; |
| |
|
| | while( 1 ) |
| | { |
| | n = fread( buffer + sum, 1, buffer_length - sum, stream ); |
| | sum += n; |
| |
|
| | if( buffer_length == sum ) |
| | break; |
| |
|
| | if( 0 == n ) |
| | { |
| | if( ferror( stream ) ) |
| | goto cleanup_buffer; |
| |
|
| | goto final_process; |
| | } |
| |
|
| | if( feof( stream ) ) |
| | goto final_process; |
| | } |
| |
|
| | blake2bp_update( S, buffer, buffer_length ); |
| | } |
| |
|
| | final_process:; |
| |
|
| | if( sum > 0 ) blake2bp_update( S, buffer, sum ); |
| |
|
| | blake2bp_final( S, resstream, outbytes ); |
| | ret = 0; |
| | cleanup_buffer: |
| | free( buffer ); |
| | return ret; |
| | } |
| |
|
| | typedef int ( *blake2fn )( FILE *, void *, size_t ); |
| |
|
| |
|
| | static void usage( char **argv, int errcode ) |
| | { |
| | FILE *out = errcode ? stderr : stdout; |
| | fprintf( out, "Usage: %s [OPTION]... [FILE]...\n", argv[0] ); |
| | fprintf( out, "\n" ); |
| | fprintf( out, "With no FILE, or when FILE is -, read standard input.\n" ); |
| | fprintf( out, "\n" ); |
| | fprintf( out, " -a <algo> hash algorithm (blake2b is default): \n" |
| | " [blake2b|blake2s|blake2bp|blake2sp]\n" ); |
| | fprintf( out, " -l <length> digest length in bits, must not exceed the maximum for\n" |
| | " the selected algorithm and must be a multiple of 8\n" ); |
| | fprintf( out, " --tag create a BSD-style checksum\n" ); |
| | fprintf( out, " --help display this help and exit\n" ); |
| | exit( errcode ); |
| | } |
| |
|
| |
|
| | int main( int argc, char **argv ) |
| | { |
| | blake2fn blake2_stream = blake2b_stream; |
| | unsigned long maxbytes = BLAKE2B_OUTBYTES; |
| | const char *algorithm = "BLAKE2b"; |
| | unsigned long outbytes = 0; |
| | unsigned char hash[BLAKE2B_OUTBYTES] = {0}; |
| | bool bsdstyle = false; |
| | int c, i; |
| | opterr = 1; |
| |
|
| | while( 1 ) |
| | { |
| | int option_index = 0; |
| | char *end = nullptr; |
| | unsigned long outbits; |
| | static struct option long_options[] = { |
| | { "help", no_argument, 0, 0 }, |
| | { "tag", no_argument, 0, 0 }, |
| | { nullptr, 0, nullptr, 0 } |
| | }; |
| |
|
| | c = getopt_long( argc, argv, "a:l:", long_options, &option_index ); |
| | if( c == -1 ) break; |
| | switch( c ) |
| | { |
| | case 'a': |
| | if( 0 == strcmp( optarg, "blake2b" ) ) |
| | { |
| | blake2_stream = blake2b_stream; |
| | maxbytes = BLAKE2B_OUTBYTES; |
| | algorithm = "BLAKE2b"; |
| | } |
| | else if ( 0 == strcmp( optarg, "blake2s" ) ) |
| | { |
| | blake2_stream = blake2s_stream; |
| | maxbytes = BLAKE2S_OUTBYTES; |
| | algorithm = "BLAKE2s"; |
| | } |
| | else if ( 0 == strcmp( optarg, "blake2bp" ) ) |
| | { |
| | blake2_stream = blake2bp_stream; |
| | maxbytes = BLAKE2B_OUTBYTES; |
| | algorithm = "BLAKE2bp"; |
| | } |
| | else if ( 0 == strcmp( optarg, "blake2sp" ) ) |
| | { |
| | blake2_stream = blake2sp_stream; |
| | maxbytes = BLAKE2S_OUTBYTES; |
| | algorithm = "BLAKE2sp"; |
| | } |
| | else |
| | { |
| | printf( "Invalid function name: `%s'\n", optarg ); |
| | usage( argv, 111 ); |
| | } |
| |
|
| | break; |
| |
|
| | case 'l': |
| | outbits = strtoul(optarg, &end, 10); |
| | if( !end || *end != '\0' || outbits % 8 != 0) |
| | { |
| | printf( "Invalid length argument: `%s'\n", optarg); |
| | usage( argv, 111 ); |
| | } |
| | outbytes = outbits / 8; |
| | break; |
| |
|
| | case 0: |
| | if( 0 == strcmp( "help", long_options[option_index].name ) ) |
| | usage( argv, 0 ); |
| | else if( 0 == strcmp( "tag", long_options[option_index].name ) ) |
| | bsdstyle = true; |
| | break; |
| |
|
| | case '?': |
| | usage( argv, 1 ); |
| | break; |
| | } |
| | } |
| |
|
| | if(outbytes > maxbytes) |
| | { |
| | printf( "Invalid length argument: %lu\n", outbytes * 8 ); |
| | printf( "Maximum digest length for %s is %lu\n", algorithm, maxbytes * 8 ); |
| | usage( argv, 111 ); |
| | } |
| | else if( outbytes == 0 ) |
| | outbytes = maxbytes; |
| |
|
| | if( optind == argc ) |
| | argv[argc++] = (char *) "-"; |
| |
|
| | for( i = optind; i < argc; ++i ) |
| | { |
| | FILE *f = nullptr; |
| | if( argv[i][0] == '-' && argv[i][1] == '\0' ) |
| | f = stdin; |
| | else |
| | f = fopen( argv[i], "rb" ); |
| |
|
| | if( !f ) |
| | { |
| | fprintf( stderr, "Could not open `%s': %s\n", argv[i], strerror( errno ) ); |
| | continue; |
| | } |
| |
|
| | if( blake2_stream( f, hash, outbytes ) < 0 ) |
| | { |
| | fprintf( stderr, "Failed to hash `%s'\n", argv[i] ); |
| | } |
| | else |
| | { |
| | size_t j; |
| | if( bsdstyle ) |
| | { |
| | if( outbytes < maxbytes ) |
| | printf( "%s-%lu (%s) = ", algorithm, outbytes * 8, argv[i] ); |
| | else |
| | printf( "%s (%s) = ", algorithm, argv[i] ); |
| | } |
| |
|
| | for( j = 0; j < outbytes; ++j ) |
| | printf( "%02x", hash[j] ); |
| |
|
| | if( bsdstyle ) |
| | printf( "\n" ); |
| | else |
| | printf( " %s\n", argv[i] ); |
| | } |
| |
|
| | if( f == stdin ) |
| | clearerr( f ); |
| | else if( fclose( f ) != 0 ) |
| | fprintf( stderr, "Could not close `%s': %s\n", argv[i], strerror( errno ) ); |
| | } |
| |
|
| | return 0; |
| | } |
| | #endif |
| |
|