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 : http://creativecommons.org/publicdomain/zero/1.0
9 - OpenSSL license : https://www.openssl.org/source/license.html
10 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
12 More information about the BLAKE2 hash function can be found at
29 /* This will help compatibility with coreutils */
30 int blake2b_stream( FILE *stream
, void *resstream
, size_t outbytes
)
35 static const size_t buffer_length
= 32768;
36 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
38 if( !buffer
) return -1;
40 blake2b_init( S
, outbytes
);
48 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
51 if( buffer_length
== sum
)
56 if( ferror( stream
) )
66 blake2b_update( S
, buffer
, buffer_length
);
71 if( sum
> 0 ) blake2b_update( S
, buffer
, sum
);
73 blake2b_final( S
, resstream
, outbytes
);
81 int blake2s_stream( FILE *stream
, void *resstream
, size_t outbytes
)
86 static const size_t buffer_length
= 32768;
87 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
89 if( !buffer
) return -1;
91 blake2s_init( S
, outbytes
);
99 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
102 if( buffer_length
== sum
)
107 if( ferror( stream
) )
117 blake2s_update( S
, buffer
, buffer_length
);
122 if( sum
> 0 ) blake2s_update( S
, buffer
, sum
);
124 blake2s_final( S
, resstream
, outbytes
);
132 int blake2sp_stream( FILE *stream
, void *resstream
, size_t outbytes
)
137 static const size_t buffer_length
= 16 * ( 1UL << 20 );
138 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
140 if( !buffer
) return -1;
142 blake2sp_init( S
, outbytes
);
150 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
153 if( buffer_length
== sum
)
158 if( ferror( stream
) )
168 blake2sp_update( S
, buffer
, buffer_length
);
173 if( sum
> 0 ) blake2sp_update( S
, buffer
, sum
);
175 blake2sp_final( S
, resstream
, outbytes
);
183 int blake2bp_stream( FILE *stream
, void *resstream
, size_t outbytes
)
188 static const size_t buffer_length
= 16 * ( 1UL << 20 );
189 uint8_t *buffer
= ( uint8_t * )malloc( buffer_length
);
191 if( !buffer
) return -1;
193 blake2bp_init( S
, outbytes
);
201 n
= fread( buffer
+ sum
, 1, buffer_length
- sum
, stream
);
204 if( buffer_length
== sum
)
209 if( ferror( stream
) )
219 blake2bp_update( S
, buffer
, buffer_length
);
224 if( sum
> 0 ) blake2bp_update( S
, buffer
, sum
);
226 blake2bp_final( S
, resstream
, outbytes
);
233 typedef int ( *blake2fn
)( FILE *, void *, size_t );
236 static void usage( char **argv
, int errcode
)
238 FILE *out
= errcode
? stderr
: stdout
;
239 fprintf( out
, "Usage: %s [OPTION]... [FILE]...\n", argv
[0] );
240 fprintf( out
, "\n" );
241 fprintf( out
, "With no FILE, or when FILE is -, read standard input.\n" );
242 fprintf( out
, "\n" );
243 fprintf( out
, " -a <algo> hash algorithm (blake2b is default): \n"
244 " [blake2b|blake2s|blake2bp|blake2sp]\n" );
245 fprintf( out
, " -l <length> digest length in bits, must not exceed the maximum for\n"
246 " the selected algorithm and must be a multiple of 8\n" );
247 fprintf( out
, " --tag create a BSD-style checksum\n" );
248 fprintf( out
, " --help display this help and exit\n" );
252 int main( int argc
, char **argv
)
254 blake2fn blake2_stream
= blake2b_stream
;
255 unsigned long maxbytes
= BLAKE2B_OUTBYTES
;
256 const char *algorithm
= "BLAKE2b";
257 unsigned long outbytes
= 0;
258 unsigned char hash
[BLAKE2B_OUTBYTES
] = {0};
259 bool bsdstyle
= false;
265 int option_index
= 0;
267 unsigned long outbits
;
268 static struct option long_options
[] = {
269 { "help", no_argument
, 0, 0 },
270 { "tag", no_argument
, 0, 0 },
274 c
= getopt_long( argc
, argv
, "a:l:", long_options
, &option_index
);
279 if( 0 == strcmp( optarg
, "blake2b" ) )
281 blake2_stream
= blake2b_stream
;
282 maxbytes
= BLAKE2B_OUTBYTES
;
283 algorithm
= "BLAKE2b";
285 else if ( 0 == strcmp( optarg
, "blake2s" ) )
287 blake2_stream
= blake2s_stream
;
288 maxbytes
= BLAKE2S_OUTBYTES
;
289 algorithm
= "BLAKE2s";
291 else if ( 0 == strcmp( optarg
, "blake2bp" ) )
293 blake2_stream
= blake2bp_stream
;
294 maxbytes
= BLAKE2B_OUTBYTES
;
295 algorithm
= "BLAKE2bp";
297 else if ( 0 == strcmp( optarg
, "blake2sp" ) )
299 blake2_stream
= blake2sp_stream
;
300 maxbytes
= BLAKE2S_OUTBYTES
;
301 algorithm
= "BLAKE2sp";
305 printf( "Invalid function name: `%s'\n", optarg
);
312 outbits
= strtoul(optarg
, &end
, 10);
313 if( !end
|| *end
!= '\0' || outbits
% 8 != 0)
315 printf( "Invalid length argument: `%s'\n", optarg
);
318 outbytes
= outbits
/ 8;
322 if( 0 == strcmp( "help", long_options
[option_index
].name
) )
324 else if( 0 == strcmp( "tag", long_options
[option_index
].name
) )
334 if(outbytes
> maxbytes
)
336 printf( "Invalid length argument: %lu\n", outbytes
* 8 );
337 printf( "Maximum digest length for %s is %lu\n", algorithm
, maxbytes
* 8 );
340 else if( outbytes
== 0 )
344 argv
[argc
++] = (char *) "-";
346 for( i
= optind
; i
< argc
; ++i
)
349 if( argv
[i
][0] == '-' && argv
[i
][1] == '\0' )
352 f
= fopen( argv
[i
], "rb" );
356 fprintf( stderr
, "Could not open `%s': %s\n", argv
[i
], strerror( errno
) );
360 if( blake2_stream( f
, hash
, outbytes
) < 0 )
362 fprintf( stderr
, "Failed to hash `%s'\n", argv
[i
] );
369 if( outbytes
< maxbytes
)
370 printf( "%s-%lu (%s) = ", algorithm
, outbytes
* 8, argv
[i
] );
372 printf( "%s (%s) = ", algorithm
, argv
[i
] );
375 for( j
= 0; j
< outbytes
; ++j
)
376 printf( "%02x", hash
[j
] );
381 printf( " %s\n", argv
[i
] );
384 if( f
!= stdin
) fclose( f
);