* [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