mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCHv2] commands: add md5/sha1/sha256sum commands using the digest api
@ 2011-05-17 20:05 Peter Korsgaard
  2011-05-18  5:08 ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Korsgaard @ 2011-05-17 20:05 UTC (permalink / raw)
  To: barebox, plagnioj, s.hauer

The interface emulates the Linux commands, except that you can
specify a sub area - E.G.:

barebox:/ md5sum /dev/fd0 2M+1M /env/config /env/bin/boot 10+2
61c4c0180b044191d28f27545f43562f  /dev/fd0	0x00200000 ... 0x00300000
908b84bcbadd2f263583a65ff31d1cad  /env/config	0x00000000 ... 0x000003a7
f23bd15825cc5006cf5f9fd486d82d2d  /env/bin/boot	0x0000000a ... 0x0000000c

Adds around 1400 bytes (+ size of digest code) with everything enabled.

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
 Changes since v1:
 - handle ctrlc
 - continue on errors
 - use wrapper functions rather than strstr for algorithm name

 commands/Kconfig  |   22 ++++++
 commands/Makefile |    1 +
 commands/digest.c |  193 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 216 insertions(+), 0 deletions(-)
 create mode 100644 commands/digest.c

diff --git a/commands/Kconfig b/commands/Kconfig
index f192d30..30eeff9 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -222,6 +222,28 @@ config CMD_CRC_CMP
 	depends on CMD_CRC
 	prompt "compare 2 files crc"
 
+config CMD_DIGEST
+       tristate
+       select DIGEST
+
+config CMD_MD5SUM
+	tristate
+	select CMD_DIGEST
+	select MD5
+	prompt "md5sum"
+
+config CMD_SHA1SUM
+	tristate
+	select CMD_DIGEST
+	select SHA1
+	prompt "sha1sum"
+
+config CMD_SHA256SUM
+	tristate
+	select CMD_DIGEST
+	select SHA256
+	prompt "sha256sum"
+
 config CMD_MTEST
 	tristate
 	prompt "mtest"
diff --git a/commands/Makefile b/commands/Makefile
index f7ef9a8..8ee4aba 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_CMD_MOUNT)		+= mount.o
 obj-$(CONFIG_CMD_UMOUNT)	+= umount.o
 obj-$(CONFIG_CMD_REGINFO)	+= reginfo.o
 obj-$(CONFIG_CMD_CRC)		+= crc.o
+obj-$(CONFIG_CMD_DIGEST)	+= digest.o
 obj-$(CONFIG_CMD_CLEAR)		+= clear.o
 obj-$(CONFIG_CMD_TEST)		+= test.o
 obj-$(CONFIG_CMD_FLASH)		+= flash.o
diff --git a/commands/digest.c b/commands/digest.c
new file mode 100644
index 0000000..7bc02bc
--- /dev/null
+++ b/commands/digest.c
@@ -0,0 +1,193 @@
+/*
+ * digest.c - Calculate a md5/sha1/sha256 checksum of a memory area
+ *
+ * Copyright (c) 2011 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <xfuncs.h>
+#include <malloc.h>
+#include <digest.h>
+
+static void print_digest(struct digest *d)
+{
+	unsigned char *data;
+	int i;
+
+	data = xmalloc(d->length);
+	d->final(d, data);
+
+	for (i=0; i<d->length; i++)
+		printf("%02x", data[i]);
+
+	free(data);
+}
+
+static int file_digest(struct digest *d, char *filename,
+		       ulong start, ulong size)
+{
+	ulong len = 0;
+	int fd, now, ret = 0;
+	char *buf;
+
+	d->init(d);
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		perror(filename);
+		return fd;
+	}
+
+	if (start > 0) {
+		ret = lseek(fd, start, SEEK_SET);
+		if (ret == -1) {
+			perror("lseek");
+			goto out;
+		}
+	}
+
+	buf = xmalloc(4096);
+
+	while (size) {
+		now = min((ulong)4096, size);
+		now = read(fd, buf, now);
+		if (now < 0) {
+			ret = now;
+			perror("read");
+			goto out_free;
+		}
+		if (!now)
+			break;
+
+		if (ctrlc()) {
+			ret = -EINTR;
+			goto out_free;
+		}
+
+		d->update(d, buf, now);
+		size -= now;
+		len += now;
+	}
+
+	print_digest(d);
+	printf("  %s\t0x%08lx ... 0x%08lx\n", filename, start, start + len);
+
+out_free:
+	free(buf);
+out:
+	close(fd);
+
+	return ret;
+}
+
+static int do_digest(char *algorithm, int argc, char *argv[])
+{
+	struct digest *d;
+	int ret = 0;
+
+	d = digest_get_by_name(algorithm);
+	BUG_ON(!d);
+
+	if (argc < 2)
+		return COMMAND_ERROR_USAGE;
+
+	argv++;
+	while (*argv) {
+		char *filename = "/dev/mem";
+		ulong 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++;
+		}
+
+		if (file_digest(d, filename, start, size) < 0)
+			ret = 1;
+
+		argv++;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_CMD_MD5SUM
+
+static int do_md5(struct command *cmdtp, int argc, char *argv[])
+{
+	return do_digest("md5", argc, argv);
+}
+
+BAREBOX_CMD_HELP_START(md5sum)
+BAREBOX_CMD_HELP_USAGE("md5sum [[FILE] [AREA]]...\n")
+BAREBOX_CMD_HELP_SHORT("Calculate a md5 checksum of a memory area.\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(md5sum)
+	.cmd		= do_md5,
+	.usage		= "md5 checksum calculation",
+	BAREBOX_CMD_HELP(cmd_md5sum_help)
+BAREBOX_CMD_END
+
+#endif /* CMD_CMD_MD5SUM */
+
+#ifdef CONFIG_CMD_SHA1SUM
+
+static int do_sha1(struct command *cmdtp, int argc, char *argv[])
+{
+	return do_digest("sha1", argc, argv);
+}
+
+BAREBOX_CMD_HELP_START(sha1sum)
+BAREBOX_CMD_HELP_USAGE("sha1sum [[FILE] [AREA]]...\n")
+BAREBOX_CMD_HELP_SHORT("Calculate a sha1 checksum of a memory area.\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(sha1sum)
+	.cmd		= do_sha1,
+	.usage		= "sha1 checksum calculation",
+	BAREBOX_CMD_HELP(cmd_sha1sum_help)
+BAREBOX_CMD_END
+
+#endif /* CMD_CMD_SHA1SUM */
+
+#ifdef CONFIG_CMD_SHA256SUM
+
+static int do_sha256(struct command *cmdtp, int argc, char *argv[])
+{
+	return do_digest("sha256", argc, argv);
+}
+
+BAREBOX_CMD_HELP_START(sha256sum)
+BAREBOX_CMD_HELP_USAGE("sha256sum [[FILE] [AREA]]...\n")
+BAREBOX_CMD_HELP_SHORT("Calculate a sha256 checksum of a memory area.\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(sha256sum)
+	.cmd		= do_sha256,
+	.usage		= "sha256 checksum calculation",
+	BAREBOX_CMD_HELP(cmd_sha256sum_help)
+BAREBOX_CMD_END
+
+#endif /* CMD_CMD_SHA256SUM */
-- 
1.7.4.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv2] commands: add md5/sha1/sha256sum commands using the digest api
  2011-05-17 20:05 [PATCHv2] commands: add md5/sha1/sha256sum commands using the digest api Peter Korsgaard
@ 2011-05-18  5:08 ` Jean-Christophe PLAGNIOL-VILLARD
  2011-05-18  7:12   ` Peter Korsgaard
  0 siblings, 1 reply; 4+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-05-18  5:08 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: barebox

> +
> +	data = xmalloc(d->length);
we realloc a buffer here where we alloc one in file_digest
and not free it before calling print_digest
> +	d->final(d, data);
> +
> +	for (i=0; i<d->length; i++)
> +		printf("%02x", data[i]);
> +
> +	free(data);
> +}
> +
> +static int file_digest(struct digest *d, char *filename,
> +		       ulong start, ulong size)
> +{
> +	ulong len = 0;
> +	int fd, now, ret = 0;
> +	char *buf;
> +
> +	d->init(d);
> +
> +	fd = open(filename, O_RDONLY);
> +	if (fd < 0) {
> +		perror(filename);
> +		return fd;
> +	}
> +
> +	if (start > 0) {
> +		ret = lseek(fd, start, SEEK_SET);
> +		if (ret == -1) {
> +			perror("lseek");
> +			goto out;
> +		}
> +	}
> +
> +	buf = xmalloc(4096);
do we really need to allocate the buffer everytime?
> +
> +	while (size) {
> +		now = min((ulong)4096, size);
> +		now = read(fd, buf, now);
> +		if (now < 0) {
> +			ret = now;
> +			perror("read");
> +			goto out_free;
> +		}
> +		if (!now)
> +			break;
> +
> +		if (ctrlc()) {
> +			ret = -EINTR;
> +			goto out_free;
> +		}
> +
> +		d->update(d, buf, now);
> +		size -= now;
> +		len += now;
> +	}
> +
> +	print_digest(d);
> +	printf("  %s\t0x%08lx ... 0x%08lx\n", filename, start, start + len);
> +
> +out_free:
> +	free(buf);
> +out:
> +	close(fd);
> +
> +	return ret;
> +}
> +
> +static int do_digest(char *algorithm, int argc, char *argv[])
> +{
> +	struct digest *d;
> +	int ret = 0;
> +
> +	d = digest_get_by_name(algorithm);
> +	BUG_ON(!d);
> +
> +	if (argc < 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	argv++;
> +	while (*argv) {
> +		char *filename = "/dev/mem";
> +		ulong start = 0, size = ~0;
		ulong so so if we want to support 64bit vfs we need to use an
		other type
> +
> +		/* 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++;
> +		}
> +
> +		if (file_digest(d, filename, start, size) < 0)
> +			ret = 1;
> +
> +		argv++;
> +	}
> +
> +	return ret;
> +}
> +
> +#ifdef CONFIG_CMD_MD5SUM
> +
> +static int do_md5(struct command *cmdtp, int argc, char *argv[])
> +{
> +	return do_digest("md5", argc, argv);
pass the cmdtp will be good
I agree it's not necessary now but I think it's a good practice

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv2] commands: add md5/sha1/sha256sum commands using the digest api
  2011-05-18  5:08 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2011-05-18  7:12   ` Peter Korsgaard
  2011-05-18  7:50     ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 4+ messages in thread
From: Peter Korsgaard @ 2011-05-18  7:12 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox

>>>>> "Jean-Christophe" == Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> writes:

Hi,

 >> +
 >> +	data = xmalloc(d->length);

 Jean-Christophe> we realloc a buffer here where we alloc one in file_digest
 Jean-Christophe> and not free it before calling print_digest

I'm not exactly sure what you mean, but yes - We could inline
print_digest in file_digest and reuse the 4K buf for the digest as
well. That would shrink the code slightly (lines / bytes) and get rid of
the 2nd xmalloc.

I'll fix that and send a v3 shortly.

 >> +	buf = xmalloc(4096);

 Jean-Christophe> do we really need to allocate the buffer everytime?

Not really, but it's simpler to do like this. It's only once per file so
hardly a performance issue.

 >> +	while (*argv) {
 >> +		char *filename = "/dev/mem";
 >> +		ulong start = 0, size = ~0;

 Jean-Christophe> ulong so so if we want to support 64bit vfs we need to
 Jean-Christophe> use an other type

ulong is what parse_area_spec and the other memory commands use.

 >> +#ifdef CONFIG_CMD_MD5SUM
 >> +
 >> +static int do_md5(struct command *cmdtp, int argc, char *argv[])
 >> +{
 >> +	return do_digest("md5", argc, argv);

 Jean-Christophe> pass the cmdtp will be good
 Jean-Christophe> I agree it's not necessary now but I think it's a good
 Jean-Christophe> practice

I think it makes more sense to add it when (if?) it is needed.

-- 
Bye, Peter Korsgaard

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv2] commands: add md5/sha1/sha256sum commands using the digest api
  2011-05-18  7:12   ` Peter Korsgaard
@ 2011-05-18  7:50     ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 4+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-05-18  7:50 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: barebox

 
>  >> +	buf = xmalloc(4096);
> 
>  Jean-Christophe> do we really need to allocate the buffer everytime?
> 
> Not really, but it's simpler to do like this. It's only once per file so
> hardly a performance issue.
> 
>  >> +	while (*argv) {
>  >> +		char *filename = "/dev/mem";
>  >> +		ulong start = 0, size = ~0;
> 
>  Jean-Christophe> ulong so so if we want to support 64bit vfs we need to
>  Jean-Christophe> use an other type
> 
> ulong is what parse_area_spec and the other memory commands use.
Just note that the file size could be more than 32bit
and uze size_t or ssize_t make more sense in my mind
of we can use loff_t

Best Regards,
J.

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-05-18  8:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-17 20:05 [PATCHv2] commands: add md5/sha1/sha256sum commands using the digest api Peter Korsgaard
2011-05-18  5:08 ` Jean-Christophe PLAGNIOL-VILLARD
2011-05-18  7:12   ` Peter Korsgaard
2011-05-18  7:50     ` Jean-Christophe PLAGNIOL-VILLARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox