From f141a79d805acbab07876d9f007e8809603718b5 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 10 Jun 2015 12:30:58 -0400 Subject: generate core_selector, probe FPGA for cores at software startup --- sw/hash.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 18 deletions(-) (limited to 'sw/hash.c') 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; } } -- cgit v1.2.3