aboutsummaryrefslogtreecommitdiff
path: root/i2c/sw/hash_i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'i2c/sw/hash_i2c.c')
-rw-r--r--i2c/sw/hash_i2c.c288
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;
-}