int test_builtin(BIO *out) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } /* * create and verify a ecdsa signature with every availble curve (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); if (curves == NULL) { BIO_printf(out, "malloc error\n"); goto builtin_err; } if (!EC_get_builtin_curves(curves, crv_len)) { BIO_printf(out, "unable to get internal curves\n"); goto builtin_err; } /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4) continue; /* create new ecdsa key (== EC_KEY) */ if ((eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); if (degree < 160) /* drop the curve */ { EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ if ((wrong_eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(wrong_eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); if ((signature = OPENSSL_malloc(sig_len)) == NULL) goto builtin_err; if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong length */ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* * Modify a single byte of the signature: to ensure we don't garble * the ASN1 structure, we read the raw signature and modify a byte in * one of the bignums directly. */ sig_ptr = signature; if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { BIO_printf(out, " failed\n"); goto builtin_err; } /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(ecdsa_sig->r); s_len = BN_num_bytes(ecdsa_sig->s); bn_len = (degree + 7) / 8; if ((r_len > bn_len) || (s_len > bn_len)) { BIO_printf(out, " failed\n"); goto builtin_err; } buf_len = 2 * bn_len; if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) goto builtin_err; /* Pad the bignums with leading zeroes. */ memset(raw_buf, 0, buf_len); BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } /* * Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) goto builtin_err; sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ /* clean bogus errors */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: if (eckey) EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); if (signature) OPENSSL_free(signature); if (raw_buf) OPENSSL_free(raw_buf); if (curves) OPENSSL_free(curves); return ret; }
static LUA_FUNCTION(openssl_ec_list_curve_name) { size_t n = 0; size_t crv_len = EC_get_builtin_curves(NULL, 0); EC_builtin_curve *curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len)); if (curves == NULL) return 0; if (!EC_get_builtin_curves(curves, crv_len)) { OPENSSL_free(curves); return 0; } lua_newtable(L); for (n = 0; n < crv_len; n++) { const char *comment; const char *sname; comment = curves[n].comment; sname = OBJ_nid2sn(curves[n].nid); if (comment == NULL) comment = "CURVE DESCRIPTION NOT AVAILABLE"; if (sname == NULL) sname = ""; AUXILIAR_SET(L, -1, sname, comment, string); } OPENSSL_free(curves); return 1; };
int main(int argc, char *argv[]) { BN_CTX *ctx = NULL; int nid, ret = 1; EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; BIO *out; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); RAND_seed(rnd_seed, sizeof rnd_seed); out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); if ((ctx = BN_CTX_new()) == NULL) goto err; /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(*curves) * crv_len); if (curves == NULL) goto err; if (!EC_get_builtin_curves(curves, crv_len)) goto err; /* NAMED CURVES TESTS */ for (n = 0; n < crv_len; n++) { nid = curves[n].nid; if (!test_ecdh_curve(nid, ctx, out)) goto err; } /* KATs */ for (n = 0; n < (sizeof(ecdh_kats)/sizeof(ecdh_kat_t)); n++) { if (!ecdh_kat(out, &ecdh_kats[n])) goto err; } ret = 0; err: ERR_print_errors_fp(stderr); OPENSSL_free(curves); BN_CTX_free(ctx); BIO_free(out); CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) ret = 1; #endif EXIT(ret); }
int VNEcdsa_ORG_GenKeys( VNAsymCryptCtx_t * ctx, int keyBits ) { int ret = 0, index = -1, interval = 0, minInterval = 102400; size_t len = 0, i = 0; EC_builtin_curve * curves = NULL; const char * pos = NULL; VNEcdsa_ORG_Ctx_t * orgCtx = VN_CONTAINER_OF( ctx, VNEcdsa_ORG_Ctx_t, mCtx ); assert( VN_TYPE_VNEcdsaSign_ORG == ctx->mType ); { len = EC_get_builtin_curves( NULL, 0 ); curves = (EC_builtin_curve*)calloc( sizeof( EC_builtin_curve ), len ); EC_get_builtin_curves( curves, len ); for( i = 0; i < len; i++ ) { pos = strstr( curves[i].comment, "over a" ); if( NULL != pos ) { interval = abs( atoi( pos + 6 ) - keyBits ); if( interval >= 0 && interval < minInterval ) { minInterval = interval; index = i; } } //printf( "%d, %s\n", curves[i].nid, curves[i].comment ); } printf( "\n\tuse %d, %s\n\n", curves[ index ].nid, curves[ index ].comment ); orgCtx->mNid = curves[ index ].nid; free( curves ); } orgCtx->mEcKey = EC_KEY_new_by_curve_name( orgCtx->mNid ); if( NULL != orgCtx->mEcKey ) { if( ! EC_KEY_generate_key( orgCtx->mEcKey ) ) { char buff[ 1024 ] = { 0 }; printf( "EC_KEY_generate_key %d, %s\n", ret, ERR_error_string( ERR_get_error(), buff ) ); ret = -1; } } else { char buff[ 1024 ] = { 0 }; printf( "EC_KEY_new_by_curve_name %d, %s\n", ret, ERR_error_string( ERR_get_error(), buff ) ); ret = -1; } return ret; }
void openssl_ec_crypt() { BIO *berr; EC_KEY *key1, *key2; unsigned int sig_len; int clen, len1, len2; EC_builtin_curve *curves; EC_GROUP *group1, *group2; const EC_KEY *key3, *key4; const EC_GROUP *group3, *group4; const EC_POINT *pubkey1, *pubkey2; unsigned char shareKey1[COMM_LEN], shareKey2[COMM_LEN]; unsigned char *signature, cont[COMM_LEN] = "123456"; key1 = EC_KEY_new(); key2 = EC_KEY_new(); clen = EC_get_builtin_curves(NULL, 0); curves = (EC_builtin_curve *) malloc(sizeof(EC_builtin_curve) * clen); EC_get_builtin_curves(curves, clen); group1 = EC_GROUP_new_by_curve_name(curves[25].nid); group2 = EC_GROUP_new_by_curve_name(curves[25].nid); group3 = group1; group4 = group2; EC_KEY_set_group(key1, group3); EC_KEY_set_group(key2, group4); EC_KEY_generate_key(key1); EC_KEY_generate_key(key2); EC_KEY_check_key(key1); key3 = key1; key4 = key2; printf("\nECDSA_size: %d\n", ECDSA_size(key3)); signature = (unsigned char *)malloc(ECDSA_size(key3)); ERR_load_crypto_strings(); berr = BIO_new(BIO_s_file()); BIO_set_fp(berr, stdout, BIO_NOCLOSE); ECDSA_sign(0, cont, 8, signature, &sig_len, key1); ECDSA_verify(0, cont, 8, signature, sig_len, key1); pubkey1 = EC_KEY_get0_public_key(key1); pubkey2 = EC_KEY_get0_public_key(key2); len1 = ECDH_compute_key(shareKey1, COMM_LEN, pubkey2, key1, NULL); len2 = ECDH_compute_key(shareKey2, COMM_LEN, pubkey1, key1, NULL); if (len1 != len2 || memcmp(shareKey1, shareKey2, len1) != 0) { printf("ECDH_compute_key err!\n"); return; } BIO_free(berr); EC_KEY_free(key1); EC_KEY_free(key2); free(signature); free(curves); }
void internal_curve_test(void) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; int ok = 1; crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); if (curves == NULL) return; if (!EC_get_builtin_curves(curves, crv_len)) { OPENSSL_free(curves); return; } fprintf(stdout, "testing internal curves: "); for (n = 0; n < crv_len; n++) { EC_GROUP *group = NULL; int nid = curves[n].nid; if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { ok = 0; fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" " curve %s\n", OBJ_nid2sn(nid)); /* try next curve */ continue; } if (!EC_GROUP_check(group, NULL)) { ok = 0; fprintf(stdout, "\nEC_GROUP_check() failed with" " curve %s\n", OBJ_nid2sn(nid)); EC_GROUP_free(group); /* try the next curve */ continue; } fprintf(stdout, "."); fflush(stdout); EC_GROUP_free(group); } if (ok) fprintf(stdout, " ok\n"); else fprintf(stdout, " failed\n"); OPENSSL_free(curves); return; }
int setup_tests(void) { #ifdef OPENSSL_NO_EC TEST_note("Elliptic curves are disabled."); #else /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len)) || !TEST_true(EC_get_builtin_curves(curves, crv_len))) return 0; ADD_ALL_TESTS(test_builtin, crv_len); ADD_ALL_TESTS(x9_62_tests, OSSL_NELEM(ecdsa_cavs_kats)); #endif return 1; }
/* * Show the Elliptic curves that are available for us to use * in the OpenSSL library. */ void show_available_curves() { #ifndef OPENSSL_NO_EC EC_builtin_curve *curves = NULL; size_t crv_len = 0; size_t n = 0; crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len)); if (curves == NULL) msg (M_SSLERR, "Cannot create EC_builtin_curve object"); else { if (EC_get_builtin_curves(curves, crv_len)) { printf ("Available Elliptic curves:\n"); for (n = 0; n < crv_len; n++) { const char *sname; sname = OBJ_nid2sn(curves[n].nid); if (sname == NULL) sname = ""; printf("%s\n", sname); } } else { msg (M_SSLERR, "Cannot get list of builtin curves"); } OPENSSL_free(curves); } #else msg (M_WARN, "Your OpenSSL library was built without elliptic curve support. " "No curves available."); #endif }
int ecparam_main(int argc, char **argv) { EC_GROUP *group = NULL; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; int new_form = 0; int asn1_flag = OPENSSL_EC_NAMED_CURVE; int new_asn1_flag = 0; char *curve_name = NULL, *inrand = NULL; int list_curves = 0, no_seed = 0, check = 0, badops = 0, text = 0, i, genkey = 0; char *infile = NULL, *outfile = NULL, *prog; BIO *in = NULL, *out = NULL; int informat, outformat, noout = 0, C = 0, ret = 1; char *engine = NULL; BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL; unsigned char *buffer = NULL; if (!load_config(bio_err, NULL)) goto end; informat = FORMAT_PEM; outformat = FORMAT_PEM; prog = argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv, "-inform") == 0) { if (--argc < 1) goto bad; informat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-outform") == 0) { if (--argc < 1) goto bad; outformat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-in") == 0) { if (--argc < 1) goto bad; infile = *(++argv); } else if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (strcmp(*argv, "-text") == 0) text = 1; else if (strcmp(*argv, "-C") == 0) C = 1; else if (strcmp(*argv, "-check") == 0) check = 1; else if (strcmp(*argv, "-name") == 0) { if (--argc < 1) goto bad; curve_name = *(++argv); } else if (strcmp(*argv, "-list_curves") == 0) list_curves = 1; else if (strcmp(*argv, "-conv_form") == 0) { if (--argc < 1) goto bad; ++argv; new_form = 1; if (strcmp(*argv, "compressed") == 0) form = POINT_CONVERSION_COMPRESSED; else if (strcmp(*argv, "uncompressed") == 0) form = POINT_CONVERSION_UNCOMPRESSED; else if (strcmp(*argv, "hybrid") == 0) form = POINT_CONVERSION_HYBRID; else goto bad; } else if (strcmp(*argv, "-param_enc") == 0) { if (--argc < 1) goto bad; ++argv; new_asn1_flag = 1; if (strcmp(*argv, "named_curve") == 0) asn1_flag = OPENSSL_EC_NAMED_CURVE; else if (strcmp(*argv, "explicit") == 0) asn1_flag = 0; else goto bad; } else if (strcmp(*argv, "-no_seed") == 0) no_seed = 1; else if (strcmp(*argv, "-noout") == 0) noout = 1; else if (strcmp(*argv, "-genkey") == 0) { genkey = 1; } else if (strcmp(*argv, "-rand") == 0) { if (--argc < 1) goto bad; inrand = *(++argv); } else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } else { BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, " -inform arg input format - " "default PEM (DER or PEM)\n"); BIO_printf(bio_err, " -outform arg output format - " "default PEM\n"); BIO_printf(bio_err, " -in arg input file - " "default stdin\n"); BIO_printf(bio_err, " -out arg output file - " "default stdout\n"); BIO_printf(bio_err, " -noout do not print the " "ec parameter\n"); BIO_printf(bio_err, " -text print the ec " "parameters in text form\n"); BIO_printf(bio_err, " -check validate the ec " "parameters\n"); BIO_printf(bio_err, " -C print a 'C' " "function creating the parameters\n"); BIO_printf(bio_err, " -name arg use the " "ec parameters with 'short name' name\n"); BIO_printf(bio_err, " -list_curves prints a list of " "all currently available curve 'short names'\n"); BIO_printf(bio_err, " -conv_form arg specifies the " "point conversion form \n"); BIO_printf(bio_err, " possible values:" " compressed\n"); BIO_printf(bio_err, " " " uncompressed (default)\n"); BIO_printf(bio_err, " " " hybrid\n"); BIO_printf(bio_err, " -param_enc arg specifies the way" " the ec parameters are encoded\n"); BIO_printf(bio_err, " in the asn1 der " "encoding\n"); BIO_printf(bio_err, " possible values:" " named_curve (default)\n"); BIO_printf(bio_err, " " " explicit\n"); BIO_printf(bio_err, " -no_seed if 'explicit'" " parameters are chosen do not" " use the seed\n"); BIO_printf(bio_err, " -genkey generate ec" " key\n"); BIO_printf(bio_err, " -rand file files to use for" " random number input\n"); BIO_printf(bio_err, " -engine e use engine e, " "possibly a hardware device\n"); goto end; } ERR_load_crypto_strings(); in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif if (list_curves) { EC_builtin_curve *curves = NULL; size_t crv_len = 0; size_t n = 0; crv_len = EC_get_builtin_curves(NULL, 0); curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve)); if (curves == NULL) goto end; if (!EC_get_builtin_curves(curves, crv_len)) { free(curves); goto end; } for (n = 0; n < crv_len; n++) { const char *comment; const char *sname; comment = curves[n].comment; sname = OBJ_nid2sn(curves[n].nid); if (comment == NULL) comment = "CURVE DESCRIPTION NOT AVAILABLE"; if (sname == NULL) sname = ""; BIO_printf(out, " %-10s: ", sname); BIO_printf(out, "%s\n", comment); } free(curves); ret = 0; goto end; } if (curve_name != NULL) { int nid; /* * workaround for the SECG curve names secp192r1 and * secp256r1 (which are the same as the curves prime192v1 and * prime256v1 defined in X9.62) */ if (!strcmp(curve_name, "secp192r1")) { BIO_printf(bio_err, "using curve name prime192v1 " "instead of secp192r1\n"); nid = NID_X9_62_prime192v1; } else if (!strcmp(curve_name, "secp256r1")) { BIO_printf(bio_err, "using curve name prime256v1 " "instead of secp256r1\n"); nid = NID_X9_62_prime256v1; } else nid = OBJ_sn2nid(curve_name); if (nid == 0) { BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name); goto end; } group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) { BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name); goto end; } EC_GROUP_set_asn1_flag(group, asn1_flag); EC_GROUP_set_point_conversion_form(group, form); } else if (informat == FORMAT_ASN1) { group = d2i_ECPKParameters_bio(in, NULL); } else if (informat == FORMAT_PEM) { group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); } else { BIO_printf(bio_err, "bad input format specified\n"); goto end; } if (group == NULL) { BIO_printf(bio_err, "unable to load elliptic curve parameters\n"); ERR_print_errors(bio_err); goto end; } if (new_form) EC_GROUP_set_point_conversion_form(group, form); if (new_asn1_flag) EC_GROUP_set_asn1_flag(group, asn1_flag); if (no_seed) { EC_GROUP_set_seed(group, NULL, 0); } if (text) { if (!ECPKParameters_print(out, group, 0)) goto end; } if (check) { if (group == NULL) BIO_printf(bio_err, "no elliptic curve parameters\n"); BIO_printf(bio_err, "checking elliptic curve parameters: "); if (!EC_GROUP_check(group, NULL)) { BIO_printf(bio_err, "failed\n"); ERR_print_errors(bio_err); } else BIO_printf(bio_err, "ok\n"); } if (C) { size_t buf_len = 0, tmp_len = 0; const EC_POINT *point; int is_prime, len = 0; const EC_METHOD *meth = EC_GROUP_method_of(group); if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL || (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL || (ec_order = BN_new()) == NULL || (ec_cofactor = BN_new()) == NULL) { perror("malloc"); goto end; } is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); if (is_prime) { if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL)) goto end; } else { /* TODO */ goto end; } if ((point = EC_GROUP_get0_generator(group)) == NULL) goto end; if (!EC_POINT_point2bn(group, point, EC_GROUP_get_point_conversion_form(group), ec_gen, NULL)) goto end; if (!EC_GROUP_get_order(group, ec_order, NULL)) goto end; if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL)) goto end; if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor) goto end; len = BN_num_bits(ec_order); if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len) buf_len = tmp_len; buffer = (unsigned char *) malloc(buf_len); if (buffer == NULL) { perror("malloc"); goto end; } ecparam_print_var(out, ec_p, "ec_p", len, buffer); ecparam_print_var(out, ec_a, "ec_a", len, buffer); ecparam_print_var(out, ec_b, "ec_b", len, buffer); ecparam_print_var(out, ec_gen, "ec_gen", len, buffer); ecparam_print_var(out, ec_order, "ec_order", len, buffer); ecparam_print_var(out, ec_cofactor, "ec_cofactor", len, buffer); BIO_printf(out, "\n\n"); BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len); BIO_printf(out, "\tint ok=0;\n"); BIO_printf(out, "\tEC_GROUP *group = NULL;\n"); BIO_printf(out, "\tEC_POINT *point = NULL;\n"); BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, " "*tmp_3 = NULL;\n\n"); BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, " "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t" "goto err;\n", len, len); BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, " "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t" "goto err;\n", len, len); BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, " "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t" "goto err;\n", len, len); if (is_prime) { BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_" "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)" "\n\t\tgoto err;\n\n"); } else { /* TODO */ goto end; } BIO_printf(out, "\t/* build generator */\n"); BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, " "sizeof(ec_gen_%d), tmp_1)) == NULL)" "\n\t\tgoto err;\n", len, len); BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, " "NULL, NULL);\n"); BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n"); BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, " "sizeof(ec_order_%d), tmp_2)) == NULL)" "\n\t\tgoto err;\n", len, len); BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, " "sizeof(ec_cofactor_%d), tmp_3)) == NULL)" "\n\t\tgoto err;\n", len, len); BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point," " tmp_2, tmp_3))\n\t\tgoto err;\n"); BIO_printf(out, "\n\tok=1;\n"); BIO_printf(out, "err:\n"); BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n"); BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n"); BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n"); BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n"); BIO_printf(out, "\tif (!ok)\n"); BIO_printf(out, "\t\t{\n"); BIO_printf(out, "\t\tEC_GROUP_free(group);\n"); BIO_printf(out, "\t\tgroup = NULL;\n"); BIO_printf(out, "\t\t}\n"); BIO_printf(out, "\treturn(group);\n\t}\n"); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_ECPKParameters_bio(out, group); else if (outformat == FORMAT_PEM) i = PEM_write_bio_ECPKParameters(out, group); else { BIO_printf(bio_err, "bad output format specified for" " outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write elliptic " "curve parameters\n"); ERR_print_errors(bio_err); goto end; } } if (genkey) { EC_KEY *eckey = EC_KEY_new(); if (eckey == NULL) goto end; if (EC_KEY_set_group(eckey, group) == 0) goto end; if (!EC_KEY_generate_key(eckey)) { EC_KEY_free(eckey); goto end; } if (outformat == FORMAT_ASN1) i = i2d_ECPrivateKey_bio(out, eckey); else if (outformat == FORMAT_PEM) i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL); else { BIO_printf(bio_err, "bad output format specified " "for outfile\n"); EC_KEY_free(eckey); goto end; } EC_KEY_free(eckey); } ret = 0; end: if (ec_p) BN_free(ec_p); if (ec_a) BN_free(ec_a); if (ec_b) BN_free(ec_b); if (ec_gen) BN_free(ec_gen); if (ec_order) BN_free(ec_order); if (ec_cofactor) BN_free(ec_cofactor); free(buffer); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (group != NULL) EC_GROUP_free(group); return (ret); }
static int test_builtin(void) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; const unsigned char *sig_ptr; unsigned char *sig_ptr2; unsigned char *raw_buf = NULL; const BIGNUM *sig_r, *sig_s; BIGNUM *modified_r = NULL, *modified_s = NULL; BIGNUM *unmodified_r = NULL, *unmodified_s = NULL; unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ if (!TEST_true(RAND_bytes(digest, 20)) || !TEST_true(RAND_bytes(wrong_digest, 20))) goto builtin_err; /* create and verify a ecdsa signature with every available curve */ /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len)) || !TEST_true(EC_get_builtin_curves(curves, crv_len))) goto builtin_err; /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4 || nid == NID_X25519) continue; /* create new ecdsa key (== EC_KEY) */ if (!TEST_ptr(eckey = EC_KEY_new()) || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) || !TEST_true(EC_KEY_set_group(eckey, group))) goto builtin_err; EC_GROUP_free(group); degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); if (degree < 160) { /* drop the curve */ EC_KEY_free(eckey); eckey = NULL; continue; } TEST_info("testing %s", OBJ_nid2sn(nid)); /* create key */ if (!TEST_true(EC_KEY_generate_key(eckey))) goto builtin_err; /* create second key */ if (!TEST_ptr(wrong_eckey = EC_KEY_new()) || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) || !TEST_true(EC_KEY_set_group(wrong_eckey, group))) goto builtin_err; EC_GROUP_free(group); if (!TEST_true(EC_KEY_generate_key(wrong_eckey))) goto builtin_err; /* check key */ if (!TEST_true(EC_KEY_check_key(eckey))) goto builtin_err; /* create signature */ sig_len = ECDSA_size(eckey); if (!TEST_ptr(signature = OPENSSL_malloc(sig_len)) || !TEST_true(ECDSA_sign(0, digest, 20, signature, &sig_len, eckey))) goto builtin_err; /* verify signature */ if (!TEST_int_eq(ECDSA_verify(0, digest, 20, signature, sig_len, eckey), 1)) goto builtin_err; /* verify signature with the wrong key */ if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey), 1)) goto builtin_err; /* wrong digest */ if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey), 1)) goto builtin_err; /* wrong length */ if (!TEST_int_ne(ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey), 1)) goto builtin_err; /* * Modify a single byte of the signature: to ensure we don't garble * the ASN1 structure, we read the raw signature and modify a byte in * one of the bignums directly. */ sig_ptr = signature; if (!TEST_ptr(ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len))) goto builtin_err; ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s); /* Store the two BIGNUMs in raw_buf. */ r_len = BN_num_bytes(sig_r); s_len = BN_num_bytes(sig_s); bn_len = (degree + 7) / 8; if (!TEST_false(r_len > bn_len) || !TEST_false(s_len > bn_len)) goto builtin_err; buf_len = 2 * bn_len; if (!TEST_ptr(raw_buf = OPENSSL_zalloc(buf_len))) goto builtin_err; BN_bn2bin(sig_r, raw_buf + bn_len - r_len); BN_bn2bin(sig_s, raw_buf + buf_len - s_len); /* Modify a single byte in the buffer. */ offset = raw_buf[10] % buf_len; dirt = raw_buf[11] ? raw_buf[11] : 1; raw_buf[offset] ^= dirt; /* Now read the BIGNUMs back in from raw_buf. */ if (!TEST_ptr(modified_sig = ECDSA_SIG_new())) goto builtin_err; if (!TEST_ptr(modified_r = BN_bin2bn(raw_buf, bn_len, NULL)) || !TEST_ptr(modified_s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) || !TEST_true(ECDSA_SIG_set0(modified_sig, modified_r, modified_s))) { BN_free(modified_r); BN_free(modified_s); goto builtin_err; } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2); if (!TEST_false(ECDSA_verify(0, digest, 20, signature, sig_len, eckey))) goto builtin_err; /* Sanity check: undo the modification and verify signature. */ raw_buf[offset] ^= dirt; if (!TEST_ptr(unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL)) || !TEST_ptr(unmodified_s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) || !TEST_true(ECDSA_SIG_set0(modified_sig, unmodified_r, unmodified_s))) { BN_free(unmodified_r); BN_free(unmodified_s); goto builtin_err; } sig_ptr2 = signature; sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2); if (!TEST_true(ECDSA_verify(0, digest, 20, signature, sig_len, eckey))) goto builtin_err; /* cleanup */ ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; ECDSA_SIG_free(ecdsa_sig); ecdsa_sig = NULL; ECDSA_SIG_free(modified_sig); modified_sig = NULL; OPENSSL_free(raw_buf); raw_buf = NULL; } ret = 1; builtin_err: EC_KEY_free(eckey); EC_KEY_free(wrong_eckey); ECDSA_SIG_free(ecdsa_sig); ECDSA_SIG_free(modified_sig); OPENSSL_free(signature); OPENSSL_free(raw_buf); OPENSSL_free(curves); return ret; }
builtin_curves::builtin_curves() { int i, num_curves = EC_get_builtin_curves(NULL, 0); EC_builtin_curve *curves = (EC_builtin_curve*)OPENSSL_malloc( (int)(sizeof(EC_builtin_curve) *num_curves)); check_oom(curves); BIGNUM *order = BN_new(); check_oom(order); EC_get_builtin_curves(curves, num_curves); for (i=0; i< num_curves; i++) { size_t j; int flag = 0, nid = curves[i].nid; unsigned long type = 0; for (j=0; j<ARRAY_SIZE(x962_curve_nids); j++) { if (x962_curve_nids[j] == nid) { flag = CURVE_X962; break; } } if (!flag) { for (j=0; j<ARRAY_SIZE(other_curve_nids); j++) { if (other_curve_nids[j] == nid) { flag = CURVE_OTHER; break; } } } if (!flag) continue; EC_GROUP *group = EC_GROUP_new_by_curve_name(nid); EC_GROUP_get_order(group, order, NULL); switch (EC_METHOD_get_field_type(EC_GROUP_method_of(group))) { case NID_X9_62_prime_field: type = CKF_EC_F_P; break; case NID_X9_62_characteristic_two_field: type = CKF_EC_F_2M; break; default: continue; } #undef PRINT_KNOWN_CURVES #ifdef PRINT_KNOWN_CURVES fprintf(stderr, "%50s %27s %20s %s\n", curves[i].comment, OBJ_nid2sn(nid), CCHAR(OBJ_obj2QString(OBJ_nid2obj(nid), 1)), type == CKF_EC_F_P ? "Fp" : "F2m"); #endif append(builtin_curve(nid, QString(curves[i].comment), BN_num_bits(order), flag, type)); EC_GROUP_free(group); } BN_free(order); }
int PKI_X509_KEYPAIR_get_curve ( PKI_X509_KEYPAIR *kp ) { #ifdef ENABLE_ECDSA PKI_X509_KEYPAIR_VALUE *pVal = NULL; const EC_GROUP *gr; EC_GROUP *gr2; EC_KEY *ec = NULL; EC_POINT *point = NULL; BN_CTX *ctx = NULL; int ret = PKI_ID_UNKNOWN; EC_builtin_curve *curves = NULL; size_t num_curves = 0; int i; BIGNUM *order; unsigned long long keyBits = 0; unsigned long long curveBits = 0; pVal = kp->value; if (!pVal ) return PKI_ID_UNKNOWN; ctx = BN_CTX_new(); switch (EVP_PKEY_type(pVal->type)) { case EVP_PKEY_EC: ec = pVal->pkey.ec; break; default: return PKI_ID_UNKNOWN; break; }; if (!ec) { return PKI_ID_UNKNOWN; }; if((gr = EC_KEY_get0_group(ec)) == NULL) { return PKI_ID_UNKNOWN; }; order = BN_new(); if (EC_GROUP_get_order(gr, order, NULL)) { keyBits = (unsigned long long) BN_num_bits(order); } BN_free( order ); order = NULL; if((point = EC_POINT_new( gr )) == NULL ) { PKI_log_err("Can not generate a new point in Key's Group"); return PKI_ID_UNKNOWN; }; /* Get the number of availabe ECDSA curves in OpenSSL */ if ((num_curves = EC_get_builtin_curves(NULL, 0)) < 1 ) { /* No curves available! */ return PKI_ID_UNKNOWN; } /* Alloc the needed memory */ curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * (int) num_curves); if (curves == NULL) { return PKI_ID_UNKNOWN; }; /* Get the builtin curves */ if (!EC_get_builtin_curves(curves, num_curves)) { if( curves ) free (curves); return PKI_ID_UNKNOWN; } order = BN_new(); /* Cycle through the curves and display the names */ for( i = 0; i < num_curves; i++ ) { int nid; nid = curves[i].nid; if(( gr2 = EC_GROUP_new_by_curve_name( nid )) == NULL) { PKI_log_err("Can not get default curve [%d]", i); break; }; if (EC_GROUP_get_order(gr2, order, NULL)) { curveBits = (unsigned long long) BN_num_bits(order); }; if ( curveBits == keyBits ) { if( EC_POINT_is_on_curve( gr2, point, ctx ) ) { ret = nid; break; }; }; if( gr2 ) EC_GROUP_free ( gr2 ); }; if ( order ) BN_free ( order ); if( curves ) free ( curves ); BN_CTX_free ( ctx ); return ret; #else return PKI_ID_UNKNOWN; #endif };
int test_builtin(BIO *out) { EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; unsigned char digest[20], wrong_digest[20]; unsigned char *signature = NULL; unsigned int sig_len; int nid, ret = 0; /* fill digest values with some random data */ if (!RAND_pseudo_bytes(digest, 20) || !RAND_pseudo_bytes(wrong_digest, 20)) { BIO_printf(out, "ERROR: unable to get random data\n"); goto builtin_err; } /* create and verify a ecdsa signature with every availble curve * (with ) */ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " "with some internal curves:\n"); /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); if (curves == NULL) { BIO_printf(out, "malloc error\n"); goto builtin_err; } if (!EC_get_builtin_curves(curves, crv_len)) { BIO_printf(out, "unable to get internal curves\n"); goto builtin_err; } /* now create and verify a signature for every curve */ for (n = 0; n < crv_len; n++) { unsigned char dirt, offset; nid = curves[n].nid; if (nid == NID_ipsec4) continue; /* create new ecdsa key (== EC_KEY) */ if ((eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160) /* drop the curve */ { EC_KEY_free(eckey); eckey = NULL; continue; } BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); /* create key */ if (!EC_KEY_generate_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } /* create second key */ if ((wrong_eckey = EC_KEY_new()) == NULL) goto builtin_err; group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) goto builtin_err; if (EC_KEY_set_group(wrong_eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); if (!EC_KEY_generate_key(wrong_eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* check key */ if (!EC_KEY_check_key(eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* create signature */ sig_len = ECDSA_size(eckey); if ((signature = OPENSSL_malloc(sig_len)) == NULL) goto builtin_err; if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature */ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* verify signature with the wrong key */ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* wrong digest */ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); /* modify a single byte of the signature */ offset = signature[10] % sig_len; dirt = signature[11]; signature[offset] ^= dirt ? dirt : 1; if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; } ret = 1; builtin_err: if (eckey) EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); if (signature) OPENSSL_free(signature); if (curves) OPENSSL_free(curves); return ret; }
int ecparam_main(int argc, char **argv) { BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL; BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL; BIO *in = NULL, *out = NULL; EC_GROUP *group = NULL; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; char *curve_name = NULL, *inrand = NULL; char *infile = NULL, *outfile = NULL, *prog; unsigned char *buffer = NULL; OPTION_CHOICE o; int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret = 1; int list_curves = 0, no_seed = 0, check = 0, new_form = 0; int text = 0, i, need_rand = 0, genkey = 0; prog = opt_init(argc, argv, ecparam_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(ecparam_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_TEXT: text = 1; break; case OPT_C: C = 1; break; case OPT_CHECK: check = 1; break; case OPT_LIST_CURVES: list_curves = 1; break; case OPT_NO_SEED: no_seed = 1; break; case OPT_NOOUT: noout = 1; break; case OPT_NAME: curve_name = opt_arg(); break; case OPT_CONV_FORM: if (!opt_pair(opt_arg(), forms, &new_form)) goto opthelp; form = new_form; new_form = 1; break; case OPT_PARAM_ENC: if (!opt_pair(opt_arg(), encodings, &asn1_flag)) goto opthelp; new_asn1_flag = 1; break; case OPT_GENKEY: genkey = need_rand = 1; break; case OPT_RAND: inrand = opt_arg(); need_rand = 1; break; case OPT_ENGINE: (void)setup_engine(opt_arg(), 0); break; } } argc = opt_num_rest(); argv = opt_rest(); in = bio_open_default(infile, RB(informat)); if (in == NULL) goto end; out = bio_open_default(outfile, WB(outformat)); if (out == NULL) goto end; if (list_curves) { EC_builtin_curve *curves = NULL; size_t crv_len = EC_get_builtin_curves(NULL, 0); size_t n; curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves"); if (!EC_get_builtin_curves(curves, crv_len)) { OPENSSL_free(curves); goto end; } for (n = 0; n < crv_len; n++) { const char *comment; const char *sname; comment = curves[n].comment; sname = OBJ_nid2sn(curves[n].nid); if (comment == NULL) comment = "CURVE DESCRIPTION NOT AVAILABLE"; if (sname == NULL) sname = ""; BIO_printf(out, " %-10s: ", sname); BIO_printf(out, "%s\n", comment); } OPENSSL_free(curves); ret = 0; goto end; } if (curve_name != NULL) { int nid; /* * workaround for the SECG curve names secp192r1 and secp256r1 (which * are the same as the curves prime192v1 and prime256v1 defined in * X9.62) */ if (strcmp(curve_name, "secp192r1") == 0) { BIO_printf(bio_err, "using curve name prime192v1 " "instead of secp192r1\n"); nid = NID_X9_62_prime192v1; } else if (strcmp(curve_name, "secp256r1") == 0) { BIO_printf(bio_err, "using curve name prime256v1 " "instead of secp256r1\n"); nid = NID_X9_62_prime256v1; } else nid = OBJ_sn2nid(curve_name); if (nid == 0) nid = EC_curve_nist2nid(curve_name); if (nid == 0) { BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name); goto end; } group = EC_GROUP_new_by_curve_name(nid); if (group == NULL) { BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name); goto end; } EC_GROUP_set_asn1_flag(group, asn1_flag); EC_GROUP_set_point_conversion_form(group, form); } else if (informat == FORMAT_ASN1) group = d2i_ECPKParameters_bio(in, NULL); else group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); if (group == NULL) { BIO_printf(bio_err, "unable to load elliptic curve parameters\n"); ERR_print_errors(bio_err); goto end; } if (new_form) EC_GROUP_set_point_conversion_form(group, form); if (new_asn1_flag) EC_GROUP_set_asn1_flag(group, asn1_flag); if (no_seed) { EC_GROUP_set_seed(group, NULL, 0); } if (text) { if (!ECPKParameters_print(out, group, 0)) goto end; } if (check) { if (group == NULL) BIO_printf(bio_err, "no elliptic curve parameters\n"); BIO_printf(bio_err, "checking elliptic curve parameters: "); if (!EC_GROUP_check(group, NULL)) { BIO_printf(bio_err, "failed\n"); ERR_print_errors(bio_err); } else BIO_printf(bio_err, "ok\n"); } if (C) { size_t buf_len = 0, tmp_len = 0; const EC_POINT *point; int is_prime, len = 0; const EC_METHOD *meth = EC_GROUP_method_of(group); if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL || (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL || (ec_order = BN_new()) == NULL || (ec_cofactor = BN_new()) == NULL) { perror("Can't allocate BN"); goto end; } is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); if (!is_prime) { BIO_printf(bio_err, "Can only handle X9.62 prime fields\n"); goto end; } if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL)) goto end; if ((point = EC_GROUP_get0_generator(group)) == NULL) goto end; if (!EC_POINT_point2bn(group, point, EC_GROUP_get_point_conversion_form(group), ec_gen, NULL)) goto end; if (!EC_GROUP_get_order(group, ec_order, NULL)) goto end; if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL)) goto end; if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor) goto end; len = BN_num_bits(ec_order); if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len) buf_len = tmp_len; if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len) buf_len = tmp_len; buffer = app_malloc(buf_len, "BN buffer"); BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len); print_bignum_var(out, ec_p, "ec_p", len, buffer); print_bignum_var(out, ec_a, "ec_a", len, buffer); print_bignum_var(out, ec_b, "ec_b", len, buffer); print_bignum_var(out, ec_gen, "ec_gen", len, buffer); print_bignum_var(out, ec_order, "ec_order", len, buffer); print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer); BIO_printf(out, " int ok = 0;\n" " EC_GROUP *group = NULL;\n" " EC_POINT *point = NULL;\n" " BIGNUM *tmp_1 = NULL;\n" " BIGNUM *tmp_2 = NULL;\n" " BIGNUM *tmp_3 = NULL;\n" "\n"); BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n" " goto err;\n", len, len); BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n" " goto err;\n", len, len); BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n" " goto err;\n", len, len); BIO_printf(out, " if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n" " goto err;\n" "\n"); BIO_printf(out, " /* build generator */\n"); BIO_printf(out, " if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n" " goto err;\n", len, len); BIO_printf(out, " point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n"); BIO_printf(out, " if (point == NULL)\n" " goto err;\n"); BIO_printf(out, " if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n" " goto err;\n", len, len); BIO_printf(out, " if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n" " goto err;\n", len, len); BIO_printf(out, " if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n" " goto err;\n" "ok = 1;" "\n"); BIO_printf(out, "err:\n" " BN_free(tmp_1);\n" " BN_free(tmp_2);\n" " BN_free(tmp_3);\n" " EC_POINT_free(point);\n" " if (!ok) {\n" " EC_GROUP_free(group);\n" " return NULL;\n" " }\n" " return (group);\n" "}\n"); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_ECPKParameters_bio(out, group); else i = PEM_write_bio_ECPKParameters(out, group); if (!i) { BIO_printf(bio_err, "unable to write elliptic " "curve parameters\n"); ERR_print_errors(bio_err); goto end; } } if (need_rand) { app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } if (genkey) { EC_KEY *eckey = EC_KEY_new(); if (eckey == NULL) goto end; assert(need_rand); if (EC_KEY_set_group(eckey, group) == 0) goto end; if (!EC_KEY_generate_key(eckey)) { EC_KEY_free(eckey); goto end; } if (outformat == FORMAT_ASN1) i = i2d_ECPrivateKey_bio(out, eckey); else i = PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL); EC_KEY_free(eckey); } if (need_rand) app_RAND_write_file(NULL); ret = 0; end: BN_free(ec_p); BN_free(ec_a); BN_free(ec_b); BN_free(ec_gen); BN_free(ec_order); BN_free(ec_cofactor); OPENSSL_free(buffer); BIO_free(in); BIO_free_all(out); EC_GROUP_free(group); return (ret); }
int main(int argc, char *argv[]) { BN_CTX *ctx = NULL; int nid, ret = 1; EC_builtin_curve *curves = NULL; size_t crv_len = 0, n = 0; BIO *out; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); RAND_seed(rnd_seed, sizeof rnd_seed); out = BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); if ((ctx = BN_CTX_new()) == NULL) goto err; /* get a list of all internal curves */ crv_len = EC_get_builtin_curves(NULL, 0); curves = OPENSSL_malloc(sizeof(*curves) * crv_len); if (curves == NULL) goto err; if (!EC_get_builtin_curves(curves, crv_len)) goto err; /* NAMED CURVES TESTS */ for (n = 0; n < crv_len; n++) { nid = curves[n].nid; /* * Skipped for X25519 because affine coordinate operations are not * supported for this curve. * Higher level ECDH tests are performed in evptests.txt instead. */ if (nid == NID_X25519) continue; if (!test_ecdh_curve(nid, ctx, out)) goto err; } /* KATs */ for (n = 0; n < (sizeof(ecdh_kats)/sizeof(ecdh_kat_t)); n++) { if (!ecdh_kat(out, &ecdh_kats[n])) goto err; } /* NIST SP800-56A co-factor ECDH KATs */ for (n = 0; n < (sizeof(ecdh_cavs_kats)/sizeof(ecdh_cavs_kat_t)); n++) { if (!ecdh_cavs_kat(out, &ecdh_cavs_kats[n])) goto err; } ret = 0; err: ERR_print_errors_fp(stderr); OPENSSL_free(curves); BN_CTX_free(ctx); BIO_free(out); #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) ret = 1; #endif EXIT(ret); }