1 /* 2 * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <string.h> 11 12 #include "apps.h" 13 #include "progs.h" 14 #include <openssl/bn.h> 15 16 typedef enum OPTION_choice { 17 OPT_COMMON, 18 OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS, 19 OPT_PROV_ENUM 20 } OPTION_CHOICE; 21 22 const OPTIONS prime_options[] = { 23 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, 24 25 OPT_SECTION("General"), 26 {"help", OPT_HELP, '-', "Display this summary"}, 27 {"bits", OPT_BITS, 'p', "Size of number in bits"}, 28 {"checks", OPT_CHECKS, 'p', "Number of checks"}, 29 30 OPT_SECTION("Output"), 31 {"hex", OPT_HEX, '-', "Hex output"}, 32 {"generate", OPT_GENERATE, '-', "Generate a prime"}, 33 {"safe", OPT_SAFE, '-', 34 "When used with -generate, generate a safe prime"}, 35 36 OPT_PROV_OPTIONS, 37 38 OPT_PARAMETERS(), 39 {"number", 0, 0, "Number(s) to check for primality if not generating"}, 40 {NULL} 41 }; 42 43 int prime_main(int argc, char **argv) 44 { 45 BIGNUM *bn = NULL; 46 int hex = 0, generate = 0, bits = 0, safe = 0, ret = 1; 47 char *prog; 48 OPTION_CHOICE o; 49 50 prog = opt_init(argc, argv, prime_options); 51 while ((o = opt_next()) != OPT_EOF) { 52 switch (o) { 53 case OPT_EOF: 54 case OPT_ERR: 55 opthelp: 56 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 57 goto end; 58 case OPT_HELP: 59 opt_help(prime_options); 60 ret = 0; 61 goto end; 62 case OPT_HEX: 63 hex = 1; 64 break; 65 case OPT_GENERATE: 66 generate = 1; 67 break; 68 case OPT_BITS: 69 bits = atoi(opt_arg()); 70 break; 71 case OPT_SAFE: 72 safe = 1; 73 break; 74 case OPT_CHECKS: 75 /* ignore parameter and argument */ 76 opt_arg(); 77 break; 78 case OPT_PROV_CASES: 79 if (!opt_provider(o)) 80 goto end; 81 break; 82 } 83 } 84 85 /* Optional arguments are numbers to check. */ 86 argc = opt_num_rest(); 87 argv = opt_rest(); 88 if (generate) { 89 if (argc != 0) 90 goto opthelp; 91 } else if (argc == 0) { 92 goto opthelp; 93 } 94 95 if (generate) { 96 char *s; 97 98 if (!bits) { 99 BIO_printf(bio_err, "Specify the number of bits.\n"); 100 goto end; 101 } 102 bn = BN_new(); 103 if (bn == NULL) { 104 BIO_printf(bio_err, "Out of memory.\n"); 105 goto end; 106 } 107 if (!BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL)) { 108 BIO_printf(bio_err, "Failed to generate prime.\n"); 109 goto end; 110 } 111 s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 112 if (s == NULL) { 113 BIO_printf(bio_err, "Out of memory.\n"); 114 goto end; 115 } 116 BIO_printf(bio_out, "%s\n", s); 117 OPENSSL_free(s); 118 } else { 119 for ( ; *argv; argv++) { 120 int r; 121 122 if (hex) 123 r = BN_hex2bn(&bn, argv[0]); 124 else 125 r = BN_dec2bn(&bn, argv[0]); 126 127 if (!r) { 128 BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]); 129 goto end; 130 } 131 132 BN_print(bio_out, bn); 133 BIO_printf(bio_out, " (%s) %s prime\n", 134 argv[0], 135 BN_check_prime(bn, NULL, NULL) 136 ? "is" : "is not"); 137 } 138 } 139 140 ret = 0; 141 end: 142 BN_free(bn); 143 return ret; 144 } 145