diff options
author | Paul Selkirk <paul@psgd.org> | 2015-04-02 15:07:22 -0400 |
---|---|---|
committer | Paul Selkirk <paul@psgd.org> | 2015-04-02 15:07:22 -0400 |
commit | b1ebb2a975de7f29e63c3a4046de15c26b44dceb (patch) | |
tree | 20c6e29fa7f51953a83629146bcf61ad556092ab /i2c/sw/trng_extractor_i2c.c | |
parent | aea9e93e560b1468bf0ff2cf5b61e5409ce60dc5 (diff) |
Add trng_extractor app to eim and i2c, refactor i2c apps to use common memory map.
Diffstat (limited to 'i2c/sw/trng_extractor_i2c.c')
-rw-r--r-- | i2c/sw/trng_extractor_i2c.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/i2c/sw/trng_extractor_i2c.c b/i2c/sw/trng_extractor_i2c.c new file mode 100644 index 0000000..29f054c --- /dev/null +++ b/i2c/sw/trng_extractor_i2c.c @@ -0,0 +1,167 @@ +/* + * trng_extractor.c + * ---------------- + * This program extracts raw data from the avalanche_entropy, rosc_entropy, + * and csprng cores. + * + * Author: Paul Selkirk + * Copyright (c) 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdint.h> + +#include "tc_i2c.h" +#include "cryptech_memory_map.h" + +char *usage = +"%s [-a|r|c] [-n #] [-o file] [-I I2C_device] [-A I2C_addr]\n\ +\n\ +-a avalanche entropy\n\ +-r rosc entropy\n\ +-c csprng\n\ +-n number of 4-byte samples (defaults to 10)\n\ +-o output file (defaults to stdout)\n\ +"; + +int debug = 0; /* for dump() */ + +/* extract one data sample */ +static int extract(off_t status_addr, off_t data_addr, uint32_t *data) +{ + if (tc_wait(status_addr, ENTROPY1_STATUS_VALID, NULL) != 0) { + fprintf(stderr, "tc_wait failed\n"); + return 1; + } + + if (tc_read(data_addr, (uint8_t *)data, 4) != 0) { + fprintf(stderr, "tc_read failed\n"); + return 1; + } + + return 0; +} + +/* main */ +int main(int argc, char *argv[]) +{ + int i, opt, num_words = 10; + uint32_t data; + off_t status_addr = 0, data_addr = 0; + FILE *output = stdout; + char *dev = I2C_dev; + int addr = I2C_addr; + + /* parse command line */ + while ((opt = getopt(argc, argv, "h?arcn:o:I:A:")) != -1) { + switch (opt) { + case 'h': + case '?': + printf(usage, argv[0]); + return EXIT_SUCCESS; + case 'a': + status_addr = ENTROPY1_ADDR_STATUS; + data_addr = ENTROPY1_ADDR_ENTROPY; + break; + case 'r': + status_addr = ENTROPY2_ADDR_STATUS; + data_addr = ENTROPY2_ADDR_ENTROPY; + break; + case 'c': + status_addr = CSPRNG_ADDR_STATUS; + data_addr = CSPRNG_ADDR_RANDOM; + break; + case 'n': + num_words = atoi(optarg); + if (num_words <= 0) { + fprintf(stderr, "-n requires a positive integer argument\n"); + return EXIT_FAILURE; + } + break; + case 'o': + output = fopen(optarg, "wb+"); + if (output == NULL) { + fprintf(stderr, "error opening output file %s: ", optarg); + perror(""); + return EXIT_FAILURE; + } + 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: + errout: + fprintf(stderr, usage, argv[0]); + return EXIT_FAILURE; + } + } + if (optind < argc) { + fprintf(stderr, "%s: invalid argument%s --", + argv[0], argc - optind > 1 ? "s" : ""); + do { + fprintf(stderr, " %s", argv[optind]); + ++optind; + } while (optind < argc); + fprintf(stderr, "\n"); + goto errout; + } + if (status_addr == 0) { + fprintf(stderr, "%s: a data source must be specified\n", argv[0]); + goto errout; + } + + /* set up I2C */ + if (i2c_open(dev, addr) != 0) { + fprintf(stderr, "I2C setup failed\n"); + return EXIT_FAILURE; + } + + /* get the data */ + for (i = 0; i < num_words; ++i) { + if (extract(status_addr, data_addr, &data) != 0) + return EXIT_FAILURE; + if (fwrite(&data, sizeof(data), 1, output) != 1) { + perror("fwrite"); + fclose(output); + return EXIT_FAILURE; + } + } + + fclose(output); + return EXIT_SUCCESS; +} |