2 BLAKE2 reference source code package - b2sum tool
4 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
5 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
6 your option. The terms of these licenses can be found at:
8 - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
9 - OpenSSL license : https://www.openssl.org/source/license.html
10 - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
12 More information about the BLAKE2 hash function can be found at
26 /* This will help compatibility with coreutils */
27 int blake2s_stream( FILE *stream
, void *resstream
, size_t outbytes
)
32 static const size_t buffer_length
= 32768;
33 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
35 if( !buffer
) return -1;
37 blake2s_init( S
, outbytes
);
45 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
48 if( buffer_length
== sum
)
53 if( ferror( stream
) )
63 blake2s_update( S
, buffer
, buffer_length
);
68 if( sum
> 0 ) blake2s_update( S
, buffer
, sum
);
70 blake2s_final( S
, resstream
, outbytes
);
78 int blake2b_stream( FILE *stream
, void *resstream
, size_t outbytes
)
83 static const size_t buffer_length
= 32768;
84 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
86 if( !buffer
) return -1;
88 blake2b_init( S
, outbytes
);
96 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
99 if( buffer_length
== sum
)
104 if( ferror( stream
) )
114 blake2b_update( S
, buffer
, buffer_length
);
119 if( sum
> 0 ) blake2b_update( S
, buffer
, sum
);
121 blake2b_final( S
, resstream
, outbytes
);
135 int blake2sp_stream( FILE *stream
, void *resstream
, size_t outbytes
)
140 static const size_t buffer_length
= 16 * ( 1UL << 20 );
141 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
143 if( !buffer
) return -1;
145 blake2sp_init( S
, outbytes
);
153 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
156 if( buffer_length
== sum
)
161 if( ferror( stream
) )
171 blake2sp_update( S
, buffer
, buffer_length
);
176 if( sum
> 0 ) blake2sp_update( S
, buffer
, sum
);
178 blake2sp_final( S
, resstream
, outbytes
);
186 int blake2bp_stream( FILE *stream
, void *resstream
, size_t outbytes
)
191 static const size_t buffer_length
= 16 * ( 1UL << 20 );
192 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
194 if( !buffer
) return -1;
196 blake2bp_init( S
, outbytes
);
204 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
207 if( buffer_length
== sum
)
212 if( ferror( stream
) )
222 blake2bp_update( S
, buffer
, buffer_length
);
227 if( sum
> 0 ) blake2bp_update( S
, buffer
, sum
);
229 blake2bp_final( S
, resstream
, outbytes
);
236 typedef int ( *blake2fn
)( FILE *, void *, size_t );
239 static void usage( char **argv
, int errcode
)
241 FILE *out
= errcode
? stderr
: stdout
;
242 fprintf( out
, "Usage: %s [OPTION]... [FILE]...\n", argv
[0] );
243 fprintf( out
, "\n" );
244 fprintf( out
, "With no FILE, or when FILE is -, read standard input.\n" );
245 fprintf( out
, "\n" );
246 fprintf( out
, " -a <algo> hash algorithm (blake2b is default): \n"
247 " [blake2b|blake2s|blake2bp|blake2sp]\n" );
248 fprintf( out
, " -l <length> digest length in bits, must not exceed the maximum for\n"
249 " the selected algorithm and must be a multiple of 8\n" );
250 fprintf( out
, " --tag create a BSD-style checksum\n" );
251 fprintf( out
, " --help display this help and exit\n" );
256 int main( int argc
, char **argv
)
258 blake2fn blake2_stream
= blake2b_stream
;
259 unsigned long maxbytes
= BLAKE2B_OUTBYTES
;
260 const char *algorithm
= "BLAKE2b";
261 unsigned long outbytes
= 0;
262 unsigned char hash
[BLAKE2B_OUTBYTES
] = {0};
263 bool bsdstyle
= false;
269 int option_index
= 0;
271 unsigned long outbits
;
272 static struct option long_options
[] = {
273 { "help", no_argument
, 0, 0 },
274 { "tag", no_argument
, 0, 0 },
275 { nullptr, 0, nullptr, 0 }
278 c
= getopt_long( argc
, argv
, "a:l:", long_options
, &option_index
);
283 if( 0 == strcmp( optarg
, "blake2b" ) )
285 blake2_stream
= blake2b_stream
;
286 maxbytes
= BLAKE2B_OUTBYTES
;
287 algorithm
= "BLAKE2b";
289 else if ( 0 == strcmp( optarg
, "blake2s" ) )
291 blake2_stream
= blake2s_stream
;
292 maxbytes
= BLAKE2S_OUTBYTES
;
293 algorithm
= "BLAKE2s";
295 else if ( 0 == strcmp( optarg
, "blake2bp" ) )
297 blake2_stream
= blake2bp_stream
;
298 maxbytes
= BLAKE2B_OUTBYTES
;
299 algorithm
= "BLAKE2bp";
301 else if ( 0 == strcmp( optarg
, "blake2sp" ) )
303 blake2_stream
= blake2sp_stream
;
304 maxbytes
= BLAKE2S_OUTBYTES
;
305 algorithm
= "BLAKE2sp";
309 printf( "Invalid function name: `%s'\n", optarg
);
316 outbits
= strtoul(optarg
, &end
, 10);
317 if( !end
|| *end
!= '\0' || outbits
% 8 != 0)
319 printf( "Invalid length argument: `%s'\n", optarg
);
322 outbytes
= outbits
/ 8;
326 if( 0 == strcmp( "help", long_options
[option_index
].name
) )
328 else if( 0 == strcmp( "tag", long_options
[option_index
].name
) )
338 if(outbytes
> maxbytes
)
340 printf( "Invalid length argument: %lu\n", outbytes
* 8 );
341 printf( "Maximum digest length for %s is %lu\n", algorithm
, maxbytes
* 8 );
344 else if( outbytes
== 0 )
348 argv
[argc
++] = (char *) "-";
350 for( i
= optind
; i
< argc
; ++i
)
353 if( argv
[i
][0] == '-' && argv
[i
][1] == '\0' )
356 f
= fopen( argv
[i
], "rb" );
360 fprintf( stderr
, "Could not open `%s': %s\n", argv
[i
], strerror( errno
) );
364 if( blake2_stream( f
, hash
, outbytes
) < 0 )
366 fprintf( stderr
, "Failed to hash `%s'\n", argv
[i
] );
373 if( outbytes
< maxbytes
)
374 printf( "%s-%lu (%s) = ", algorithm
, outbytes
* 8, argv
[i
] );
376 printf( "%s (%s) = ", algorithm
, argv
[i
] );
379 for( j
= 0; j
< outbytes
; ++j
)
380 printf( "%02x", hash
[j
] );
385 printf( " %s\n", argv
[i
] );
390 else if( fclose( f
) != 0 )
391 fprintf( stderr
, "Could not close `%s': %s\n", argv
[i
], strerror( errno
) );