From 283bfbeeb7fb5767815c10ea98bb155638d4bfb3 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Tue, 17 Mar 2015 13:49:30 +0100 Subject: Rearrange cores. --- src/sw/hash.c | 620 ---------------------------------------------------------- 1 file changed, 620 deletions(-) delete mode 100644 src/sw/hash.c (limited to 'src/sw/hash.c') diff --git a/src/sw/hash.c b/src/sw/hash.c deleted file mode 100644 index 29110eb..0000000 --- a/src/sw/hash.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * hash.c - * ------ - * This program uses the coretest_hashes subsystem to produce a - * cryptographic hash of a file or input stream. It is a generalization - * of the hash_tester.c test program. - * - * Authors: Joachim Strömbergson, Paul Selkirk - * Copyright (c) 2014, SUNET - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *usage = -"Usage: %s [-d] [-v] [-q] [-i I2C_device] [-a I2C_addr] [algorithm [file]]\n" -"algorithms: sha-1, sha-256, sha-512/224, sha-512/256, sha-384, sha-512\n"; - -/* I2C configuration */ -#define I2C_dev "/dev/i2c-2" -#define I2C_addr 0x0f - -/* command codes */ -#define SOC 0x55 -#define EOC 0xaa -#define READ_CMD 0x10 -#define WRITE_CMD 0x11 -#define RESET_CMD 0x01 - -/* response codes */ -#define SOR 0xaa -#define EOR 0x55 -#define READ_OK 0x7f -#define WRITE_OK 0x7e -#define RESET_OK 0x7d -#define UNKNOWN 0xfe -#define ERROR 0xfd - -/* addresses and codes common to all hash cores */ -#define ADDR_NAME0 0x00 -#define ADDR_NAME1 0x01 -#define ADDR_VERSION 0x02 -#define ADDR_CTRL 0x08 -#define CTRL_INIT_CMD 1 -#define CTRL_NEXT_CMD 2 -#define ADDR_STATUS 0x09 -#define STATUS_READY_BIT 0 -#define STATUS_VALID_BIT 1 - -/* addresses and codes for the specific hash cores */ -/* block and digest lengths are number of bytes */ -#define SHA1_ADDR_PREFIX 0x10 -#define SHA1_ADDR_BLOCK 0x10 -#define SHA1_BLOCK_LEN 512/8 -#define SHA1_ADDR_DIGEST 0x20 -#define SHA1_DIGEST_LEN 160/8 - -#define SHA256_ADDR_PREFIX 0x20 -#define SHA256_ADDR_BLOCK 0x10 -#define SHA256_BLOCK_LEN 512/8 -#define SHA256_ADDR_DIGEST 0x20 -#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 1024/8 -#define SHA512_ADDR_DIGEST 0x40 -#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; -int verbose = 0; - -/* ---------------- algorithm lookup code ---------------- */ - -struct ctrl { - char *name; - uint8_t addr_prefix; - uint8_t addr_block; - uint8_t block_len; - uint8_t addr_digest; - uint8_t digest_len; - uint8_t mode; -} ctrl[] = { - { "sha-1", SHA1_ADDR_PREFIX, SHA1_ADDR_BLOCK, SHA1_BLOCK_LEN, - SHA1_ADDR_DIGEST, SHA1_DIGEST_LEN, 0 }, - { "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, SHA512_224_DIGEST_LEN, MODE_SHA512_224 }, - { "sha-512/256", SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN, - SHA512_ADDR_DIGEST, SHA512_256_DIGEST_LEN, MODE_SHA512_256 }, - { "sha-384", SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN, - SHA512_ADDR_DIGEST, SHA384_DIGEST_LEN, MODE_SHA384 }, - { "sha-512", SHA512_ADDR_PREFIX, SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN, - SHA512_ADDR_DIGEST, SHA512_DIGEST_LEN, MODE_SHA512 }, - { NULL, 0, 0, 0 } -}; - -/* return the control structure for the given algorithm */ -struct ctrl *find_algo(char *algo) -{ - int i; - - for (i = 0; ctrl[i].name != NULL; ++i) - if (strcmp(ctrl[i].name, algo) == 0) - return &ctrl[i]; - - fprintf(stderr, "algorithm \"%s\" not found\n\n", algo); - fprintf(stderr, usage, "hash"); - return NULL; -} - -/* ---------------- I2C low-level code ---------------- */ - -int i2c_open(char *dev, int addr) -{ - i2cfd = open(dev, O_RDWR); - if (i2cfd < 0) { - fprintf(stderr, "Unable to open %s: ", dev); - perror(""); - i2cfd = 0; - return 1; - } - - if (ioctl(i2cfd, I2C_SLAVE, addr) < 0) { - fprintf(stderr, "Unable to set I2C slave device 0x%02x: ", addr); - perror(""); - return 1; - } - - return 0; -} - -void i2c_close(void) -{ - close(i2cfd); -} - -int i2c_write(uint8_t *buf, int len) -{ - if (debug) { - int i; - printf("write ["); - for (i = 0; i < len; ++i) - printf(" %02x", buf[i]); - printf(" ]\n"); - } - - if (write(i2cfd, buf, len) != len) { - perror("i2c write failed"); - return 1; - } - - return 0; -} - -int i2c_read(uint8_t *b) -{ - /* read() on the i2c device only returns one byte at a time, - * and tc_get_resp() needs to parse the response one byte at a time - */ - if (read(i2cfd, b, 1) != 1) { - perror("i2c read failed"); - return 1; - } - - return 0; -} - -/* ---------------- test-case low-level code ---------------- */ - -int tc_send_write_cmd(uint8_t addr0, uint8_t addr1, uint8_t *data) -{ - uint8_t buf[9] = { SOC, WRITE_CMD, addr0, addr1, - data[0], data[1], data[2], data[3], EOC }; - - return i2c_write(buf, sizeof(buf)); -} - -int tc_send_read_cmd(uint8_t addr0, uint8_t addr1) -{ - uint8_t buf[5] = { SOC, READ_CMD, addr0, addr1, EOC }; - - return i2c_write(buf, sizeof(buf)); -} - -int tc_get_resp(uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; ++i) { - if (i2c_read(&buf[i]) != 0) - return 1; - if ((i == 0) && (buf[i] != SOR)) { - /* we've gotten out of sync, and there's probably nothing we can do */ - fprintf(stderr, "response byte 0: expected 0x%02x (SOR), got 0x%02x\n", - SOR, buf[0]); - return 1; - } - else if (i == 1) { /* response code */ - switch (buf[i]) { - case READ_OK: - len = 9; - break; - case WRITE_OK: - len = 5; - break; - case RESET_OK: - len = 3; - break; - case ERROR: - case UNKNOWN: - len = 4; - break; - default: - /* we've gotten out of sync, and there's probably nothing we can do */ - fprintf(stderr, "unknown response code 0x%02x\n", buf[i]); - return 1; - } - } - } - - if (debug) { - printf("read ["); - for (i = 0; i < len; ++i) - printf(" %02x", buf[i]); - printf(" ]\n"); - } - - return 0; -} - -int tc_compare(uint8_t *buf, uint8_t *expected, int len) -{ - int i; - - /* start at byte 1 because SOR has already been tested */ - for (i = 1; i < len; ++i) { - if (buf[i] != expected[i]) { - fprintf(stderr, "response byte %d: expected 0x%02x, got 0x%02x\n", - i, expected[i], buf[i]); - return 1; - } - } - - return 0; -} - -int tc_get_write_resp(uint8_t addr0, uint8_t addr1) -{ - uint8_t buf[5]; - uint8_t expected[5] = { SOR, WRITE_OK, addr0, addr1, EOR }; - - return - tc_get_resp(buf, sizeof(buf)) || - tc_compare(buf, expected, sizeof(expected)); -} - -int tc_get_read_resp(uint8_t addr0, uint8_t addr1, uint8_t *data) -{ - uint8_t buf[9]; - uint8_t expected[4] = { SOR, READ_OK, addr0, addr1 }; - - if ((tc_get_resp(buf, sizeof(buf)) != 0) || - (tc_compare(buf, expected, 4) != 0) || buf[8] != EOR) - return 1; - - data[0] = buf[4]; - data[1] = buf[5]; - data[2] = buf[6]; - data[3] = buf[7]; - - return 0; -} - -int tc_write(uint8_t addr0, uint8_t addr1, uint8_t *data) -{ - return (tc_send_write_cmd(addr0, addr1, data) || - tc_get_write_resp(addr0, addr1)); -} - -int tc_read(uint8_t addr0, uint8_t addr1, uint8_t *data) -{ - return (tc_send_read_cmd(addr0, addr1) || - tc_get_read_resp(addr0, addr1, data)); -} - -int tc_init(uint8_t addr0, uint8_t mode) -{ - uint8_t buf[4] = { 0, 0, 0, CTRL_INIT_CMD }; - - if (addr0 == SHA512_ADDR_PREFIX) - buf[3] += (mode << SHA512_CTRL_MODE_LOW); - - return tc_write(addr0, ADDR_CTRL, buf); -} - -int tc_next(uint8_t addr0, uint8_t mode) -{ - uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT_CMD }; - - if (addr0 == SHA512_ADDR_PREFIX) - buf[3] += (mode << SHA512_CTRL_MODE_LOW); - - return tc_write(addr0, ADDR_CTRL, buf); -} - -int tc_wait(uint8_t addr0, uint8_t status) -{ - uint8_t buf[4]; - - do { - if (tc_read(addr0, ADDR_STATUS, &buf[0]) != 0) - return 1; - } while ((buf[3] & status) != status); - - return 0; -} - -int tc_wait_ready(uint8_t addr0) -{ - return tc_wait(addr0, STATUS_READY_BIT); -} - -int tc_wait_valid(uint8_t addr0) -{ - return tc_wait(addr0, STATUS_VALID_BIT); -} - -int tc_write_block(uint8_t addr0, uint8_t addr1, uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len/4; ++i) { - if (tc_write(addr0, addr1 + i, &buf[i*4]) != 0) - return 1; - } - - return 0; -} - -int tc_read_digest(uint8_t addr0, uint8_t addr1, uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len/4; ++i) { - if (tc_read(addr0, addr1 + i, &buf[i*4]) != 0) - return 1; - } - - return 0; -} - -/* ---------------- 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]; - struct ctrl *ctrl; - int in_fd = 0; /* stdin */ - uint8_t addr0, baddr, blen, daddr, dlen, mode; - int nblk, nread, first; - int ret = -1; - struct timeval start, stop, difftime; - - ctrl = find_algo(algo); - if (ctrl == NULL) - return -1; - addr0 = ctrl->addr_prefix; - baddr = ctrl->addr_block; - blen = ctrl->block_len; - daddr = ctrl->addr_digest; - dlen = ctrl->digest_len; - mode = ctrl->mode; - - if (strcmp(file, "-") != 0) { - in_fd = open(file, O_RDONLY); - if (in_fd < 0) { - perror("open"); - return -1; - } - } - - if (verbose) { - if (gettimeofday(&start, NULL) < 0) { - perror("gettimeofday"); - goto out; - } - } - - for (nblk = 0, first = 1; ; ++nblk, first = 0) { - nread = read(in_fd, block, blen); - if (nread < 0) { - /* read error */ - perror("read"); - goto out; - } - 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 { - /* full block read */ - if (transmit(block, blen, addr0, baddr, mode, first) != 0) - goto out; - } - } - - if (tc_wait_valid(addr0) != 0) - goto out; - if (tc_read_digest(addr0, daddr, digest, dlen) != 0) { - perror("i2c read failed"); - goto out; - } - - if (verbose) { - if (gettimeofday(&stop, NULL) < 0) { - perror("gettimeofday"); - goto out; - } - timersub(&stop, &start, &difftime); - printf("%d blocks written in %d.%03d sec (%.3f blocks/sec)\n", - nblk, (int)difftime.tv_sec, (int)difftime.tv_usec/1000, - (float)nblk / ((float)difftime.tv_sec + ((float)difftime.tv_usec)/1000000)); - } - - ret = dlen; -out: - if (in_fd != 0) - close(in_fd); - return ret; -} - -/* ---------------- main ---------------- */ - -int main(int argc, char *argv[]) -{ - char *dev = I2C_dev; - int addr = I2C_addr; - int i, opt, quiet = 0; - char *algo = "sha-1"; - char *file = "-"; - uint8_t digest[512/8]; - int dlen; - - while ((opt = getopt(argc, argv, "h?dvqi:a:")) != -1) { - switch (opt) { - case 'h': - case '?': - printf(usage, argv[0]); - return 0; - case 'd': - debug = 1; - break; - case 'v': - verbose = 1; - break; - case 'q': - quiet = 1; - break; - case 'i': - dev = optarg; - break; - case 'a': - addr = (int)strtol(optarg, NULL, 0); - if ((addr < 0x03) || (addr > 0x77)) { - fprintf(stderr, "addr must be between 0x03 and 0x77\n"); - return 1; - } - break; - default: - fprintf(stderr, usage, argv[0]); - return 1; - } - } - - if (optind < argc) { - algo = argv[optind]; - ++optind; - } - else { - if (!quiet) - printf("defaulting to algorithm \"%s\"\n", algo); - } - - if (optind < argc) { - file = argv[optind]; - ++optind; - } - else { - if (!quiet) - printf("reading from stdin\n"); - } - - if (i2c_open(dev, addr) != 0) - return -1; - - dlen = hash(algo, file, digest); - if (dlen < 0) - return 1; - - for (i = 0; i < dlen; ++i) { - printf("%02x", digest[i]); - if (i % 16 == 15) - printf("\n"); - else if (i % 4 == 3) - printf(" "); - } - if (dlen % 16 != 0) - printf("\n"); - - i2c_close(); - - return 0; -} -- cgit v1.2.3