1 /* 2 * Copyright 2004-2022 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 static int check_num(const char *s, const int is_hex) 23 { 24 int i; 25 /* 26 * It would make sense to use ossl_isxdigit and ossl_isdigit here, 27 * but ossl_ctype_check is a local symbol in libcrypto.so. 28 */ 29 if (is_hex) { 30 for (i = 0; ('0' <= s[i] && s[i] <= '9') 31 || ('A' <= s[i] && s[i] <= 'F') 32 || ('a' <= s[i] && s[i] <= 'f'); i++); 33 } else { 34 for (i = 0; '0' <= s[i] && s[i] <= '9'; i++); 35 } 36 return s[i] == 0; 37 } 38 39 const OPTIONS prime_options[] = { 40 {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, 41 42 OPT_SECTION("General"), 43 {"help", OPT_HELP, '-', "Display this summary"}, 44 {"bits", OPT_BITS, 'p', "Size of number in bits"}, 45 {"checks", OPT_CHECKS, 'p', "Number of checks"}, 46 47 OPT_SECTION("Output"), 48 {"hex", OPT_HEX, '-', "Hex output"}, 49 {"generate", OPT_GENERATE, '-', "Generate a prime"}, 50 {"safe", OPT_SAFE, '-', 51 "When used with -generate, generate a safe prime"}, 52 53 OPT_PROV_OPTIONS, 54 55 OPT_PARAMETERS(), 56 {"number", 0, 0, "Number(s) to check for primality if not generating"}, 57 {NULL} 58 }; 59 60 int prime_main(int argc, char **argv) 61 { 62 BIGNUM *bn = NULL; 63 int hex = 0, generate = 0, bits = 0, safe = 0, ret = 1; 64 char *prog; 65 OPTION_CHOICE o; 66 67 prog = opt_init(argc, argv, prime_options); 68 while ((o = opt_next()) != OPT_EOF) { 69 switch (o) { 70 case OPT_EOF: 71 case OPT_ERR: 72 opthelp: 73 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 74 goto end; 75 case OPT_HELP: 76 opt_help(prime_options); 77 ret = 0; 78 goto end; 79 case OPT_HEX: 80 hex = 1; 81 break; 82 case OPT_GENERATE: 83 generate = 1; 84 break; 85 case OPT_BITS: 86 bits = atoi(opt_arg()); 87 break; 88 case OPT_SAFE: 89 safe = 1; 90 break; 91 case OPT_CHECKS: 92 /* ignore parameter and argument */ 93 opt_arg(); 94 break; 95 case OPT_PROV_CASES: 96 if (!opt_provider(o)) 97 goto end; 98 break; 99 } 100 } 101 102 /* Optional arguments are numbers to check. */ 103 if (generate && !opt_check_rest_arg(NULL)) 104 goto opthelp; 105 argc = opt_num_rest(); 106 argv = opt_rest(); 107 if (!generate && argc == 0) { 108 BIO_printf(bio_err, "Missing number (s) to check\n"); 109 goto opthelp; 110 } 111 112 if (generate) { 113 char *s; 114 115 if (!bits) { 116 BIO_printf(bio_err, "Specify the number of bits.\n"); 117 goto end; 118 } 119 bn = BN_new(); 120 if (bn == NULL) { 121 BIO_printf(bio_err, "Out of memory.\n"); 122 goto end; 123 } 124 if (!BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL)) { 125 BIO_printf(bio_err, "Failed to generate prime.\n"); 126 goto end; 127 } 128 s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 129 if (s == NULL) { 130 BIO_printf(bio_err, "Out of memory.\n"); 131 goto end; 132 } 133 BIO_printf(bio_out, "%s\n", s); 134 OPENSSL_free(s); 135 } else { 136 for ( ; *argv; argv++) { 137 int r = check_num(argv[0], hex); 138 139 if (r) 140 r = hex ? BN_hex2bn(&bn, argv[0]) : BN_dec2bn(&bn, argv[0]); 141 142 if (!r) { 143 BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]); 144 goto end; 145 } 146 147 BN_print(bio_out, bn); 148 r = BN_check_prime(bn, NULL, NULL); 149 if (r < 0) { 150 BIO_printf(bio_err, "Error checking prime\n"); 151 goto end; 152 } 153 BIO_printf(bio_out, " (%s) %s prime\n", 154 argv[0], 155 r == 1 ? "is" : "is not"); 156 } 157 } 158 159 ret = 0; 160 end: 161 BN_free(bn); 162 return ret; 163 } 164