aboutsummaryrefslogtreecommitdiff
path: root/sw/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'sw/hash.c')
-rw-r--r--sw/hash.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/sw/hash.c b/sw/hash.c
index 8b3bac2..d875225 100644
--- a/sw/hash.c
+++ b/sw/hash.c
@@ -64,23 +64,24 @@ int verbose = 0;
struct ctrl {
char *name;
+ off_t base_addr;
off_t block_addr;
int block_len;
off_t digest_addr;
int digest_len;
int mode;
} ctrl[] = {
- { "sha-1", SHA1_ADDR_BLOCK, SHA1_BLOCK_LEN,
+ { "sha-1", 0, SHA1_ADDR_BLOCK, SHA1_BLOCK_LEN,
SHA1_ADDR_DIGEST, SHA1_DIGEST_LEN, 0 },
- { "sha-256", SHA256_ADDR_BLOCK, SHA256_BLOCK_LEN,
+ { "sha-256", 0, SHA256_ADDR_BLOCK, SHA256_BLOCK_LEN,
SHA256_ADDR_DIGEST, SHA256_DIGEST_LEN, 0 },
- { "sha-512/224", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-512/224", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA512_224_DIGEST_LEN, MODE_SHA_512_224 },
- { "sha-512/256", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-512/256", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA512_256_DIGEST_LEN, MODE_SHA_512_256 },
- { "sha-384", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-384", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA384_DIGEST_LEN, MODE_SHA_384 },
- { "sha-512", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
+ { "sha-512", 0, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN,
SHA512_ADDR_DIGEST, SHA512_DIGEST_LEN, MODE_SHA_512 },
{ NULL, 0, 0, 0 }
};
@@ -99,24 +100,63 @@ struct ctrl *find_algo(char *algo)
return NULL;
}
+/* ---------------- startup code ---------------- */
+
+static int patch(char *name, off_t base_addr) {
+ struct ctrl *ctrl;
+
+ ctrl = find_algo(name);
+ if (ctrl == NULL)
+ return -1;
+
+ ctrl->base_addr = base_addr;
+ return 0;
+}
+
+static int inited = 0;
+
+static int init(void)
+{
+ struct core_info *core;
+
+ if (inited)
+ return 0;
+
+ for (core = tc_core_first("sha"); core; core = tc_core_next(core, "sha")) {
+ if (strncmp(core->name, SHA1_NAME0 SHA1_NAME1, 8) == 0)
+ patch("sha-1", core->base);
+ else if (strncmp(core->name, SHA256_NAME0 SHA256_NAME1, 8) == 0)
+ patch("sha-256", core->base);
+ else if (strncmp(core->name, SHA512_NAME0 SHA512_NAME1, 8) == 0) {
+ patch("sha-512/224", core->base);
+ patch("sha-512/256", core->base);
+ patch("sha-384", core->base);
+ patch("sha-512", core->base);
+ }
+ }
+
+ inited = 1;
+ return 0;
+}
+
/* ---------------- hash ---------------- */
-static int transmit(off_t offset, uint8_t *block, int blen, int mode, int first)
+static int transmit(off_t base, uint8_t *block, int blen, int mode, int first)
{
- off_t base = offset & ~(0x1ff);
uint8_t ctrl_cmd[4] = { 0 };
+ int limit = 10;
- if (tc_write(offset, block, blen) != 0)
+ if (tc_write(base + ADDR_BLOCK, block, blen) != 0)
return 1;
ctrl_cmd[3] = (first ? CTRL_INIT : CTRL_NEXT) | mode;
return
tc_write(base + ADDR_CTRL, ctrl_cmd, 4) ||
- tc_wait_ready(base + ADDR_STATUS);
+ tc_wait(base + ADDR_STATUS, STATUS_READY, &limit);
}
-static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen,
+static int pad_transmit(off_t base, uint8_t *block, uint8_t flen, uint8_t blen,
uint8_t mode, long long tlen, int first)
{
assert(flen < blen);
@@ -125,7 +165,7 @@ static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen
memset(block + flen, 0, blen - flen);
if (blen - flen < ((blen == 64) ? 8 : 16)) {
- if (transmit(offset, block, blen, mode, first) != 0)
+ if (transmit(base, block, blen, mode, first) != 0)
return 1;
first = 0;
memset(block, 0, blen);
@@ -137,7 +177,7 @@ static int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen
((uint32_t *)block)[blen/4 - 2] = htonl((tlen >> 32) & 0xffff);
((uint32_t *)block)[blen/4 - 1] = htonl(tlen & 0xffff);
- return transmit(offset, block, blen, mode, first);
+ return transmit(base, block, blen, mode, first);
}
/* return number of digest bytes read */
@@ -146,18 +186,26 @@ static int hash(char *algo, char *file, uint8_t *digest)
uint8_t block[SHA512_BLOCK_LEN];
struct ctrl *ctrl;
int in_fd = 0; /* stdin */
- off_t baddr, daddr;
+ off_t base, daddr;
int blen, dlen, mode;
int nblk, nread, first;
int ret = -1;
struct timeval start, stop, difftime;
+ if (init() != 0)
+ return -1;
+
ctrl = find_algo(algo);
if (ctrl == NULL)
return -1;
- baddr = ctrl->block_addr;
+ base = ctrl->base_addr;
+ if (base == 0) {
+ fprintf(stderr, "core for algorithm \"%s\" not installed\n", algo);
+ return -1;
+ }
+
blen = ctrl->block_len;
- daddr = ctrl->digest_addr;
+ daddr = ctrl->base_addr + ctrl->digest_addr;
dlen = ctrl->digest_len;
mode = ctrl->mode;
@@ -185,14 +233,14 @@ static int hash(char *algo, char *file, uint8_t *digest)
}
else if (nread < blen) {
/* partial read = last block */
- if (pad_transmit(baddr, block, nread, blen, mode,
+ if (pad_transmit(base, block, nread, blen, mode,
(nblk * blen + nread) * 8, first) != 0)
goto out;
break;
}
else {
/* full block read */
- if (transmit(baddr, block, blen, mode, first) != 0)
+ if (transmit(base, block, blen, mode, first) != 0)
goto out;
}
}