summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Smirnov <andrew.smirnov@gmail.com>2019-01-12 00:24:54 -0800
committerSascha Hauer <s.hauer@pengutronix.de>2019-01-16 08:33:34 +0100
commitb77582effd360f15da2a42c2ad3c45f8cbc6dba9 (patch)
treeb6401f3d26c3c317c9deaa53b65132d2eaa69a25
parent23c9657eb120019097b364820bc17bac5d172d12 (diff)
downloadbarebox-b77582effd360f15da2a42c2ad3c45f8cbc6dba9.tar.gz
barebox-b77582effd360f15da2a42c2ad3c45f8cbc6dba9.tar.xz
crypto: digest: Split memory vs. file code into separate functions
Instead of trying to fit two rather different cases into a single loop, split digesting memory and digesting files into separate subroutines. While duplicating some of the code shared by both of the while() loops this makes the body of the loop easier to follow as well as gets rid of poorly named "flags" variable. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--crypto/digest.c118
1 files changed, 70 insertions, 48 deletions
diff --git a/crypto/digest.c b/crypto/digest.c
index 980a694915..7b34742c52 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -211,14 +211,76 @@ void digest_free(struct digest *d)
}
EXPORT_SYMBOL_GPL(digest_free);
+static int digest_update_interruptible(struct digest *d, const void *data,
+ unsigned long len)
+{
+ if (ctrlc())
+ return -EINTR;
+
+ return digest_update(d, data, len);
+}
+
+static int digest_update_from_fd(struct digest *d, int fd,
+ ulong start, ulong size)
+{
+ unsigned char *buf = xmalloc(PAGE_SIZE);
+ int ret = 0;
+
+ ret = lseek(fd, start, SEEK_SET);
+ if (ret == -1) {
+ perror("lseek");
+ goto out_free;
+ }
+
+ while (size) {
+ const ssize_t now = read(fd, buf, PAGE_SIZE);
+ if (now < 0) {
+ ret = now;
+ perror("read");
+ goto out_free;
+ }
+
+ if (!now)
+ break;
+
+ ret = digest_update_interruptible(d, buf, now);
+ if (ret)
+ goto out_free;
+
+ size -= now;
+ }
+
+out_free:
+ free(buf);
+ return ret;
+}
+
+static int digest_update_from_memory(struct digest *d,
+ const unsigned char *buf,
+ ulong size)
+{
+ while (size) {
+ unsigned long now = min_t(typeof(size), PAGE_SIZE, size);
+ int ret;
+
+ ret = digest_update_interruptible(d, buf, now);
+ if (ret)
+ return ret;
+
+ size -= now;
+ buf += now;
+ }
+
+ return 0;
+}
+
int digest_file_window(struct digest *d, const char *filename,
unsigned char *hash,
const unsigned char *sig,
ulong start, ulong size)
{
- int fd, now, ret = 0;
+ int fd, ret;
unsigned char *buf;
- int flags = 0;
ret = digest_init(d);
if (ret)
@@ -231,58 +293,18 @@ int digest_file_window(struct digest *d, const char *filename,
}
buf = memmap(fd, PROT_READ);
- if (buf == MAP_FAILED) {
- buf = xmalloc(PAGE_SIZE);
- flags = 1;
- }
-
- if (start > 0) {
- if (flags) {
- ret = lseek(fd, start, SEEK_SET);
- if (ret == -1) {
- perror("lseek");
- goto out;
- }
- } else {
- buf += start;
- }
- }
-
- while (size) {
- now = min((ulong)PAGE_SIZE, size);
- if (flags) {
- 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;
- }
-
- ret = digest_update(d, buf, now);
- if (ret)
- goto out_free;
- size -= now;
+ if (buf == MAP_FAILED)
+ ret = digest_update_from_fd(d, fd, start, size);
+ else
+ ret = digest_update_from_memory(d, buf + start, size);
- if (!flags)
- buf += now;
- }
+ if (ret)
+ goto out;
if (sig)
ret = digest_verify(d, sig);
else
ret = digest_final(d, hash);
-
-out_free:
- if (flags)
- free(buf);
out:
close(fd);