Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/BLAKE2/BLAKE2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Barker <paul@paulbarker.me.uk>2016-01-03 14:39:42 +0300
committerPaul Barker <paul@paulbarker.me.uk>2016-01-31 13:51:11 +0300
commit3b2fb9f2cdfa4ef250a817ae3d2c8bfbbf87e66e (patch)
treebe1c157aad48be083f03b380d2528d62a612a594
parent3a9a49defb741ae55fe98d112e9faedd80a958f9 (diff)
b2sum: Add digest length argument
It may be desirable to produce a digest with a shorter length than the default using a BLAKE2 algorithm. For example, the crypto_generichash() function in libsodium uses BLAKE2b but shortens the digest to 256 bits by default and it is useful for debugging to generate similar hashes with b2sum for comparison. The requested digest length is specified in bits, must be a multiple of 8 and cannot exceed the total output length of the selected algoritm. No minimum digest length is enforced. If a shorter-than-default digest length is selected, this is indicated in the output when the '--tag' option is given.
-rw-r--r--b2sum/b2sum.c71
1 files changed, 49 insertions, 22 deletions
diff --git a/b2sum/b2sum.c b/b2sum/b2sum.c
index 36ecd52..af01a81 100644
--- a/b2sum/b2sum.c
+++ b/b2sum/b2sum.c
@@ -25,7 +25,7 @@
#include "blake2.h"
/* This will help compatibility with coreutils */
-int blake2s_stream( FILE *stream, void *resstream )
+int blake2s_stream( FILE *stream, void *resstream, size_t outbytes )
{
int ret = -1;
size_t sum, n;
@@ -35,7 +35,7 @@ int blake2s_stream( FILE *stream, void *resstream )
if( !buffer ) return -1;
- blake2s_init( S, BLAKE2S_OUTBYTES );
+ blake2s_init( S, outbytes );
while( 1 )
{
@@ -68,14 +68,14 @@ final_process:;
if( sum > 0 ) blake2s_update( S, buffer, sum );
- blake2s_final( S, resstream, BLAKE2S_OUTBYTES );
+ blake2s_final( S, resstream, outbytes );
ret = 0;
cleanup_buffer:
free( buffer );
return ret;
}
-int blake2b_stream( FILE *stream, void *resstream )
+int blake2b_stream( FILE *stream, void *resstream, size_t outbytes )
{
int ret = -1;
size_t sum, n;
@@ -85,7 +85,7 @@ int blake2b_stream( FILE *stream, void *resstream )
if( !buffer ) return -1;
- blake2b_init( S, BLAKE2B_OUTBYTES );
+ blake2b_init( S, outbytes );
while( 1 )
{
@@ -118,14 +118,14 @@ final_process:;
if( sum > 0 ) blake2b_update( S, buffer, sum );
- blake2b_final( S, resstream, BLAKE2B_OUTBYTES );
+ blake2b_final( S, resstream, outbytes );
ret = 0;
cleanup_buffer:
free( buffer );
return ret;
}
-int blake2sp_stream( FILE *stream, void *resstream )
+int blake2sp_stream( FILE *stream, void *resstream, size_t outbytes )
{
int ret = -1;
size_t sum, n;
@@ -135,7 +135,7 @@ int blake2sp_stream( FILE *stream, void *resstream )
if( !buffer ) return -1;
- blake2sp_init( S, BLAKE2S_OUTBYTES );
+ blake2sp_init( S, outbytes );
while( 1 )
{
@@ -168,7 +168,7 @@ final_process:;
if( sum > 0 ) blake2sp_update( S, buffer, sum );
- blake2sp_final( S, resstream, BLAKE2S_OUTBYTES );
+ blake2sp_final( S, resstream, outbytes );
ret = 0;
cleanup_buffer:
free( buffer );
@@ -176,7 +176,7 @@ cleanup_buffer:
}
-int blake2bp_stream( FILE *stream, void *resstream )
+int blake2bp_stream( FILE *stream, void *resstream, size_t outbytes )
{
int ret = -1;
size_t sum, n;
@@ -186,7 +186,7 @@ int blake2bp_stream( FILE *stream, void *resstream )
if( !buffer ) return -1;
- blake2bp_init( S, BLAKE2B_OUTBYTES );
+ blake2bp_init( S, outbytes );
while( 1 )
{
@@ -219,14 +219,14 @@ final_process:;
if( sum > 0 ) blake2bp_update( S, buffer, sum );
- blake2bp_final( S, resstream, BLAKE2B_OUTBYTES );
+ blake2bp_final( S, resstream, outbytes );
ret = 0;
cleanup_buffer:
free( buffer );
return ret;
}
-typedef int ( *blake2fn )( FILE *, void * );
+typedef int ( *blake2fn )( FILE *, void *, size_t );
static void usage( char **argv, int errcode )
@@ -238,6 +238,8 @@ static void usage( char **argv, int errcode )
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 );
@@ -247,8 +249,9 @@ static void usage( char **argv, int errcode )
int main( int argc, char **argv )
{
blake2fn blake2_stream = blake2b_stream;
- size_t outlen = BLAKE2B_OUTBYTES;
+ size_t maxbytes = BLAKE2B_OUTBYTES;
const char *algorithm = "BLAKE2b";
+ size_t outbytes = 0;
unsigned char hash[BLAKE2B_OUTBYTES] = {0};
bool bsdstyle = false;
int c;
@@ -258,13 +261,15 @@ int main( int argc, char **argv )
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
+ char *end = NULL;
+ size_t outbits;
static struct option long_options[] = {
{ "help", no_argument, 0, 0 },
{ "tag", no_argument, 0, 0 },
{ NULL, 0, NULL, 0 }
};
- c = getopt_long( argc, argv, "a:", long_options, &option_index );
+ c = getopt_long( argc, argv, "a:l:", long_options, &option_index );
if( c == -1 ) break;
switch( c )
{
@@ -272,25 +277,25 @@ int main( int argc, char **argv )
if( 0 == strcmp( optarg, "blake2b" ) )
{
blake2_stream = blake2b_stream;
- outlen = BLAKE2B_OUTBYTES;
+ maxbytes = BLAKE2B_OUTBYTES;
algorithm = "BLAKE2b";
}
else if ( 0 == strcmp( optarg, "blake2s" ) )
{
blake2_stream = blake2s_stream;
- outlen = BLAKE2S_OUTBYTES;
+ maxbytes = BLAKE2S_OUTBYTES;
algorithm = "BLAKE2s";
}
else if ( 0 == strcmp( optarg, "blake2bp" ) )
{
blake2_stream = blake2bp_stream;
- outlen = BLAKE2B_OUTBYTES;
+ maxbytes = BLAKE2B_OUTBYTES;
algorithm = "BLAKE2bp";
}
else if ( 0 == strcmp( optarg, "blake2sp" ) )
{
blake2_stream = blake2sp_stream;
- outlen = BLAKE2S_OUTBYTES;
+ maxbytes = BLAKE2S_OUTBYTES;
algorithm = "BLAKE2sp";
}
else
@@ -301,6 +306,16 @@ int main( int argc, char **argv )
break;
+ case 'l':
+ outbits = strtoul(optarg, &end, 10);
+ if( !end || *end != '\0' || outbits % 8 )
+ {
+ 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 );
@@ -314,6 +329,15 @@ int main( int argc, char **argv )
}
}
+ if(outbytes > maxbytes)
+ {
+ printf( "Invalid length argument: %zu\n", outbytes * 8 );
+ printf( "Maximum digest length for %s is %zu\n", algorithm, maxbytes * 8 );
+ usage( argv, 111 );
+ }
+ else if( outbytes == 0 )
+ outbytes = maxbytes;
+
if( optind == argc )
argv[argc++] = (char *) "-";
@@ -331,7 +355,7 @@ int main( int argc, char **argv )
continue;
}
- if( blake2_stream( f, hash ) < 0 )
+ if( blake2_stream( f, hash, outbytes ) < 0 )
{
fprintf( stderr, "Failed to hash `%s'\n", argv[i] );
}
@@ -339,10 +363,13 @@ int main( int argc, char **argv )
{
if( bsdstyle )
{
- printf( "%s (%s) = ", algorithm, argv[i] );
+ if( outbytes < maxbytes )
+ printf( "%s-%zu (%s) = ", algorithm, outbytes * 8, argv[i] );
+ else
+ printf( "%s (%s) = ", algorithm, argv[i] );
}
- for( size_t j = 0; j < outlen; ++j )
+ for( size_t j = 0; j < outbytes; ++j )
printf( "%02x", hash[j] );
if( bsdstyle )