[PATCH 7/7] command: add generic digest command

Sascha Hauer s.hauer at pengutronix.de
Fri Mar 13 00:26:16 PDT 2015


On Thu, Mar 12, 2015 at 03:22:26PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> That can be used for digest calculation and verify
> 
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> ---
>  commands/Kconfig    |  12 +++-
>  commands/Makefile   |   1 +
>  commands/digest.c   | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  commands/hashsum.c  |  68 ++++--------------
>  commands/internal.h |   3 +
>  common/password.c   |  43 +-----------
>  crypto/digest.c     |  92 +++++++++++++++++++++++--
>  include/digest.h    |  13 +++-
>  8 files changed, 322 insertions(+), 105 deletions(-)
>  create mode 100644 commands/digest.c
>  create mode 100644 commands/internal.h
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 7e3e8b7..847ff76 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -14,7 +14,7 @@ if COMMAND_SUPPORT
>  
>  config COMPILE_HASH
>  	tristate
> -	select DIGEST
> +	select CMD_DIGEST
>  	help
>  	  Turns on compilation of digest.c
>  
> @@ -842,6 +842,16 @@ config CMD_CMP
>  
>  	  Returns successfully if the two files are the same, return with an error if not
>  
> +config CMD_DIGEST
> +	tristate
> +	select DIGEST
> +	prompt "digest"
> +	help
> +	  Usage: digest -a <algo> [-k <key> | -K <file>] [-s <sig> | -S <file>] FILE|AREA
> +
> +	  Calculate a digest over a FILE or a memory area with the possibility
> +	  to checkit.
> +
>  config CMD_DIRNAME
>  	tristate
>  	prompt "dirname"
> diff --git a/commands/Makefile b/commands/Makefile
> index e42662f..b902f58 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -1,4 +1,5 @@
>  obj-$(CONFIG_STDDEV)		+= stddev.o
> +obj-$(CONFIG_CMD_DIGEST)	+= digest.o
>  obj-$(CONFIG_COMPILE_HASH)	+= hashsum.o
>  obj-$(CONFIG_COMPILE_MEMORY)	+= mem.o
>  obj-$(CONFIG_CMD_BOOTM)		+= bootm.o
> diff --git a/commands/digest.c b/commands/digest.c
> new file mode 100644
> index 0000000..e9b4e66
> --- /dev/null
> +++ b/commands/digest.c
> @@ -0,0 +1,195 @@
> +/*
> + * Copyright (c) 2015 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> + *
> + * GPLv2 ONLY
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <fs.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +#include <xfuncs.h>
> +#include <malloc.h>
> +#include <digest.h>
> +#include <getopt.h>
> +#include <libfile.h>
> +
> +#include "internal.h"
> +
> +int __do_digest(struct digest *d, unsigned char *key, int keylen,
> +		       unsigned char *sig,
> +		       int argc, char *argv[])
> +{
> +	int ret = 0;
> +	int i;
> +	unsigned char *hash;
> +
> +	if (argc < 1)
> +		return COMMAND_ERROR_USAGE;
> +
> +	hash = calloc(digest_length(d), sizeof(unsigned char));
> +	if (!hash) {
> +		perror("calloc");
> +		return COMMAND_ERROR_USAGE;
> +	}
> +
> +	while (*argv) {
> +		char *filename = "/dev/mem";
> +		loff_t start = 0, size = ~0;
> +
> +		/* arguments are either file, file+area or area */
> +		if (parse_area_spec(*argv, &start, &size)) {
> +			filename = *argv;
> +			if (argv[1] && !parse_area_spec(argv[1], &start, &size))
> +				argv++;
> +		}
> +
> +		ret = digest_file_window(d, filename,
> +					 key, keylen,
> +					 hash, sig, start, size);
> +		if (ret < 0) {
> +			ret = 1;
> +		} else {
> +			if (!sig) {
> +				for (i = 0; i < digest_length(d); i++)
> +					printf("%02x", hash[i]);
> +
> +				printf("  %s\t0x%08llx ... 0x%08llx\n",
> +					filename, start, start + size);
> +			}
> +		}
> +
> +		argv++;
> +	}
> +
> +	free(hash);
> +	digest_free(d);
> +
> +	return ret;
> +}
> +
> +static void __prints_algo(void)
> +{
> +	puts("available algo:\n\n");
> +	digest_algo_prints("\t");
> +}
> +
> +static int do_digest(int argc, char *argv[])
> +{
> +	struct digest *d;
> +	unsigned char *tmp_key = NULL;
> +	unsigned char *tmp_sig = NULL;
> +	char *sig = NULL;
> +	char *sigfile = NULL;
> +	size_t siglen = 0;
> +	char *key = NULL;
> +	char *keyfile = NULL;
> +	size_t keylen = 0;
> +	size_t digestlen = 0;
> +	char *algo = NULL;
> +	int opt, ret;
> +
> +	if (argc < 2) {
> +		__prints_algo();
> +		return 0;
> +	}

This is an untuitive trigger to print the available algos. Can we add an
explicit option here?

> +
> +	while((opt = getopt(argc, argv, "a:k:K:s:S:")) > 0) {
> +		switch(opt) {
> +		case 'k':
> +			key = optarg;
> +			keylen = strlen(key);
> +			break;
> +		case 'K':
> +			keyfile = optarg;
> +			break;
> +		case 'a':
> +			algo = optarg;
> +			break;
> +		case 's':
> +			sig = optarg;
> +			siglen = strlen(sig);
> +			break;
> +		case 'S':
> +			sigfile = optarg;
> +			break;
> +		}
> +	}
> +
> +	if (!algo)
> +		return COMMAND_ERROR_USAGE;
> +
> +	d = digest_alloc(algo);
> +	if (!d) {
> +		eprintf("algo '%s' not found\n", algo);
> +		__prints_algo();
> +		return COMMAND_ERROR_USAGE;
> +	}
> +
> +	argc -= optind;
> +	argv += optind;
> +
> +	if (keyfile) {
> +		tmp_key = key = read_file(keyfile, &keylen);

Why two variables? Both tmp_key and key are never changed.

> +		if (!key) {
> +			eprintf("file '%s' not found\n", keyfile);
> +			goto err;
> +		}
> +	}
> +
> +	digest_set_key(d, key, keylen);

This can fail. You should check the error code.

> +unsigned char to_digit(unsigned char c)
> +{
> +	if (c >= '0' && c <= '9')
> +		c -= '0';
> +	else
> +		c -= 'a' - 10;
> +
> +	return c;
> +}
> +
> +unsigned char to_hexa(unsigned char c)
> +{
> +	if (c < 10)
> +		c += '0';
> +	else
> +		c += 'a' - 10;
> +
> +	return c;
> +}
> +
> +int base64_to_hex(const unsigned char *sum, unsigned char *buf, size_t length)
> +{

The ASCII input here contains hex digits, base64 is something different.
Also these functions are useful enough to be always available, not only
when digest is enabled.

I just sent a patch containing the kernels implementation of bin2hex and
hex2bin. Please base on this one.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



More information about the barebox mailing list