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