[Cryptech-Commits] [core/novena] 02/04: do proper SHA* padding

git at cryptech.is git at cryptech.is
Thu Nov 20 00:11:51 UTC 2014


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository core/novena.

commit c0153c65d55f7b47dc6e94a3ce7b33daec95592d
Author: Paul Selkirk <paul at psgd.org>
Date:   Tue Nov 18 15:21:20 2014 -0500

    do proper SHA* padding
---
 src/sw/hash.c               | 148 +++++++++++++++++++++++++++-----------------
 src/sw/nist_1024_double.bin | Bin 256 -> 112 bytes
 src/sw/nist_1024_single.bin | Bin 128 -> 3 bytes
 src/sw/nist_512_double.bin  | Bin 128 -> 56 bytes
 src/sw/nist_512_single.bin  | Bin 64 -> 3 bytes
 5 files changed, 91 insertions(+), 57 deletions(-)

diff --git a/src/sw/hash.c b/src/sw/hash.c
index f67a863..29110eb 100644
--- a/src/sw/hash.c
+++ b/src/sw/hash.c
@@ -47,6 +47,7 @@
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
 #include <ctype.h>
+#include <assert.h>
 
 char *usage = 
 "Usage: %s [-d] [-v] [-q] [-i I2C_device] [-a I2C_addr] [algorithm [file]]\n"
@@ -84,30 +85,33 @@ char *usage =
 #define STATUS_VALID_BIT        1
 
 /* addresses and codes for the specific hash cores */
-/* block and digest lengths are number of 32-bit words */
+/* block and digest lengths are number of bytes */
 #define SHA1_ADDR_PREFIX        0x10
 #define SHA1_ADDR_BLOCK         0x10
-#define SHA1_BLOCK_LEN          16
+#define SHA1_BLOCK_LEN          512/8
 #define SHA1_ADDR_DIGEST        0x20
-#define SHA1_DIGEST_LEN         5
+#define SHA1_DIGEST_LEN         160/8
 
 #define SHA256_ADDR_PREFIX      0x20
 #define SHA256_ADDR_BLOCK       0x10
-#define SHA256_BLOCK_LEN        16
+#define SHA256_BLOCK_LEN        512/8
 #define SHA256_ADDR_DIGEST      0x20
-#define SHA256_DIGEST_LEN       8
+#define SHA256_DIGEST_LEN       256/8
 
 #define SHA512_ADDR_PREFIX      0x30
 #define SHA512_CTRL_MODE_LOW    2
 #define SHA512_CTRL_MODE_HIGH   3
 #define SHA512_ADDR_BLOCK       0x10
-#define SHA512_BLOCK_LEN        32
+#define SHA512_BLOCK_LEN        1024/8
 #define SHA512_ADDR_DIGEST      0x40
-#define SHA512_DIGEST_LEN       16
-#define MODE_SHA_512_224        0
-#define MODE_SHA_512_256        1
-#define MODE_SHA_384            2
-#define MODE_SHA_512            3
+#define SHA512_224_DIGEST_LEN   224/8
+#define SHA512_256_DIGEST_LEN   256/8
+#define SHA384_DIGEST_LEN       384/8
+#define SHA512_DIGEST_LEN       512/8
+#define MODE_SHA512_224         0
+#define MODE_SHA512_256         1
+#define MODE_SHA384             2
+#define MODE_SHA512             3
 
 int i2cfd;
 int debug = 0;
@@ -129,13 +133,13 @@ struct ctrl {
     { "sha-256",     SHA256_ADDR_PREFIX, SHA256_ADDR_BLOCK, SHA256_BLOCK_LEN,
                      SHA256_ADDR_DIGEST, SHA256_DIGEST_LEN, 0 },
     { "sha-512/224", SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
-                     SHA512_ADDR_DIGEST, 7, MODE_SHA_512_224 },
+                     SHA512_ADDR_DIGEST, SHA512_224_DIGEST_LEN, MODE_SHA512_224 },
     { "sha-512/256", SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
-                     SHA512_ADDR_DIGEST, 8, MODE_SHA_512_256 },
+                     SHA512_ADDR_DIGEST, SHA512_256_DIGEST_LEN, MODE_SHA512_256 },
     { "sha-384",     SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
-                     SHA512_ADDR_DIGEST, 12, MODE_SHA_384 },
+                     SHA512_ADDR_DIGEST, SHA384_DIGEST_LEN, MODE_SHA384 },
     { "sha-512",     SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
-                     SHA512_ADDR_DIGEST, 16, MODE_SHA_512 },
+                     SHA512_ADDR_DIGEST, SHA512_DIGEST_LEN, MODE_SHA512 },
     { NULL, 0, 0, 0 }
 };
 
@@ -157,8 +161,6 @@ struct ctrl *find_algo(char *algo)
 
 int i2c_open(char *dev, int addr)
 {
-    if (debug) printf("i2c_open(%s, %d)\n", dev, addr);
-
     i2cfd = open(dev, O_RDWR);
     if (i2cfd < 0) {
         fprintf(stderr, "Unable to open %s: ", dev);
@@ -376,7 +378,7 @@ int tc_write_block(uint8_t addr0, uint8_t addr1, uint8_t *buf, int len)
 {
     int i;
 
-    for (i = 0; i < len; ++i) {
+    for (i = 0; i < len/4; ++i) {
         if (tc_write(addr0, addr1 + i, &buf[i*4]) != 0)
             return 1;
     }
@@ -388,7 +390,7 @@ int tc_read_digest(uint8_t addr0, uint8_t addr1, uint8_t *buf, int len)
 {
     int i;
 
-    for (i = 0; i < len; ++i) {
+    for (i = 0; i < len/4; ++i) {
         if (tc_read(addr0, addr1 + i, &buf[i*4]) != 0)
             return 1;
     }
@@ -398,19 +400,71 @@ int tc_read_digest(uint8_t addr0, uint8_t addr1, uint8_t *buf, int len)
 
 /* ---------------- hash ---------------- */
 
+int transmit(uint8_t *block, uint8_t blen, uint8_t addr0, uint8_t baddr,
+             uint8_t mode, int first)
+{
+    int i;
+
+    if (debug) {
+        printf("write [");
+        for (i = 0; i < blen; ++i)
+            printf(" %02x", block[i]);
+        printf(" ]\n");
+    }
+
+    if (tc_write_block(addr0, baddr, block, blen) != 0) {
+        return 1;
+    }
+    if (first) {
+        if (tc_init(addr0, mode) != 0)
+            return 1;
+    }
+    else {
+        if (tc_next(addr0, mode) != 0)
+            return 1;
+    }
+    if (tc_wait_ready(addr0) != 0)
+        return 1;
+
+    return 0;
+}
+
+int pad_transmit(uint8_t *block, uint8_t flen, uint8_t blen,
+                 uint8_t addr0, uint8_t baddr, uint8_t mode,
+                 long long tlen, int first)
+{
+    assert(flen < blen);
+
+    block[flen++] = 0x80;
+    memset(block + flen, 0, blen - flen);
+
+    if (blen - flen < ((blen == 64) ? 8 : 16)) {
+        if (transmit(block, blen, addr0, baddr, mode, first) != 0)
+            return 1;
+        first = 0;
+        memset(block, 0, blen);
+    }
+
+    /* properly the length is 128 bits for sha-512, but we can't
+     * actually count above 64 bits
+     */
+    ((uint32_t *)block)[blen/4 - 2] = htonl((tlen >> 32) & 0xffff);
+    ((uint32_t *)block)[blen/4 - 1] = htonl(tlen & 0xffff);
+
+    return transmit(block, blen, addr0, baddr, mode, first);
+}
+
 /* return number of digest bytes read */
 int hash(char *algo, char *file, uint8_t *digest)
 {
-    uint8_t block[SHA512_BLOCK_LEN * 4];
+    uint8_t block[SHA512_BLOCK_LEN];
     struct ctrl *ctrl;
     int in_fd = 0;      /* stdin */
     uint8_t addr0, baddr, blen, daddr, dlen, mode;
     int nblk, nread, first;
-    int i, ret = -1;
+    int ret = -1;
     struct timeval start, stop, difftime;
 
-    if (debug) printf("hash(algo=%s, file=%s, digest=%p)\n", algo, file, digest);
-
     ctrl = find_algo(algo);
     if (ctrl == NULL)
         return -1;
@@ -436,49 +490,29 @@ int hash(char *algo, char *file, uint8_t *digest)
         }
     }
 
-    for (nblk = 0, first = 1; ; ++nblk) {
-        nread = read(in_fd, block, blen * 4);
-        if (nread != blen * 4) {
-            if (nread < 0) {
-                /* read error */
-                perror("read");
-                goto out;
-            }
-            else if (nread == 0) {
-                /* EOF */
-                break;
-            }
-            else {
-                /* partial read - pad the block with 0 */
-                while (nread < blen * 4) {
-                    block[nread++] = 0;
-                }
-            }
-        }
-        if (debug) {
-            printf("write [");
-            for (i = 0; i < blen * 4; ++i)
-                printf(" %02x", block[i]);
-            printf(" ]\n");
-        }
-        if (tc_write_block(addr0, baddr, block, blen) != 0) {
+    for (nblk = 0, first = 1; ; ++nblk, first = 0) {
+        nread = read(in_fd, block, blen);
+        if (nread < 0) {
+            /* read error */
+            perror("read");
             goto out;
         }
-        if (first) {
-            first = 0;
-            if (tc_init(addr0, mode) != 0)
+        else if (nread < blen) {
+            /* partial read = last block */
+            if (pad_transmit(block, nread, blen, addr0, baddr, mode,
+                             (nblk * blen + nread) * 8, first) != 0)
                 goto out;
+            break;
         }
         else {
-            if (tc_next(addr0, mode) != 0)
+            /* full block read */
+            if (transmit(block, blen, addr0, baddr, mode, first) != 0)
                 goto out;
         }
-        if (tc_wait_ready(addr0) != 0)
-            goto out;
     }
 
     if (tc_wait_valid(addr0) != 0)
-	goto out;
+        goto out;
     if (tc_read_digest(addr0, daddr, digest, dlen) != 0) {
         perror("i2c read failed");
         goto out;
@@ -495,7 +529,7 @@ int hash(char *algo, char *file, uint8_t *digest)
                (float)nblk / ((float)difftime.tv_sec + ((float)difftime.tv_usec)/1000000));
     }
 
-    ret = dlen * 4;
+    ret = dlen;
 out:
     if (in_fd != 0)
         close(in_fd);
diff --git a/src/sw/nist_1024_double.bin b/src/sw/nist_1024_double.bin
index 543b415..4674ea4 100644
Binary files a/src/sw/nist_1024_double.bin and b/src/sw/nist_1024_double.bin differ
diff --git a/src/sw/nist_1024_single.bin b/src/sw/nist_1024_single.bin
index 100111a..f2ba8f8 100644
Binary files a/src/sw/nist_1024_single.bin and b/src/sw/nist_1024_single.bin differ
diff --git a/src/sw/nist_512_double.bin b/src/sw/nist_512_double.bin
index ac8d755..199f24e 100644
Binary files a/src/sw/nist_512_double.bin and b/src/sw/nist_512_double.bin differ
diff --git a/src/sw/nist_512_single.bin b/src/sw/nist_512_single.bin
index 1f3a5ce..f2ba8f8 100644
Binary files a/src/sw/nist_512_single.bin and b/src/sw/nist_512_single.bin differ



More information about the Commits mailing list