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