1 /* 2 * rand_gen.c 3 * 4 * a random source (random number generator) 5 * 6 * David A. McGrew 7 * Cisco Systems, Inc. 8 */ 9 /* 10 * 11 * Copyright(c) 2001-2006 Cisco Systems, Inc. 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 18 * Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * Neither the name of the Cisco Systems, Inc. nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 41 * OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 46 #include <stdio.h> /* for printf() */ 47 #include <unistd.h> /* for getopt() */ 48 #include "crypto_kernel.h" 49 50 /* 51 * MAX_PRINT_STRING_LEN is defined in datatypes.h, and is the length 52 * of the largest hexadecimal string that can be generated by the 53 * function octet_string_hex_string(). 54 */ 55 56 #define BUF_LEN (MAX_PRINT_STRING_LEN/2) 57 58 void 59 usage(char *prog_name) { 60 printf("usage: %s -n <num_bytes> [-l][ -d debug_module ]*\n" 61 " -n <num> output <num> random bytes, where <num>" 62 " is between zero and %d\n" 63 " -l list the avaliable debug modules\n" 64 " -d <mod> turn on debugging module <mod>\n", 65 prog_name, BUF_LEN); 66 exit(255); 67 } 68 69 int 70 main (int argc, char *argv[]) { 71 extern char *optarg; 72 int q; 73 int num_octets = 0; 74 unsigned do_list_mods = 0; 75 err_status_t status; 76 77 if (argc == 1) 78 usage(argv[0]); 79 80 /* initialize kernel - we need to do this before anything else */ 81 status = crypto_kernel_init(); 82 if (status) { 83 printf("error: crypto_kernel init failed\n"); 84 exit(1); 85 } 86 87 /* process input arguments */ 88 while (1) { 89 q = getopt(argc, argv, "ld:n:"); 90 if (q == -1) 91 break; 92 switch (q) { 93 case 'd': 94 status = crypto_kernel_set_debug_module(optarg, 1); 95 if (status) { 96 printf("error: set debug module (%s) failed\n", optarg); 97 exit(1); 98 } 99 break; 100 case 'l': 101 do_list_mods = 1; 102 break; 103 case 'n': 104 num_octets = atoi(optarg); 105 if (num_octets < 0 || num_octets > BUF_LEN) 106 usage(argv[0]); 107 break; 108 default: 109 usage(argv[0]); 110 } 111 } 112 113 if (do_list_mods) { 114 status = crypto_kernel_list_debug_modules(); 115 if (status) { 116 printf("error: list of debug modules failed\n"); 117 exit(1); 118 } 119 } 120 121 if (num_octets > 0) { 122 uint8_t buffer[BUF_LEN]; 123 124 status = crypto_get_random(buffer, num_octets); 125 if (status) { 126 printf("error: failure in random source\n"); 127 } else { 128 printf("%s\n", octet_string_hex_string(buffer, num_octets)); 129 } 130 } 131 132 status = crypto_kernel_shutdown(); 133 if (status) { 134 printf("error: crypto_kernel shutdown failed\n"); 135 exit(1); 136 } 137 138 return 0; 139 } 140 141