EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { const EC_METHOD *meth; EC_GROUP *ret; meth = EC_GFp_nist_method(); ret = EC_GROUP_new(meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { unsigned long err; err = ERR_peek_last_error(); if (!(ERR_GET_LIB(err) == ERR_LIB_EC && ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) { /* real error */ EC_GROUP_clear_free(ret); return NULL; } /* not an actual error, we just cannot use EC_GFp_nist_method */ ERR_clear_error(); EC_GROUP_clear_free(ret); meth = EC_GFp_mont_method(); ret = EC_GROUP_new(meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { EC_GROUP_clear_free(ret); return NULL; } } return ret; }
/***************************************************************************//** * Delete all Mikey Sakke parameter set data. ******************************************************************************/ void ms_deleteParameterSets() { int c = 0; for (c = 0; c < MAX_ES_PARAMETER_SETS; c++) { if (NULL != ms_parameter_sets[c].p) { BN_clear_free(ms_parameter_sets[c].p); } if (NULL != ms_parameter_sets[c].q) { BN_clear_free(ms_parameter_sets[c].q); } if (NULL != ms_parameter_sets[c].Px) { BN_clear_free(ms_parameter_sets[c].Px); } if (NULL != ms_parameter_sets[c].Py) { BN_clear_free(ms_parameter_sets[c].Py); } if (NULL != ms_parameter_sets[c].g) { BN_clear_free(ms_parameter_sets[c].g); } if (NULL != ms_parameter_sets[c].E) { EC_GROUP_clear_free(ms_parameter_sets[c].E); } if (NULL != ms_parameter_sets[c].P) { EC_POINT_clear_free(ms_parameter_sets[c].P); } memset(&ms_parameter_sets[c], 0, sizeof(struct msParameterSet_t)); } ms_parameter_sets_initialised = ES_FALSE; } /* ms_deleteParameterSets */
int finaliseRingSigs() { if (fDebugRingSig) LogPrintf("finaliseRingSigs()\n"); BN_free(bnOrder); BN_CTX_free(bnCtx); EC_GROUP_clear_free(ecGrp); EC_GROUP_clear_free(ecGrpKi); ecGrp = NULL; ecGrpKi = NULL; bnCtx = NULL; bnOrder = NULL; return 0; };
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { const EC_METHOD *meth; EC_GROUP *ret; #if defined(OPENSSL_BN_ASM_MONT) /* * This might appear controversial, but the fact is that generic * prime method was observed to deliver better performance even * for NIST primes on a range of platforms, e.g.: 60%-15% * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% * in 32-bit build and 35%--12% in 64-bit build on Core2... * Coefficients are relative to optimized bn_nist.c for most * intensive ECDSA verify and ECDH operations for 192- and 521- * bit keys respectively. Choice of these boundary values is * arguable, because the dependency of improvement coefficient * from key length is not a "monotone" curve. For example while * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's * generally faster, sometimes "respectfully" faster, sometimes * "tolerably" slower... What effectively happens is that loop * with bn_mul_add_words is put against bn_mul_mont, and the * latter "wins" on short vectors. Correct solution should be * implementing dedicated NxN multiplication subroutines for * small N. But till it materializes, let's stick to generic * prime method... * <appro> */ meth = EC_GFp_mont_method(); #else if (BN_nist_mod_func(p)) meth = EC_GFp_nist_method(); else meth = EC_GFp_mont_method(); #endif ret = EC_GROUP_new(meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) { EC_GROUP_clear_free(ret); return NULL; } return ret; }
EC_GROUP * EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { const EC_METHOD *meth; EC_GROUP *ret; meth = EC_GF2m_simple_method(); ret = EC_GROUP_new(meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) { EC_GROUP_clear_free(ret); return NULL; } return ret; }
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { const EC_METHOD *meth; EC_GROUP *ret; # ifdef OPENSSL_FIPS if (FIPS_mode()) return FIPS_ec_group_new_curve_gf2m(p, a, b, ctx); # endif meth = EC_GF2m_simple_method(); ret = EC_GROUP_new(meth); if (ret == NULL) return NULL; if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) { EC_GROUP_clear_free(ret); return NULL; } return ret; }
jbyteArray Java_ru_ivanovpv_gorets_psm_nativelib_NativeLib_getECSharedKey( JNIEnv* env, jobject thiz, jbyteArray privKey, jbyteArray pubKey, jint ecGroup) { EC_GROUP * ec_group = NULL; EC_POINT * ec_pub = NULL; EC_POINT * ec_res = NULL; BN_CTX * bn_ctx = NULL; BIGNUM * bn_priv = NULL; jbyte * privKeyArr = NULL; jbyte * pubKeyArr = NULL; jbyteArray resKey = NULL; jbyte resKeyArr[MAX_EC_KEY_SIZE]; jint privKeySize = 0; jint pubKeySize = 0; size_t resKeySize = 0; if ( ((ecGroup != 1) && (ecGroup != 2) && (ecGroup != 3)) || (privKey == NULL) || (pubKey == NULL) ) { goto cleanup; } privKeySize = (*env)->GetArrayLength(env, privKey); pubKeySize = (*env)->GetArrayLength(env, pubKey); if ( (privKeySize <= 0) || (pubKeySize <= 0) ) { goto cleanup; } switch(ecGroup) { case 1: if ( ( privKeySize < (112/8) ) || ( pubKeySize < (112/8+1) ) ) goto cleanup; ec_group = EC_GROUP_new_by_curve_name(NID_secp112r1); break; case 2: if ( ( privKeySize < (256/8) ) || ( pubKeySize < (256/8+1) ) ) goto cleanup; ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); break; case 3: if ( ( privKeySize < (384/8) ) || ( pubKeySize < (384/8+1) ) ) goto cleanup; ec_group = EC_GROUP_new_by_curve_name(NID_secp384r1); break; default: goto cleanup; } if (!ec_group) { goto cleanup; } if( (bn_priv = BN_new()) == NULL) { goto cleanup; } if( (privKeyArr = (*env)->GetByteArrayElements(env, privKey, NULL)) == NULL ) { goto cleanup; } if ( BN_bin2bn((const unsigned char *)privKeyArr, (int) privKeySize, bn_priv) == NULL ) { goto cleanup; } if ( (bn_ctx = BN_CTX_new()) == NULL ) { goto cleanup; } if ( (ec_pub = EC_POINT_new(ec_group)) == NULL) { goto cleanup; } if( (pubKeyArr = (*env)->GetByteArrayElements(env, pubKey, NULL)) == NULL ) { goto cleanup; } if ( EC_POINT_oct2point((const EC_GROUP *) ec_group, (EC_POINT *) ec_pub, (unsigned char *) pubKeyArr, (size_t) pubKeySize, bn_ctx) == 0 ) { goto cleanup; } if ( (ec_res = EC_POINT_new(ec_group)) == NULL) { goto cleanup; } if (!EC_POINT_mul((const EC_GROUP *) ec_group, ec_res, (const BIGNUM *)NULL, ec_pub, bn_priv, bn_ctx)) { goto cleanup; } if ( (resKeySize = EC_POINT_point2oct((const EC_GROUP *) ec_group, (const EC_POINT *) ec_res, POINT_CONVERSION_COMPRESSED, (unsigned char *) resKeyArr, (size_t) MAX_EC_KEY_SIZE, bn_ctx)) == 0 ) { goto cleanup; } resKey = (*env)->NewByteArray(env, resKeySize); if (resKey == NULL) { goto cleanup; } (*env)->SetByteArrayRegion(env, resKey, 0, resKeySize, (const jbyte*)resKeyArr); memset (resKeyArr, 0, resKeySize); cleanup: if ( ec_group ) EC_GROUP_clear_free( ec_group ); if ( ec_pub ) EC_POINT_clear_free( ec_pub ); if ( ec_res ) EC_POINT_clear_free( ec_res ); if ( bn_priv ) BN_clear_free( bn_priv ); if ( privKeyArr ) (*env)->ReleaseByteArrayElements(env, privKey, privKeyArr, JNI_ABORT); if ( pubKeyArr ) (*env)->ReleaseByteArrayElements(env, pubKey, pubKeyArr, JNI_ABORT); return resKey; }
int ecdh_gm_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * mem_h = NULL; BIGNUM * bn_s = NULL, *order = NULL, *cofactor = NULL; EC_POINT * ecp_h = NULL, *ecp_g = NULL; const ECDH_METHOD *default_method; EC_GROUP *group = NULL; EC_KEY *static_key = NULL, *ephemeral_key = NULL; BN_CTX_start(bn_ctx); check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments"); static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key); check(static_key, "could not get key object"); /* Extract group parameters */ group = EC_GROUP_dup(EC_KEY_get0_group(static_key)); order = BN_CTX_get(bn_ctx); cofactor = BN_CTX_get(bn_ctx); check(group && cofactor, "internal error"); if (!EC_GROUP_get_order(group, order, bn_ctx) || !EC_GROUP_get_cofactor(group, cofactor, bn_ctx)) goto err; /* Convert nonce to BIGNUM */ bn_s = BN_bin2bn((unsigned char *) s->data, s->length, bn_s); if (!bn_s) goto err; default_method = ECDH_get_default_method(); ECDH_set_default_method(ECDH_OpenSSL_Point()); /* complete the ECDH and get the resulting point h */ mem_h = ecdh_compute_key(ctx->static_key, in, bn_ctx); ECDH_set_default_method(default_method); ecp_h = EC_POINT_new(group); if (!mem_h || !ecp_h || !EC_POINT_oct2point(group, ecp_h, (unsigned char *) mem_h->data, mem_h->length, bn_ctx)) goto err; /* map to new generator */ ecp_g = EC_POINT_new(group); /* g' = g*s + h*1 */ if (!EC_POINT_mul(group, ecp_g, bn_s, ecp_h, BN_value_one(), bn_ctx)) goto err; /* Initialize ephemeral parameters with parameters from the static key */ ephemeral_key = EC_KEY_dup(static_key); if (!ephemeral_key) goto err; EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key); /* configure the new EC_KEY */ if (!EC_GROUP_set_generator(group, ecp_g, order, cofactor) || !EC_GROUP_check(group, bn_ctx) || !EC_KEY_set_group(ephemeral_key, group)) goto err; ret = 1; err: if (ecp_g) EC_POINT_clear_free(ecp_g); if (ecp_h) EC_POINT_clear_free(ecp_h); if (mem_h) BUF_MEM_free(mem_h); if (bn_s) BN_clear_free(bn_s); BN_CTX_end(bn_ctx); /* Decrement reference count, keys are still available via PACE_CTX */ if (static_key) EC_KEY_free(static_key); if (ephemeral_key) EC_KEY_free(ephemeral_key); if (group) EC_GROUP_clear_free(group); return ret; }
int generatePem(char **pem) { int returnError = NOERROR; char * errorMessage = ""; char *pemholder = calloc(240, sizeof(char)); EC_KEY *eckey = NULL; BIO *out = NULL; BUF_MEM *buf = NULL; EC_GROUP *group = NULL; if ((out = BIO_new(BIO_s_mem())) == NULL) { returnError = ERROR; errorMessage = "Error in BIO_new(BIO_s_mem())"; goto clearVariables; } if ((group = EC_GROUP_new_by_curve_name(NID_secp256k1)) == NULL) { returnError = ERROR; errorMessage = "Error in EC_GROUP_new_by_curve_name(NID_secp256k1))"; goto clearVariables; } if (((eckey = EC_KEY_new()) == NULL) || ((buf = BUF_MEM_new()) == NULL)) { returnError = ERROR; errorMessage = "Error in EC_KEY_new())"; goto clearVariables; }; if (createNewKey(group, eckey) == ERROR) { returnError = ERROR; errorMessage = "Error in createNewKey(group, eckey)"; goto clearVariables; } if (PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL) == 0) { returnError = ERROR; errorMessage = "Error in PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL, NULL)"; goto clearVariables; } BIO_get_mem_ptr(out, &buf); memcpy(pemholder, buf->data, 224); if (buf->data[218] == '\n') { pemholder[219] = '\0'; memcpy(*pem, pemholder, 220); } else if ( buf->data[219] == '\n') { pemholder[220] = '\0'; memcpy(*pem, pemholder, 221); } else if ( buf->data[221] == '\n') { pemholder[222] = '\0'; memcpy(*pem, pemholder, 223); } else if (buf->data[222] == '\n') { pemholder[223] = '\0'; memcpy(*pem, pemholder, 224); } else { returnError = ERROR; errorMessage = "Invalid PEM generated"; goto clearVariables; } goto clearVariables; clearVariables: if (group != NULL) EC_GROUP_clear_free(group); if (pemholder != NULL) free(pemholder); if (eckey != NULL) EC_KEY_free(eckey); if (out != NULL) BIO_free_all(out); if (errorMessage[0] != '\0') printf("Error: %s\n", errorMessage); return returnError; };