1 /* $OpenBSD: prime.c,v 1.6 2015/02/11 03:19:37 doug 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 #include <openssl/err.h> 58 59 struct { 60 int bits; 61 int checks; 62 int generate; 63 int hex; 64 int safe; 65 } prime_config; 66 67 struct option prime_options[] = { 68 { 69 .name = "bits", 70 .argname = "n", 71 .desc = "Number of bits in the generated prime number", 72 .type = OPTION_ARG_INT, 73 .opt.value = &prime_config.bits, 74 }, 75 { 76 .name = "checks", 77 .argname = "n", 78 .desc = "Miller-Rabin probablistic primality test iterations", 79 .type = OPTION_ARG_INT, 80 .opt.value = &prime_config.checks, 81 }, 82 { 83 .name = "generate", 84 .desc = "Generate a pseudo-random prime number", 85 .type = OPTION_FLAG, 86 .opt.flag = &prime_config.generate, 87 }, 88 { 89 .name = "hex", 90 .desc = "Hexadecimal prime numbers", 91 .type = OPTION_FLAG, 92 .opt.flag = &prime_config.hex, 93 }, 94 { 95 .name = "safe", 96 .desc = "Generate only \"safe\" prime numbers", 97 .type = OPTION_FLAG, 98 .opt.flag = &prime_config.safe, 99 }, 100 {NULL}, 101 }; 102 103 static void 104 prime_usage() 105 { 106 fprintf(stderr, 107 "usage: prime [-bits n] [-checks n] [-generate] [-hex] [-safe] " 108 "p\n"); 109 options_usage(prime_options); 110 } 111 112 int prime_main(int, char **); 113 114 int 115 prime_main(int argc, char **argv) 116 { 117 BIGNUM *bn = NULL; 118 char *prime = NULL; 119 BIO *bio_out; 120 char *s; 121 int ret = 1; 122 123 memset(&prime_config, 0, sizeof(prime_config)); 124 125 /* Default iterations for Miller-Rabin probabilistic primality test. */ 126 prime_config.checks = 20; 127 128 if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) { 129 prime_usage(); 130 return (1); 131 } 132 133 if (prime == NULL && prime_config.generate == 0) { 134 BIO_printf(bio_err, "No prime specified.\n"); 135 prime_usage(); 136 return (1); 137 } 138 139 if ((bio_out = BIO_new(BIO_s_file())) == NULL) { 140 ERR_print_errors(bio_err); 141 return (1); 142 } 143 BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); 144 145 if (prime_config.generate != 0) { 146 if (prime_config.bits == 0) { 147 BIO_printf(bio_err, "Specify the number of bits.\n"); 148 goto end; 149 } 150 bn = BN_new(); 151 if (!bn) { 152 BIO_printf(bio_err, "Out of memory.\n"); 153 goto end; 154 } 155 if (!BN_generate_prime_ex(bn, prime_config.bits, 156 prime_config.safe, NULL, NULL, NULL)) { 157 BIO_printf(bio_err, "Prime generation error.\n"); 158 goto end; 159 } 160 s = prime_config.hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 161 if (s == NULL) { 162 BIO_printf(bio_err, "Out of memory.\n"); 163 goto end; 164 } 165 BIO_printf(bio_out, "%s\n", s); 166 free(s); 167 } else { 168 if (prime_config.hex) { 169 if (!BN_hex2bn(&bn, prime)) { 170 BIO_printf(bio_err, "%s is an invalid hex " 171 "value.\n", prime); 172 goto end; 173 } 174 } else { 175 if (!BN_dec2bn(&bn, prime)) { 176 BIO_printf(bio_err, "%s is an invalid decimal " 177 "value.\n", prime); 178 goto end; 179 } 180 } 181 182 BN_print(bio_out, bn); 183 BIO_printf(bio_out, " is %sprime\n", 184 BN_is_prime_ex(bn, prime_config.checks, 185 NULL, NULL) ? "" : "not "); 186 } 187 188 ret = 0; 189 190 end: 191 BN_free(bn); 192 BIO_free_all(bio_out); 193 194 return (ret); 195 } 196