diff options
Diffstat (limited to 'i2c/sw/hash_i2c.c')
-rw-r--r-- | i2c/sw/hash_i2c.c | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/i2c/sw/hash_i2c.c b/i2c/sw/hash_i2c.c deleted file mode 100644 index 3a9f0cf..0000000 --- a/i2c/sw/hash_i2c.c +++ /dev/null @@ -1,288 +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-2015, NORDUnet A/S All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - 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. - * - * - Neither the name of the NORDUnet nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 - * HOLDER 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 <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.h> -#include <stdint.h> -#include <arpa/inet.h> -#include <assert.h> - -#include "tc_i2c.h" -#include "cryptech_memory_map.h" - -char *usage = -"Usage: %s [-d] [-v] [-q] [algorithm [file]]\n" -"algorithms: sha-1, sha-256, sha-512/224, sha-512/256, sha-384, sha-512\n"; - -int debug = 0; -int quiet = 0; -int verbose = 0; - - -/* ---------------- algorithm lookup code ---------------- */ - -struct ctrl { - char *name; - 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, - SHA1_ADDR_DIGEST, SHA1_DIGEST_LEN, 0 }, - { "sha-256", SHA256_ADDR_BLOCK, SHA256_BLOCK_LEN, - SHA256_ADDR_DIGEST, SHA256_DIGEST_LEN, 0 }, - { "sha-512/224", 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, - SHA512_ADDR_DIGEST, SHA512_256_DIGEST_LEN, MODE_SHA_512_256 }, - { "sha-384", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN, - SHA512_ADDR_DIGEST, SHA384_DIGEST_LEN, MODE_SHA_384 }, - { "sha-512", SHA512_ADDR_BLOCK, SHA512_BLOCK_LEN, - SHA512_ADDR_DIGEST, SHA512_DIGEST_LEN, MODE_SHA_512 }, - { 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; -} - -/* ---------------- hash ---------------- */ - -int transmit(off_t offset, uint8_t *block, int blen, int mode, int first) -{ - off_t base = offset & ~(0x1ff); - uint8_t ctrl_cmd[4] = { 0 }; - - if (tc_write(offset, block, blen) != 0) - return 1; - - ctrl_cmd[3] = (first ? CTRL_INIT_CMD : CTRL_NEXT_CMD) | mode; - - return - tc_write(base + ADDR_CTRL, ctrl_cmd, 4) || - tc_wait_ready(base + ADDR_STATUS); -} - -int pad_transmit(off_t offset, uint8_t *block, uint8_t flen, uint8_t blen, - 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(offset, block, blen, 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(offset, block, blen, 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 */ - off_t baddr, daddr; - int blen, dlen, mode; - int nblk, nread, first; - int ret = -1; - struct timeval start, stop, difftime; - - ctrl = find_algo(algo); - if (ctrl == NULL) - return -1; - baddr = ctrl->block_addr; - blen = ctrl->block_len; - daddr = ctrl->digest_addr; - 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(baddr, 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) - goto out; - } - } - - /* Strictly speaking we should query "valid" status before reading digest, - * but transmit() waits for "ready" status before returning, and the SHA - * cores always assert valid before ready. - */ - if (tc_read(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[]) -{ - int i, opt; - char *algo = "sha-1"; - char *file = "-"; - uint8_t digest[512/8]; - int dlen; - - while ((opt = getopt(argc, argv, "h?dvq")) != -1) { - switch (opt) { - case 'h': - case '?': - printf(usage, argv[0]); - return EXIT_SUCCESS; - case 'd': - debug = 1; - break; - case 'v': - verbose = 1; - break; - case 'q': - quiet = 1; - break; - default: - fprintf(stderr, usage, argv[0]); - return EXIT_FAILURE; - } - } - - 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"); - } - - dlen = hash(algo, file, digest); - if (dlen < 0) - return EXIT_FAILURE; - - 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"); - - return EXIT_SUCCESS; -} |