1 /* $OpenBSD: prime.c,v 1.5 2015/01/13 03:42:36 lteo 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 int ret = 1; 121 122 memset(&prime_config, 0, sizeof(prime_config)); 123 124 /* Default iterations for Miller-Rabin probabilistic primality test. */ 125 prime_config.checks = 20; 126 127 if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) { 128 prime_usage(); 129 return (1); 130 } 131 132 if (prime == NULL && prime_config.generate == 0) { 133 BIO_printf(bio_err, "No prime specified.\n"); 134 prime_usage(); 135 return (1); 136 } 137 138 if ((bio_out = BIO_new(BIO_s_file())) == NULL) { 139 ERR_print_errors(bio_err); 140 return (1); 141 } 142 BIO_set_fp(bio_out, stdout, BIO_NOCLOSE); 143 144 if (prime_config.generate != 0) { 145 if (prime_config.bits == 0) { 146 BIO_printf(bio_err, "Specify the number of bits.\n"); 147 goto end; 148 } 149 bn = BN_new(); 150 if (!bn) { 151 BIO_printf(bio_err, "Out of memory.\n"); 152 goto end; 153 } 154 if (!BN_generate_prime_ex(bn, prime_config.bits, 155 prime_config.safe, NULL, NULL, NULL)) { 156 BIO_printf(bio_err, "Prime generation error.\n"); 157 goto end; 158 } 159 s = prime_config.hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 160 if (s == NULL) { 161 BIO_printf(bio_err, "Out of memory.\n"); 162 goto end; 163 } 164 BIO_printf(bio_out, "%s\n", s); 165 free(s); 166 } else { 167 if (prime_config.hex) { 168 if (!BN_hex2bn(&bn, prime)) { 169 BIO_printf(bio_err, "%s is an invalid hex " 170 "value.\n", prime); 171 goto end; 172 } 173 } else { 174 if (!BN_dec2bn(&bn, prime)) { 175 BIO_printf(bio_err, "%s is an invalid decimal " 176 "value.\n", prime); 177 goto end; 178 } 179 } 180 181 BN_print(bio_out, bn); 182 BIO_printf(bio_out, " is %sprime\n", 183 BN_is_prime_ex(bn, prime_config.checks, 184 NULL, NULL) ? "" : "not "); 185 } 186 187 ret = 0; 188 189 end: 190 BN_free(bn); 191 BIO_free_all(bio_out); 192 193 return (ret); 194 } 195