/*! * \brief Decode ECDSA public key from RDATA and set it into EC key. * \note DNSKEY format for ECDSA is described in RFC 6605 section 4. */ static int ecdsa_set_public_key(const knot_binary_t *rdata, EC_KEY *ec_key) { assert(rdata); assert(ec_key); const uint8_t *pubkey_data = NULL; size_t pubkey_size = 0; if (!any_dnskey_get_pubkey(rdata, &pubkey_data, &pubkey_size)) { return KNOT_EINVAL; } if (pubkey_size % 2 != 0) { return KNOT_EINVAL; } size_t param_size = pubkey_size / 2; const uint8_t *x_ptr = pubkey_data; const uint8_t *y_ptr = pubkey_data + param_size; BIGNUM *x = BN_bin2bn(x_ptr, param_size, NULL); BIGNUM *y = BN_bin2bn(y_ptr, param_size, NULL); int result = EC_KEY_set_public_key_affine_coordinates(ec_key, x, y); BN_free(x); BN_free(y); return result == 1 ? KNOT_EOK : KNOT_DNSSEC_EINVALID_KEY; }
static EC_KEY *self_test_ecdsa_key(void) { static const uint8_t kQx[] = { 0xc8, 0x15, 0x61, 0xec, 0xf2, 0xe5, 0x4e, 0xde, 0xfe, 0x66, 0x17, 0xdb, 0x1c, 0x7a, 0x34, 0xa7, 0x07, 0x44, 0xdd, 0xb2, 0x61, 0xf2, 0x69, 0xb8, 0x3d, 0xac, 0xfc, 0xd2, 0xad, 0xe5, 0xa6, 0x81, }; static const uint8_t kQy[] = { 0xe0, 0xe2, 0xaf, 0xa3, 0xf9, 0xb6, 0xab, 0xe4, 0xc6, 0x98, 0xef, 0x64, 0x95, 0xf1, 0xbe, 0x49, 0xa3, 0x19, 0x6c, 0x50, 0x56, 0xac, 0xb3, 0x76, 0x3f, 0xe4, 0x50, 0x7e, 0xec, 0x59, 0x6e, 0x88, }; static const uint8_t kD[] = { 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77, }; EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL); BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL); BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL); if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL || !EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) || !EC_KEY_set_private_key(ec_key, d)) { EC_KEY_free(ec_key); ec_key = NULL; } BN_free(qx); BN_free(qy); BN_free(d); return ec_key; }
int FIPS_selftest_ecdsa() { EC_KEY *ec = NULL; BIGNUM *x = NULL, *y = NULL, *d = NULL; EVP_PKEY pk; int rv = 0; size_t i; for (i = 0; i < sizeof(test_ec_data)/sizeof(EC_SELFTEST_DATA); i++) { EC_SELFTEST_DATA *ecd = test_ec_data + i; x = BN_bin2bn(ecd->x, ecd->xlen, x); y = BN_bin2bn(ecd->y, ecd->ylen, y); d = BN_bin2bn(ecd->d, ecd->dlen, d); if (!x || !y || !d) goto err; ec = EC_KEY_new_by_curve_name(ecd->curve); if (!ec) goto err; if (!EC_KEY_set_public_key_affine_coordinates(ec, x, y)) goto err; if (!EC_KEY_set_private_key(ec, d)) goto err; pk.type = EVP_PKEY_EC; pk.pkey.ec = ec; if (!fips_pkey_signature_test(FIPS_TEST_SIGNATURE, &pk, NULL, 0, NULL, 0, EVP_sha512(), 0, ecd->name)) goto err; EC_KEY_free(ec); ec = NULL; } rv = 1; err: if (x) BN_clear_free(x); if (y) BN_clear_free(y); if (d) BN_clear_free(d); if (ec) EC_KEY_free(ec); return rv; }
openssl::Key BackendOpenSsl::internal_public_key(const ecdsa256::PublicKey& generic) const { openssl::Key key(NID_X9_62_prime256v1); openssl::BigNumber x(generic.x); openssl::BigNumber y(generic.y); EC_KEY_set_public_key_affine_coordinates(key, x, y); openssl::check(EC_KEY_check_key(key)); return key; }
Handle<ScopedEVP_PKEY> JwkEc::To(int &key_type) { LOG_FUNC(); LOG_INFO("Check key_type"); if (!(key_type == NODESSL_KT_PRIVATE || key_type == NODESSL_KT_PUBLIC)) { THROW_ERROR("Wrong value of key_type"); } LOG_INFO("import EC from JWK"); ScopedEC_KEY ec_key(EC_KEY_new()); LOG_INFO("set public key"); ScopedEC_GROUP group(EC_GROUP_new_by_curve_name(this->crv)); if (group.isEmpty()) { THROW_OPENSSL("EC_GROUP_new_by_curve_name"); } EC_KEY_set_group(ec_key.Get(), group.Get()); ScopedBIGNUM x(BN_dup(this->x.Get())); ScopedBIGNUM y(BN_dup(this->y.Get())); if (EC_KEY_set_public_key_affine_coordinates(ec_key.Get(), x.Get(), y.Get()) != 1) { THROW_OPENSSL("EC_KEY_set_public_key_affine_coordinates"); } x.unref(); y.unref(); if (key_type == NODESSL_KT_PRIVATE) { LOG_INFO("set private key"); ScopedBIGNUM d(BN_dup(this->d.Get())); if (EC_KEY_set_private_key(ec_key.Get(), d.Get()) != 1) { THROW_OPENSSL("EC_KEY_set_private_key"); } d.unref(); } LOG_INFO("set internal key"); Handle<ScopedEVP_PKEY> new_key(new ScopedEVP_PKEY(EVP_PKEY_new())); EVP_PKEY_assign_EC_KEY(new_key->Get(), ec_key.Get()); ec_key.unref(); return new_key; }
static int PKV(FILE *in, FILE *out) { char buf[2048], lbuf[2048]; char *keyword, *value; int curve_nid = NID_undef; BIGNUM *Qx = NULL, *Qy = NULL; EC_KEY *key = NULL; while (fgets(buf, sizeof buf, in) != NULL) { fputs(buf, out); if (*buf == '[' && buf[2] == '-') { curve_nid = elookup_curve(buf, lbuf, NULL); if (curve_nid == NID_undef) return 0; } if (!parse_line(&keyword, &value, lbuf, buf)) continue; if (!strcmp(keyword, "Qx")) { if (!do_hex2bn(&Qx, value)) { fprintf(stderr, "Invalid Qx value\n"); return 0; } } if (!strcmp(keyword, "Qy")) { int rv; if (!do_hex2bn(&Qy, value)) { fprintf(stderr, "Invalid Qy value\n"); return 0; } key = EC_KEY_new_by_curve_name(curve_nid); no_err = 1; rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy); no_err = 0; EC_KEY_free(key); fprintf(out, "Result = %s" RESP_EOL, rv ? "P" : "F"); } } BN_free(Qx); BN_free(Qy); return 1; }
SEXP R_ecdsa_pubkey_build(SEXP x, SEXP y, SEXP nist){ #ifndef OPENSSL_NO_EC int nid = my_nist2nid(CHAR(STRING_ELT(nist, 0))); bail(nid); EC_KEY *pubkey = EC_KEY_new_by_curve_name(nid); EC_KEY_set_asn1_flag(pubkey, OPENSSL_EC_NAMED_CURVE); if(!EC_KEY_set_public_key_affine_coordinates(pubkey, new_bignum_from_r(x), new_bignum_from_r(y))) error("Failed to construct EC key. Perhaps invalid point or curve."); unsigned char *buf = NULL; int len = i2d_EC_PUBKEY(pubkey, &buf); bail(len); EC_KEY_free(pubkey); SEXP res = allocVector(RAWSXP, len); memcpy(RAW(res), buf, len); OPENSSL_free(buf); return res; #else //OPENSSL_NO_EC Rf_error("OpenSSL has been configured without EC support"); #endif //OPENSSL_NO_EC }
jlong Java_org_keysupport_provider_ECDSASignature_jniVerifyInit(JNIEnv *env, jobject obj, jint jcid, jbyteArray jx, jbyteArray jy) { // LOGD("entering ECDSASignature_jniVerifyInit"); EC_Ctx *ec = 0; BIGNUM *x, *y; if (!(ec = (EC_Ctx *) calloc(sizeof(EC_Ctx), 1))) { throw_exception(env, "java/lang/RuntimeException", "allocating EC_Ctx"); destroy_ec_ctx(ec); return 0; } if (!(ec->ec = EC_KEY_new_by_curve_name(jcid))) { throw_exception(env, "java/lang/RuntimeException", "allocating EC_KEY"); destroy_ec_ctx(ec); return 0; } if (!jba_to_bigint(env, &x, jx)) { throw_exception(env, "java/lang/RuntimeException", "importing affine coordinate x"); destroy_ec_ctx(ec); return 0; } if (!jba_to_bigint(env, &y, jy)) { throw_exception(env, "java/lang/RuntimeException", "importing affine coordinate y"); destroy_ec_ctx(ec); return 0; } if (!(EC_KEY_set_public_key_affine_coordinates(ec->ec, x, y))) { LOGE("Failed to set EC_KEY affine coordinates"); throw_exception(env, "java/lang/RuntimeException", "setting EC_KEY affine coordinates"); destroy_ec_ctx(ec); return 0; } // LOGD("leaving ECDSASignature_jniVerifyInit"); return ((long) ec); }
/* * verify EC signature on JWT */ static apr_byte_t apr_jws_verify_ec(apr_pool_t *pool, apr_jwt_t *jwt, apr_jwk_t *jwk, apr_jwt_error_t *err) { int nid = apr_jws_ec_alg_to_curve(jwt->header.alg); if (nid == -1) { apr_jwt_error(err, "no OpenSSL Elliptic Curve identifier found for algorithm \"%s\"", jwt->header.alg); return FALSE; } EC_GROUP *curve = EC_GROUP_new_by_curve_name(nid); if (curve == NULL) { apr_jwt_error(err, "no OpenSSL Elliptic Curve found for algorithm \"%s\"", jwt->header.alg); return FALSE; } apr_byte_t rc = FALSE; /* get the OpenSSL digest function */ const EVP_MD *digest = NULL; if ((digest = apr_jws_crypto_alg_to_evp(pool, jwt->header.alg, err)) == NULL) return FALSE; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); EC_KEY * pubkey = EC_KEY_new(); EC_KEY_set_group(pubkey, curve); BIGNUM * x = BN_new(); BIGNUM * y = BN_new(); BN_bin2bn(jwk->key.ec->x, jwk->key.ec->x_len, x); BN_bin2bn(jwk->key.ec->y, jwk->key.ec->y_len, y); if (!EC_KEY_set_public_key_affine_coordinates(pubkey, x, y)) { apr_jwt_error_openssl(err, "EC_KEY_set_public_key_affine_coordinates"); return FALSE; } EVP_PKEY* pEcKey = EVP_PKEY_new(); if (!EVP_PKEY_assign_EC_KEY(pEcKey, pubkey)) { pEcKey = NULL; apr_jwt_error_openssl(err, "EVP_PKEY_assign_EC_KEY"); goto end; } ctx.pctx = EVP_PKEY_CTX_new(pEcKey, NULL); if (!EVP_PKEY_verify_init(ctx.pctx)) { apr_jwt_error_openssl(err, "EVP_PKEY_verify_init"); goto end; } if (!EVP_VerifyInit_ex(&ctx, digest, NULL)) { apr_jwt_error_openssl(err, "EVP_VerifyInit_ex"); goto end; } if (!EVP_VerifyUpdate(&ctx, jwt->message, strlen(jwt->message))) { apr_jwt_error_openssl(err, "EVP_VerifyUpdate"); goto end; } if (!EVP_VerifyFinal(&ctx, (const unsigned char *) jwt->signature.bytes, jwt->signature.length, pEcKey)) { apr_jwt_error_openssl(err, "wrong key? EVP_VerifyFinal"); goto end; } rc = TRUE; end: if (pEcKey) { EVP_PKEY_free(pEcKey); } else if (pubkey) { EC_KEY_free(pubkey); } EVP_MD_CTX_cleanup(&ctx); return rc; }
int FIPS_selftest_ecdh(void) { EC_KEY *ec1 = NULL, *ec2 = NULL; const EC_POINT *ecp = NULL; BIGNUM *x = NULL, *y = NULL, *d = NULL; unsigned char *ztmp = NULL; int rv = 1; size_t i; for (i = 0; i < sizeof(test_ecdh_data) / sizeof(ECDH_SELFTEST_DATA); i++) { ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i; if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0)) continue; ztmp = OPENSSL_malloc(ecd->zlen); x = BN_bin2bn(ecd->x1, ecd->x1len, x); y = BN_bin2bn(ecd->y1, ecd->y1len, y); d = BN_bin2bn(ecd->d1, ecd->d1len, d); if (!x || !y || !d || !ztmp) { rv = -1; goto err; } ec1 = EC_KEY_new_by_curve_name(ecd->curve); if (!ec1) { rv = -1; goto err; } EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) { rv = -1; goto err; } if (!EC_KEY_set_private_key(ec1, d)) { rv = -1; goto err; } x = BN_bin2bn(ecd->x2, ecd->x2len, x); y = BN_bin2bn(ecd->y2, ecd->y2len, y); if (!x || !y) { rv = -1; goto err; } ec2 = EC_KEY_new_by_curve_name(ecd->curve); if (!ec2) { rv = -1; goto err; } EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) { rv = -1; goto err; } ecp = EC_KEY_get0_public_key(ec2); if (!ecp) { rv = -1; goto err; } if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) { rv = -1; goto err; } if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL)) ztmp[0] ^= 0x1; if (memcmp(ztmp, ecd->z, ecd->zlen)) { fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0); rv = 0; } else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0)) goto err; EC_KEY_free(ec1); ec1 = NULL; EC_KEY_free(ec2); ec2 = NULL; OPENSSL_free(ztmp); ztmp = NULL; } err: if (x) BN_clear_free(x); if (y) BN_clear_free(y); if (d) BN_clear_free(d); if (ec1) EC_KEY_free(ec1); if (ec2) EC_KEY_free(ec2); if (ztmp) OPENSSL_free(ztmp); return rv; }
// unsigned char *rgbHashData, 哈希数值 // unsigned char *rgbKeyPb, SM2公钥数据,Px Py 不含标志位 point_conversion_form_t // unsigned char *rs 待验证的签名数据 unsigned char eccVerifySignature(unsigned char *rgbHashData, unsigned char *rgbKeyPb, unsigned char *rs) { int ret = SM2_VERIFY_INNER_ERROR; EC_POINT *point = NULL; BN_CTX *ctx = NULL; BIGNUM *order = NULL; BIGNUM *e = NULL; BIGNUM *t = NULL; int i; EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1); BIGNUM *x = BN_new();; BIGNUM *y = BN_new();; if (!BN_bin2bn(rgbKeyPb, 32, x)) { goto err; } if (!BN_bin2bn(rgbKeyPb + 32, 32, y)) { goto err; } if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) { goto err; } const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key); BIGNUM *r= BN_new(), *s = BN_new(); BN_bin2bn(rs, 32, r); BN_bin2bn(rs + 32, 32, s); //// 相当于 //EC_KEY *ret = EC_KEY_new(); EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(NID_sm2p256v1); ctx = BN_CTX_new(); order = BN_new(); e = BN_new(); t = BN_new(); if (!ctx || !order || !e || !t) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_GROUP_get_order(ec_group, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } /* check r, s in [1, n-1] and r + s != 0 (mod n) */ if (BN_is_zero(r) || BN_is_negative(r) || BN_ucmp(r, order) >= 0 || BN_is_zero(s) || BN_is_negative(s) || BN_ucmp(s, order) >= 0) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); ret = 0; goto err; } /* check t = r + s != 0 */ if (!BN_mod_add(t, r, s, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } if (BN_is_zero(t)) { ret = 0; goto err; } /* convert digest to e */ i = BN_num_bits(order); #if 0 if (8 * dgstlen > i) { dgstlen = (i + 7)/8; } #endif if (!BN_bin2bn(rgbHashData, 32, e)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } #if 0 if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } #endif /* compute (x, y) = sG + tP, P is pub_key */ if (!(point = EC_POINT_new(ec_group))) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_mul(ec_group, point, s, pub_key, t, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) { if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, t, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } } else /* NID_X9_62_characteristic_two_field */ { if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, t, NULL, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); goto err; } } if (!BN_nnmod(t, t, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } /* check (sG + tP).x + e == sig.r */ if (!BN_mod_add(t, t, e, order, ctx)) { ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); goto err; } if (BN_ucmp(t, r) == 0) { ret = SM2_VERIFY_SUCCESS; } else { ret = SM2_VERIFY_FAILED; } err: if (point) EC_POINT_free(point); if (order) BN_free(order); if (e) BN_free(e); if (t) BN_free(t); if (ctx) BN_CTX_free(ctx); return 0; }
static EVP_PKEY *ssh_nistp_line_to_key(char *line) { EVP_PKEY *key; EC_KEY *ec_key; BIGNUM *x; BIGNUM *y; unsigned char decoded[OPENSSH_LINE_MAX]; int len; int flen; char *b, *c; int i; int nid; /* check allowed key size */ if (strncmp(line + 16, "256", 3) == 0) flen = 32, nid = NID_X9_62_prime256v1; else if (strncmp(line + 16, "384", 3) == 0) flen = 48, nid = NID_secp384r1; else if (strncmp(line + 16, "521", 3) == 0) flen = 66, nid = NID_secp521r1; else return NULL; /* find the mime-blob */ b = line; if (!b) return NULL; /* find the first whitespace */ while (*b && *b != ' ') b++; /* skip that whitespace */ b++; /* find the end of the blob / comment */ for (c = b; *c && *c != ' ' && 'c' != '\t' && *c != '\r' && *c != '\n'; c++) ; *c = 0; /* decode binary data */ if (sc_base64_decode(b, decoded, OPENSSH_LINE_MAX) < 0) return NULL; i = 0; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* always check 'len' to get safe 'i' as index into 'decoded' array */ if (len != 19) return NULL; /* check key type (must be same in decoded data and at line start) */ if (strncmp((char *)&decoded[i], line, 19) != 0) return NULL; i += len; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* check curve name - must match key type */ if(len != 8) return NULL; if (strncmp((char *)&decoded[i], line + 11, 8) != 0) return NULL; i += len; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* read public key (uncompressed point) */ /* test if data length is corresponding to key size */ if (len != 1 + flen * 2) return NULL; /* check uncompressed indicator */ if (decoded[i] != 4 ) return NULL; i++; /* create key */ ec_key = EC_KEY_new_by_curve_name(nid); /* read point coordinates */ x = BN_bin2bn(decoded + i, flen, NULL); i += flen; y = BN_bin2bn(decoded + i, flen, NULL); /* do error checking here: valid x, y, ec_key, point on curve.. */ if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) { EC_KEY_free(ec_key); BN_free(x); BN_free(y); return NULL; } key = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(key, ec_key); return key; }
int dnskey_build_pkey(struct rr_dnskey *rr) { if (rr->pkey_built) return rr->pkey ? 1 : 0; rr->pkey_built = 1; if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) { RSA *rsa; EVP_PKEY *pkey; unsigned int e_bytes; unsigned char *pk; int l; rsa = RSA_new(); if (!rsa) goto done; pk = (unsigned char *)rr->pubkey.data; l = rr->pubkey.length; e_bytes = *pk++; l--; if (e_bytes == 0) { if (l < 2) /* public key is too short */ goto done; e_bytes = (*pk++) << 8; e_bytes += *pk++; l -= 2; } if (l < e_bytes) /* public key is too short */ goto done; rsa->e = BN_bin2bn(pk, e_bytes, NULL); pk += e_bytes; l -= e_bytes; rsa->n = BN_bin2bn(pk, l, NULL); pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto done; rr->pkey = pkey; } else if (algorithm_type(rr->algorithm) == ALG_ECC_FAMILY) { EC_KEY *pubeckey; EVP_PKEY *pkey; unsigned char *pk; int l; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; if (rr->algorithm == ALG_ECDSAP256SHA256) { l = SHA256_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); } else if (rr->algorithm == ALG_ECDSAP384SHA384) { l = SHA384_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_secp384r1); } else { goto done; } if (!pubeckey) goto done; if (rr->pubkey.length != 2*l) { goto done; } pk = (unsigned char *)rr->pubkey.data; bn_x = BN_bin2bn(pk, l, NULL); bn_y = BN_bin2bn(&pk[l], l, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(pubeckey, bn_x, bn_y)) { goto done; } pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_assign_EC_KEY(pkey, pubeckey)) goto done; rr->pkey = pkey; } done: if (!rr->pkey) { moan(rr->rr.file_name, rr->rr.line, "error building pkey"); } return rr->pkey ? 1 : 0; }
static int SigVer(FILE *in, FILE *out) { char buf[2048], lbuf[2048]; char *keyword, *value; unsigned char *msg = NULL; int curve_nid = NID_undef; long mlen; BIGNUM *Qx = NULL, *Qy = NULL; EC_KEY *key = NULL; ECDSA_SIG sg, *sig = &sg; const EVP_MD *digest = NULL; sig->r = NULL; sig->s = NULL; while (fgets(buf, sizeof buf, in) != NULL) { fputs(buf, out); if (*buf == '[') { curve_nid = elookup_curve(buf, lbuf, &digest); if (curve_nid == NID_undef) return 0; } if (!parse_line(&keyword, &value, lbuf, buf)) continue; if (!strcmp(keyword, "Msg")) { msg = hex2bin_m(value, &mlen); if (!msg) { fprintf(stderr, "Invalid Message\n"); return 0; } } if (!strcmp(keyword, "Qx")) { if (!do_hex2bn(&Qx, value)) { fprintf(stderr, "Invalid Qx value\n"); return 0; } } if (!strcmp(keyword, "Qy")) { if (!do_hex2bn(&Qy, value)) { fprintf(stderr, "Invalid Qy value\n"); return 0; } } if (!strcmp(keyword, "R")) { if (!do_hex2bn(&sig->r, value)) { fprintf(stderr, "Invalid R value\n"); return 0; } } if (!strcmp(keyword, "S")) { int rv; if (!do_hex2bn(&sig->s, value)) { fprintf(stderr, "Invalid S value\n"); return 0; } key = EC_KEY_new_by_curve_name(curve_nid); rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy); if (rv != 1) { fprintf(stderr, "Error setting public key\n"); return 0; } no_err = 1; rv = FIPS_ecdsa_verify(key, msg, mlen, digest, sig); EC_KEY_free(key); if (msg) OPENSSL_free(msg); no_err = 0; fprintf(out, "Result = %s" RESP_EOL, rv ? "P" : "F"); } } if (sig->r) BN_free(sig->r); if (sig->s) BN_free(sig->s); if (Qx) BN_free(Qx); if (Qy) BN_free(Qy); return 1; }
/* Verify the signature on this transaction using the public key * prev_tx->dest_pubkey. The return value is: * 1 for successful verification; * 0 for failed verification; * -1 for any runtime error. */ int transaction_verify(struct transaction *tx, const struct transaction *prev_tx) { unsigned char uint32_buf[4]; SHA256_CTX sha; hash_output h; EC_KEY *pubkey; ECDSA_SIG *sig; BIGNUM *x, *y; int v, rc; pubkey = NULL; sig = NULL; x = NULL; y = NULL; SHA256_Init(&sha); serialize_uint32(uint32_buf, tx->height); SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf)); SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash)); SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x)); SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y)); SHA256_Final(h, &sha); x = BN_bin2bn(prev_tx->dest_pubkey.x, sizeof(prev_tx->dest_pubkey.x), NULL); if (x == NULL) goto err; y = BN_bin2bn(prev_tx->dest_pubkey.y, sizeof(prev_tx->dest_pubkey.y), NULL); if (y == NULL) goto err; pubkey = EC_KEY_new_by_curve_name(EC_GROUP_NID); if (pubkey == NULL) goto err; rc = EC_KEY_set_public_key_affine_coordinates(pubkey, x, y); if (rc != 1) { EC_KEY_free(pubkey); BN_free(x); BN_free(y); return 0; } BN_free(x); x = NULL; BN_free(y); y = NULL; sig = ECDSA_SIG_new(); if (sig == NULL) goto err; sig->r = BN_bin2bn(tx->src_signature.r, sizeof(tx->src_signature.r), sig->r); if (sig->r == NULL) goto err; sig->s = BN_bin2bn(tx->src_signature.s, sizeof(tx->src_signature.s), sig->s); if (sig->s == NULL) goto err; v = ECDSA_do_verify(h, sizeof(h), sig, pubkey); EC_KEY_free(pubkey); ECDSA_SIG_free(sig); return v; err: if (pubkey != NULL) EC_KEY_free(pubkey); if (sig != NULL) ECDSA_SIG_free(sig); if (x != NULL) BN_free(x); if (y != NULL) BN_free(y); return -1; }
void ecdsa_sigverify(val_context_t * ctx, const u_char *data, size_t data_len, const val_dnskey_rdata_t * dnskey, const val_rrsig_rdata_t * rrsig, val_astatus_t * key_status, val_astatus_t * sig_status) { char buf[1028]; size_t buflen = 1024; u_char sha_hash[MAX_DIGEST_LENGTH]; EC_KEY *eckey = NULL; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; ECDSA_SIG *ecdsa_sig; size_t hashlen = 0; ecdsa_sig = ECDSA_SIG_new(); memset(sha_hash, 0, sizeof(sha_hash)); val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): parsing the public key..."); if (rrsig->algorithm == ALG_ECDSAP256SHA256) { hashlen = SHA256_DIGEST_LENGTH; SHA256(data, data_len, sha_hash); eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); /* P-256 */ } else if (rrsig->algorithm == ALG_ECDSAP384SHA384) { hashlen = SHA384_DIGEST_LENGTH; SHA384(data, data_len, sha_hash); eckey = EC_KEY_new_by_curve_name(NID_secp384r1); /* P-384 */ } if (eckey == NULL) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): could not create key for ECDSA group."); *key_status = VAL_AC_INVALID_KEY; goto err; }; /* * contruct an EC_POINT from the "Q" field in the * dnskey->public_key, dnskey->public_key_len */ if (dnskey->public_key_len != 2*hashlen) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): dnskey length does not match expected size."); *key_status = VAL_AC_INVALID_KEY; goto err; } bn_x = BN_bin2bn(dnskey->public_key, hashlen, NULL); bn_y = BN_bin2bn(&dnskey->public_key[hashlen], hashlen, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(eckey, bn_x, bn_y)) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): Error associating ECSA structure with key."); *key_status = VAL_AC_INVALID_KEY; goto err; } val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): SHA hash = %s", get_hex_string(sha_hash, hashlen, buf, buflen)); val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): verifying ECDSA signature..."); /* * contruct ECDSA signature from the "r" and "s" fileds in * rrsig->signature, rrsig->signature_len */ if (rrsig->signature_len != 2*hashlen) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): Signature length does not match expected size."); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; goto err; } ECDSA_SIG_set0(ecdsa_sig, BN_bin2bn(rrsig->signature, hashlen, NULL), BN_bin2bn(&rrsig->signature[hashlen], hashlen, NULL)); if (ECDSA_do_verify(sha_hash, hashlen, ecdsa_sig, eckey) == 1) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned SUCCESS"); *sig_status = VAL_AC_RRSIG_VERIFIED; } else { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned FAILURE"); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; } /* Free all structures allocated */ err: if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); if (bn_x) BN_free(bn_x); if (bn_y) BN_free(bn_y); if (eckey) EC_KEY_free(eckey); return; }
// unsigned char *pC 输出,密文 // unsigned char *pPxKey, unsigned char *pPyKey 公钥 // unsigned char *pM 明文 // unsigned long MLen 明文长度 unsigned char eccEncrypt(unsigned char *pC, unsigned char *pPxKey, unsigned char *pPyKey, unsigned char *pM, unsigned long MLen) { // NID_sm2p256v1 EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1); //// 相当于 //EC_KEY *ret = EC_KEY_new(); EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(NID_sm2p256v1); KDF_FUNC kdf = KDF_get_x9_63(EVP_sm3());; EC_POINT *point = NULL; //// 设置私钥 //BIGNUM *d = NULL; //BN_hex2bn(&d, pPDKey); //EC_KEY_set_private_key(ec_key, d); int ret = 1; BIGNUM *x = BN_new();; BIGNUM *y = BN_new();; if (!BN_bin2bn(pPxKey, 32, x)) { goto end; } if (!BN_bin2bn(pPyKey, 32, y)) { goto end; } if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) { goto end; } const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key); /* init ec domain parameters */ BIGNUM *n = NULL; BIGNUM *h = NULL; BIGNUM *k = NULL; n = BN_new(); h = BN_new(); k = BN_new(); BN_CTX *bn_ctx = NULL; bn_ctx = BN_CTX_new(); if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) { goto end; } if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) { goto end; } int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8; EC_POINT *ec_point = EC_POINT_new(ec_group); point = EC_POINT_new(ec_group); unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1]; size_t len; char *ciphertext = (char *)OPENSSL_malloc(MLen); size_t ciphertext_size = MLen; do { /* A1: rand k in [1, n-1] */ do { BN_rand_range(k, n); } while (BN_is_zero(k)); /* A2: C1 = [k]G = (x1, y1) */ if (!EC_POINT_mul(ec_group, ec_point, k, NULL, NULL, bn_ctx)) { goto end; } #if 1 if (!(len = EC_POINT_point2oct(ec_group, ec_point, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) { goto end; } BN_bin2bn(buf, 65, n); printf(BN_bn2hex(n)); printf("\n"); printf(BN_bn2hex(k)); #endif /* A3: check [h]P_B != O */ if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) { goto end; } if (EC_POINT_is_at_infinity(ec_group, point)) { goto end; } /* A4: compute ECDH [k]P_B = (x2, y2) */ if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) { goto end; } if (!(len = EC_POINT_point2oct(ec_group, point, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) { goto end; } OPENSSL_assert(len == nbytes * 2 + 1); /* A5: t = KDF(x2 || y2, klen) */ kdf(buf + 1, len - 1, (unsigned char *)ciphertext, &ciphertext_size); // 防止全0 size_t i = 0; for (i = 0; i < ciphertext_size; i++) { if (ciphertext[i]) { break; } } if (i == ciphertext_size) { continue; } break; } while (1); /* A6: C2 = M xor t */ for (size_t i = 0; i < MLen; i++) { ciphertext[i] ^= pM[i]; } unsigned char dgst[EVP_MAX_MD_SIZE]; unsigned int dgstlen; EVP_MD_CTX *md_ctx = EVP_MD_CTX_create(); if (1) { /* A7: C3 = Hash(x2 || M || y2) */ if (!EVP_DigestInit_ex(md_ctx, EVP_sm3(), NULL)) { goto end; } if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) { goto end; } if (!EVP_DigestUpdate(md_ctx, pM, MLen)) { goto end; } if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) { goto end; } if (!EVP_DigestFinal_ex(md_ctx, dgst, &dgstlen)) { goto end; } } EC_POINT_point2oct(ec_group, point, POINT_CONVERSION_UNCOMPRESSED, pC, 65, NULL); memcpy(&pC[65], ciphertext, MLen); memcpy(&pC[65 + MLen], dgst, dgstlen); ret = 0; end: if (point) EC_POINT_free(point); if (n) BN_free(n); if (h) BN_free(h); if (k) BN_free(k); if (bn_ctx) BN_CTX_free(bn_ctx); if (md_ctx) EVP_MD_CTX_destroy(md_ctx); return ret; }