1 /* $OpenBSD: prime.c,v 1.3 2014/10/13 02:46:14 bcook Exp $ */ 2 /* ==================================================================== 3 * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core@openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * 49 */ 50 51 #include <string.h> 52 #include <limits.h> 53 54 #include "apps.h" 55 56 #include <openssl/bn.h> 57 58 struct { 59 int bits; 60 int checks; 61 int generate; 62 int hex; 63 int safe; 64 } prime_config; 65 66 struct option prime_options[] = { 67 { 68 .name = "bits", 69 .argname = "n", 70 .desc = "Number of bits in the generated prime number", 71 .type = OPTION_ARG_INT, 72 .opt.value = &prime_config.bits, 73 }, 74 { 75 .name = "checks", 76 .argname = "n", 77 .desc = "Miller-Rabin probablistic primality test iterations", 78 .type = OPTION_ARG_INT, 79 .opt.value = &prime_config.checks, 80 }, 81 { 82 .name = "generate", 83 .desc = "Generate a pseudo-random prime number", 84 .type = OPTION_FLAG, 85 .opt.flag = &prime_config.generate, 86 }, 87 { 88 .name = "hex", 89 .desc = "Hexadecimal prime numbers", 90 .type = OPTION_FLAG, 91 .opt.flag = &prime_config.hex, 92 }, 93 { 94 .name = "safe", 95 .desc = "Generate only \"safe\" prime numbers", 96 .type = OPTION_FLAG, 97 .opt.flag = &prime_config.safe, 98 }, 99 {NULL}, 100 }; 101 102 static void 103 prime_usage() 104 { 105 fprintf(stderr, 106 "usage: prime [-bits n] [-checks n] [-generate] [-hex] [-safe] " 107 "p\n"); 108 options_usage(prime_options); 109 } 110 111 int prime_main(int, char **); 112 113 int 114 prime_main(int argc, char **argv) 115 { 116 BIGNUM *bn = NULL; 117 char *prime = NULL; 118 BIO *bio_out; 119 char *s; 120 121 memset(&prime_config, 0, sizeof(prime_config)); 122 123 /* Default iterations for Miller-Rabin probabilistic primality test. */ 124 prime_config.checks = 20; 125 126 if (options_parse(argc, argv, prime_options, &prime) != 0) { 127 prime_usage(); 128 return (1); 129 } 130 131 if (prime == NULL && prime_config.generate == 0) { 132 BIO_printf(bio_err, "No prime specified.\n"); 133 prime_usage(); 134 return (1); 135 } 136 137 if ((bio_out = BIO_new(BIO_s_file())) != NULL) { 138 BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); 139 } 140 141 if (prime_config.generate != 0) { 142 if (prime_config.bits == 0) { 143 BIO_printf(bio_err, "Specify the number of bits.\n"); 144 return 1; 145 } 146 bn = BN_new(); /* XXX - unchecked malloc. */ 147 BN_generate_prime_ex(bn, prime_config.bits, prime_config.safe, 148 NULL, NULL, NULL); 149 s = prime_config.hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 150 BIO_printf(bio_out, "%s\n", s); 151 free(s); 152 } else { 153 if (prime_config.hex) 154 BN_hex2bn(&bn, prime); 155 else 156 BN_dec2bn(&bn, prime); 157 158 BN_print(bio_out, bn); 159 BIO_printf(bio_out, " is %sprime\n", 160 BN_is_prime_ex(bn, prime_config.checks, 161 NULL, NULL) ? "" : "not "); 162 } 163 164 BN_free(bn); 165 BIO_free_all(bio_out); 166 167 return 0; 168 } 169