11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved. 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 51cb0ef41Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at 71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include <string.h> 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include "apps.h" 131cb0ef41Sopenharmony_ci#include "progs.h" 141cb0ef41Sopenharmony_ci#include <openssl/bn.h> 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_citypedef enum OPTION_choice { 171cb0ef41Sopenharmony_ci OPT_COMMON, 181cb0ef41Sopenharmony_ci OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS, 191cb0ef41Sopenharmony_ci OPT_PROV_ENUM 201cb0ef41Sopenharmony_ci} OPTION_CHOICE; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciconst OPTIONS prime_options[] = { 231cb0ef41Sopenharmony_ci {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"}, 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci OPT_SECTION("General"), 261cb0ef41Sopenharmony_ci {"help", OPT_HELP, '-', "Display this summary"}, 271cb0ef41Sopenharmony_ci {"bits", OPT_BITS, 'p', "Size of number in bits"}, 281cb0ef41Sopenharmony_ci {"checks", OPT_CHECKS, 'p', "Number of checks"}, 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci OPT_SECTION("Output"), 311cb0ef41Sopenharmony_ci {"hex", OPT_HEX, '-', "Hex output"}, 321cb0ef41Sopenharmony_ci {"generate", OPT_GENERATE, '-', "Generate a prime"}, 331cb0ef41Sopenharmony_ci {"safe", OPT_SAFE, '-', 341cb0ef41Sopenharmony_ci "When used with -generate, generate a safe prime"}, 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci OPT_PROV_OPTIONS, 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci OPT_PARAMETERS(), 391cb0ef41Sopenharmony_ci {"number", 0, 0, "Number(s) to check for primality if not generating"}, 401cb0ef41Sopenharmony_ci {NULL} 411cb0ef41Sopenharmony_ci}; 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciint prime_main(int argc, char **argv) 441cb0ef41Sopenharmony_ci{ 451cb0ef41Sopenharmony_ci BIGNUM *bn = NULL; 461cb0ef41Sopenharmony_ci int hex = 0, generate = 0, bits = 0, safe = 0, ret = 1; 471cb0ef41Sopenharmony_ci char *prog; 481cb0ef41Sopenharmony_ci OPTION_CHOICE o; 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci prog = opt_init(argc, argv, prime_options); 511cb0ef41Sopenharmony_ci while ((o = opt_next()) != OPT_EOF) { 521cb0ef41Sopenharmony_ci switch (o) { 531cb0ef41Sopenharmony_ci case OPT_EOF: 541cb0ef41Sopenharmony_ci case OPT_ERR: 551cb0ef41Sopenharmony_ciopthelp: 561cb0ef41Sopenharmony_ci BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 571cb0ef41Sopenharmony_ci goto end; 581cb0ef41Sopenharmony_ci case OPT_HELP: 591cb0ef41Sopenharmony_ci opt_help(prime_options); 601cb0ef41Sopenharmony_ci ret = 0; 611cb0ef41Sopenharmony_ci goto end; 621cb0ef41Sopenharmony_ci case OPT_HEX: 631cb0ef41Sopenharmony_ci hex = 1; 641cb0ef41Sopenharmony_ci break; 651cb0ef41Sopenharmony_ci case OPT_GENERATE: 661cb0ef41Sopenharmony_ci generate = 1; 671cb0ef41Sopenharmony_ci break; 681cb0ef41Sopenharmony_ci case OPT_BITS: 691cb0ef41Sopenharmony_ci bits = atoi(opt_arg()); 701cb0ef41Sopenharmony_ci break; 711cb0ef41Sopenharmony_ci case OPT_SAFE: 721cb0ef41Sopenharmony_ci safe = 1; 731cb0ef41Sopenharmony_ci break; 741cb0ef41Sopenharmony_ci case OPT_CHECKS: 751cb0ef41Sopenharmony_ci /* ignore parameter and argument */ 761cb0ef41Sopenharmony_ci opt_arg(); 771cb0ef41Sopenharmony_ci break; 781cb0ef41Sopenharmony_ci case OPT_PROV_CASES: 791cb0ef41Sopenharmony_ci if (!opt_provider(o)) 801cb0ef41Sopenharmony_ci goto end; 811cb0ef41Sopenharmony_ci break; 821cb0ef41Sopenharmony_ci } 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci /* Optional arguments are numbers to check. */ 861cb0ef41Sopenharmony_ci argc = opt_num_rest(); 871cb0ef41Sopenharmony_ci argv = opt_rest(); 881cb0ef41Sopenharmony_ci if (generate) { 891cb0ef41Sopenharmony_ci if (argc != 0) 901cb0ef41Sopenharmony_ci goto opthelp; 911cb0ef41Sopenharmony_ci } else if (argc == 0) { 921cb0ef41Sopenharmony_ci goto opthelp; 931cb0ef41Sopenharmony_ci } 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci if (generate) { 961cb0ef41Sopenharmony_ci char *s; 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci if (!bits) { 991cb0ef41Sopenharmony_ci BIO_printf(bio_err, "Specify the number of bits.\n"); 1001cb0ef41Sopenharmony_ci goto end; 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci bn = BN_new(); 1031cb0ef41Sopenharmony_ci if (bn == NULL) { 1041cb0ef41Sopenharmony_ci BIO_printf(bio_err, "Out of memory.\n"); 1051cb0ef41Sopenharmony_ci goto end; 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci if (!BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL)) { 1081cb0ef41Sopenharmony_ci BIO_printf(bio_err, "Failed to generate prime.\n"); 1091cb0ef41Sopenharmony_ci goto end; 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn); 1121cb0ef41Sopenharmony_ci if (s == NULL) { 1131cb0ef41Sopenharmony_ci BIO_printf(bio_err, "Out of memory.\n"); 1141cb0ef41Sopenharmony_ci goto end; 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci BIO_printf(bio_out, "%s\n", s); 1171cb0ef41Sopenharmony_ci OPENSSL_free(s); 1181cb0ef41Sopenharmony_ci } else { 1191cb0ef41Sopenharmony_ci for ( ; *argv; argv++) { 1201cb0ef41Sopenharmony_ci int r; 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci if (hex) 1231cb0ef41Sopenharmony_ci r = BN_hex2bn(&bn, argv[0]); 1241cb0ef41Sopenharmony_ci else 1251cb0ef41Sopenharmony_ci r = BN_dec2bn(&bn, argv[0]); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci if (!r) { 1281cb0ef41Sopenharmony_ci BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]); 1291cb0ef41Sopenharmony_ci goto end; 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci BN_print(bio_out, bn); 1331cb0ef41Sopenharmony_ci BIO_printf(bio_out, " (%s) %s prime\n", 1341cb0ef41Sopenharmony_ci argv[0], 1351cb0ef41Sopenharmony_ci BN_check_prime(bn, NULL, NULL) 1361cb0ef41Sopenharmony_ci ? "is" : "is not"); 1371cb0ef41Sopenharmony_ci } 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci ret = 0; 1411cb0ef41Sopenharmony_ci end: 1421cb0ef41Sopenharmony_ci BN_free(bn); 1431cb0ef41Sopenharmony_ci return ret; 1441cb0ef41Sopenharmony_ci} 145