static int ecdh_build_k(ssh_session session) { const EC_GROUP *group = EC_KEY_get0_group(session->next_crypto->ecdh_privkey); EC_POINT *pubkey; void *buffer; int len = (EC_GROUP_get_degree(group) + 7) / 8; bignum_CTX ctx = bignum_ctx_new(); if (ctx == NULL) { return -1; } session->next_crypto->k = bignum_new(); if (session->next_crypto->k == NULL) { bignum_ctx_free(ctx); return -1; } pubkey = EC_POINT_new(group); if (pubkey == NULL) { bignum_ctx_free(ctx); return -1; } if (session->server) EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_client_pubkey), ssh_string_len(session->next_crypto->ecdh_client_pubkey),ctx); else EC_POINT_oct2point(group,pubkey,ssh_string_data(session->next_crypto->ecdh_server_pubkey), ssh_string_len(session->next_crypto->ecdh_server_pubkey),ctx); buffer = malloc(len); ECDH_compute_key(buffer,len,pubkey,session->next_crypto->ecdh_privkey,NULL); EC_POINT_free(pubkey); BN_bin2bn(buffer,len,session->next_crypto->k); free(buffer); EC_KEY_free(session->next_crypto->ecdh_privkey); session->next_crypto->ecdh_privkey=NULL; #ifdef DEBUG_CRYPTO ssh_print_hexa("Session server cookie", session->next_crypto->server_kex.cookie, 16); ssh_print_hexa("Session client cookie", session->next_crypto->client_kex.cookie, 16); ssh_print_bignum("Shared secret key", session->next_crypto->k); #endif #ifdef HAVE_LIBCRYPTO bignum_ctx_free(ctx); #endif return 0; }
int _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx, const unsigned char *k, size_t k_len, libssh2_curve_type curve) { int ret = 0; const EC_GROUP *ec_group = NULL; EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve); EC_POINT *point = NULL; if(ec_key) { ec_group = EC_KEY_get0_group(ec_key); point = EC_POINT_new(ec_group); ret = EC_POINT_oct2point(ec_group, point, k, k_len, NULL); ret = EC_KEY_set_public_key(ec_key, point); if(point != NULL) EC_POINT_free(point); if(ec_ctx != NULL) *ec_ctx = ec_key; } return (ret == 1) ? 0 : -1; }
int _libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key, const unsigned char *server_public_key, size_t server_public_key_len) { int ret = 0; int rc; size_t secret_len; unsigned char *secret = NULL; const EC_GROUP *private_key_group; EC_POINT *server_public_key_point; BN_CTX *bn_ctx = BN_CTX_new(); if(!bn_ctx) return -1; if(k == NULL) return -1; private_key_group = EC_KEY_get0_group(private_key); server_public_key_point = EC_POINT_new(private_key_group); if(server_public_key_point == NULL) return -1; rc = EC_POINT_oct2point(private_key_group, server_public_key_point, server_public_key, server_public_key_len, bn_ctx); if(rc != 1) { ret = -1; goto clean_exit; } secret_len = (EC_GROUP_get_degree(private_key_group) + 7) / 8; secret = malloc(secret_len); if(!secret) { ret = -1; goto clean_exit; } secret_len = ECDH_compute_key(secret, secret_len, server_public_key_point, private_key, NULL); if(secret_len <= 0 || secret_len > EC_MAX_POINT_LEN) { ret = -1; goto clean_exit; } BN_bin2bn(secret, secret_len, *k); clean_exit: if(server_public_key_point != NULL) EC_POINT_free(server_public_key_point); if(bn_ctx != NULL) BN_CTX_free(bn_ctx); if(secret != NULL) free(secret); return ret; }
int ECDSA_verify_signed_digest(int hash_nid, const uint8_t *digest, size_t digest_len, const uint8_t *sig, size_t sig_len, EC_GROUP_new_fn ec_group_new, const uint8_t *ec_key, const size_t ec_key_len) { EC_GROUP *group = ec_group_new(); if (!group) { return 0; } int ret = 0; ECDSA_SIG *s = NULL; EC_POINT *point = EC_POINT_new(group); if (!point || !EC_POINT_oct2point(group, point, ec_key, ec_key_len, NULL)) { goto err; } s = ECDSA_SIG_from_bytes(sig, sig_len); if (s == NULL) { goto err; } ret = ECDSA_do_verify_point(digest, digest_len, s, group, point); err: ECDSA_SIG_free(s); EC_POINT_free(point); EC_GROUP_free(group); return ret; }
int verify_x962_octets_are_on_p256(const unsigned char* octets, size_t len) { assert(octets); assert(len); EC_GROUP* p256group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); if (!p256group) { fprintf(stderr, "error: EC_GROUP_new_by_curve_name() failed.\n"); return 4; } EC_POINT* point = EC_POINT_new(p256group); if (!point) { fprintf(stderr, "error: EC_POINT_new() failed.\n"); EC_GROUP_free(p256group); return 4; } if (0 == EC_POINT_oct2point(p256group, point, octets, len, NULL)) { fprintf(stderr, "error: EC_POINT_oct2point() failed.\n"); EC_POINT_free(point); EC_GROUP_free(p256group); return 4; } if (0 == EC_POINT_is_on_curve(p256group, point, NULL)) { fprintf(stderr, "error: Public key point isn't on P-256 curve.\n"); EC_POINT_free(point); EC_GROUP_free(p256group); return 4; } EC_POINT_free(point); EC_GROUP_free(p256group); return 0; }
static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 5480, section 2. // The parameters are a named curve. EC_POINT *point = NULL; EC_KEY *eckey = NULL; EC_GROUP *group = EC_KEY_parse_curve_name(params); if (group == NULL || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } eckey = EC_KEY_new(); if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { goto err; } point = EC_POINT_new(group); if (point == NULL || !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) || !EC_KEY_set_public_key(eckey, point)) { goto err; } EC_GROUP_free(group); EC_POINT_free(point); EVP_PKEY_assign_EC_KEY(out, eckey); return 1; err: EC_GROUP_free(group); EC_POINT_free(point); EC_KEY_free(eckey); return 0; }
EC_POINT * EC_POINT_bn2point(const EC_GROUP * group, const BIGNUM * bn, EC_POINT * point, BN_CTX * ctx) { size_t buf_len = 0; unsigned char *buf; EC_POINT *ret; if ((buf_len = BN_num_bytes(bn)) == 0) return NULL; buf = malloc(buf_len); if (buf == NULL) return NULL; if (!BN_bn2bin(bn, buf)) { free(buf); return NULL; } if (point == NULL) { if ((ret = EC_POINT_new(group)) == NULL) { free(buf); return NULL; } } else ret = point; if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { if (point == NULL) EC_POINT_clear_free(ret); free(buf); return NULL; } free(buf); return ret; }
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(const EC_GROUP *ec_group, point_conversion_form_t point_form, const EVP_MD *mac_md, const unsigned char *buf, size_t buflen) { int ok = 0; SM2_CIPHERTEXT_VALUE *ret = NULL; BN_CTX *bn_ctx = BN_CTX_new(); int ptlen; int fixlen; if (!bn_ctx) { return NULL; } if (!(fixlen = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md))) { fprintf(stderr, "%s %d\n", __FILE__, __LINE__); goto end; } if (buflen <= fixlen) { fprintf(stderr, "%s %d\n", __FILE__, __LINE__); goto end; } if (!(ret = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) { fprintf(stderr, "%s %d\n", __FILE__, __LINE__); goto end; } ret->ephem_point = EC_POINT_new(ec_group); ret->ciphertext_size = buflen - fixlen; ret->ciphertext = OPENSSL_malloc(ret->ciphertext_size); if (!ret->ephem_point || !ret->ciphertext) { fprintf(stderr, "%s %d\n", __FILE__, __LINE__); goto end; } ptlen = fixlen - EVP_MD_size(mac_md); if (!EC_POINT_oct2point(ec_group, ret->ephem_point, buf, ptlen, bn_ctx)) { fprintf(stderr, "%s %d\n", __FILE__, __LINE__); ERR_print_errors_fp(stdout); goto end; } memcpy(ret->ciphertext, buf + ptlen, ret->ciphertext_size); ret->mactag_size = EVP_MD_size(mac_md); memcpy(ret->mactag, buf + buflen - ret->mactag_size, ret->mactag_size); ok = 1; end: if (!ok && ret) { SM2_CIPHERTEXT_VALUE_free(ret); ret = NULL; } if (bn_ctx) BN_CTX_free(bn_ctx); return ret; }
const EC_POINT* crypt_ec_helper::from_base58(std::string base58) { const char* psz = base58.c_str(); std::vector<unsigned char> vch; // Skip leading spaces. while (*psz && isspace(*psz)) psz++; // Skip and count leading '1's. int zeroes = 0; while (*psz == '1') { zeroes++; psz++; } // Allocate enough space in big-endian base256 representation. std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character const char* ch = strchr(pszBase58, *psz); if (ch == NULL) return NULL; // Apply "b256 = b256 * 58 + ch". int carry = ch - pszBase58; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); psz++; } // Skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return NULL; // Skip leading zeroes in b256. std::vector<unsigned char>::iterator it = b256.begin(); while (it != b256.end() && *it == 0) it++; // Copy result into output vector. vch.reserve(zeroes + (b256.end() - it)); vch.assign(zeroes, 0x00); while (it != b256.end()) vch.push_back(*(it++)); EC_GROUP *ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1); pub = EC_POINT_new(ecgrp); size_t len = EC_POINT_oct2point(ecgrp, pub, vch.data(), vch.size(), NULL); EC_GROUP_free(ecgrp); return pub; }
int MKEM_decode_message(const MKEM *kp, uint8_t *secret, const uint8_t *message) { int use_curve0 = !(message[0] & kp->params->curve_bit); const EC_GROUP *ca = use_curve0 ? kp->params->c0 : kp->params->c1; const BIGNUM *sa = use_curve0 ? kp->s0 : kp->s1; EC_POINT *q = 0, *r = 0; uint8_t *unpadded = 0; BIGNUM x, y; size_t mlen = kp->params->msgsize; int rv; if (!kp->s0 || !kp->s1) /* secret key not available */ return -1; BN_init(&x); BN_init(&y); FAILZ(q = EC_POINT_new(ca)); FAILZ(r = EC_POINT_new(ca)); FAILZ(unpadded = malloc(mlen + 1)); /* Copy the message, erase the padding bits, and put an 0x02 byte on the front so we can use EC_POINT_oct2point to recover the y-coordinate. */ unpadded[0] = 0x02; unpadded[1] = (message[0] & ~(kp->params->pad_mask|kp->params->curve_bit)); memcpy(&unpadded[2], &message[1], mlen - 1); FAILZ(EC_POINT_oct2point(ca, q, unpadded, mlen + 1, kp->params->ctx)); FAILZ(EC_POINT_mul(ca, r, 0, q, sa, kp->params->ctx)); FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, q, &x, &y, kp->params->ctx)); if (bn2bin_padhi(&x, secret, mlen) != mlen) goto fail; FAILZ(EC_POINT_get_affine_coordinates_GF2m(ca, r, &x, &y, kp->params->ctx)); if (bn2bin_padhi(&x, secret + mlen, mlen) != mlen) goto fail; rv = 0; done: if (unpadded) { memset(unpadded, 0, mlen + 1); free(unpadded); } if (q) EC_POINT_clear_free(q); if (r) EC_POINT_clear_free(r); BN_clear(&x); BN_clear(&y); return rv; fail: rv = -1; memset(secret, 0, mlen * 2); goto done; }
EC_POINT *get_EcPoint_oct(EC_GROUP *curveGroup, unsigned char *in, size_t size) { BN_CTX *ctx; EC_POINT *res; ctx = BN_CTX_new(); res = EC_POINT_new(curveGroup); EC_POINT_oct2point(curveGroup, res, in, size, ctx); BN_CTX_free(ctx); return res; }
BUF_MEM * Comp(EVP_PKEY *key, const BUF_MEM *pub, BN_CTX *bn_ctx, EVP_MD_CTX *md_ctx) { BUF_MEM *out = NULL; const EC_GROUP *group; EC_POINT *ecp = NULL; EC_KEY *ec = NULL; BIGNUM *x = NULL, *y = NULL; check((key && pub), "Invalid arguments"); switch (EVP_PKEY_base_id(key)) { case EVP_PKEY_DH: out = hash(EVP_sha1(), md_ctx, NULL, pub); break; case EVP_PKEY_EC: ec = EVP_PKEY_get1_EC_KEY(key); if (!ec) goto err; group = EC_KEY_get0_group(ec); ecp = EC_POINT_new(group); x = BN_CTX_get(bn_ctx); y = BN_CTX_get(bn_ctx); if(!ecp || !x || !y || !EC_POINT_oct2point(group, ecp, (unsigned char *) pub->data, pub->length, bn_ctx) || !EC_POINT_get_affine_coordinates_GF2m(group, ecp, x, y, bn_ctx)) goto err; out = BUF_MEM_create(BN_num_bytes(x)); if(!out || !BN_bn2bin(x, (unsigned char *) out->data)) goto err; break; default: log_err("Unknown protocol"); goto err; } err: if (ecp) EC_POINT_free(ecp); /* Decrease the reference count, the key is still available in the EVP_PKEY * structure */ if (ec) EC_KEY_free(ec); if (x) BN_free(x); if (y) BN_free(y); return out; }
int MKEM_init_pk_vec(MKEM *kp, const MKEMParams *params, const uint8_t *p0, size_t p0l, const uint8_t *p1, size_t p1l) { EC_POINT *pp0 = EC_POINT_new(params->c0); EC_POINT *pp1 = EC_POINT_new(params->c1); FAILZ(pp0); FAILZ(pp1); FAILZ(EC_POINT_oct2point(params->c0, pp0, p0, p0l, params->ctx)); FAILZ(EC_POINT_oct2point(params->c1, pp1, p1, p1l, params->ctx)); return MKEM_init_pk_point(kp, params, pp0, pp1); fail: if (pp0) EC_POINT_clear_free(pp0); if (pp1) EC_POINT_clear_free(pp1); return -1; }
int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, BN_CTX *ctx) { if (key == NULL || key->group == NULL) return 0; if (key->pub_key == NULL) key->pub_key = EC_POINT_new(key->group); if (key->pub_key == NULL) return 0; return EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx); }
/** * eccx08_eckey_convert() * * \brief Converts raw 64 bytes of public key (ATECC508 format) to the * openssl EC_KEY structure. It allocates EC_KEY structure and * does not free it (must be a caller to free) * * \param[out] p_eckey Pointer to EC_KEY with Public Key on success * \param[in] raw_pubkey Raw public key, 64 bytes length 32-byte X following with 32-byte Y * \param[in] serial_number 9 bytes of ATECCX08 serial number * \param[in] serial_len Size of the ATECCX08 serial number buffer * \return 1 on success, 0 on error */ int eccx08_eckey_convert(EC_KEY **p_eckey, uint8_t *raw_pubkey, uint8_t *serial_number, int serial_len) { int rc = 0; int ret = 0; EC_GROUP *ecgroup = NULL, *ecgroup_old = NULL; EC_KEY *eckey = *p_eckey; EC_POINT *ecpoint = NULL; BN_CTX *bnctx = NULL; int asn1_flag = OPENSSL_EC_NAMED_CURVE; point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED; char tmp_buf[MEM_BLOCK_SIZE * 2 + 1]; /* Openssl raw key has a leading byte with conversion form id */ tmp_buf[0] = POINT_CONVERSION_UNCOMPRESSED; memcpy(&tmp_buf[1], raw_pubkey, MEM_BLOCK_SIZE * 2); if (!eckey) { eckey = EC_KEY_new(); if (!eckey) goto done; } ecgroup = eckey->group; if (!ecgroup) { ecgroup = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); if (!ecgroup) goto done; EC_GROUP_set_point_conversion_form(ecgroup, form); EC_GROUP_set_asn1_flag(ecgroup, asn1_flag); } if (!eckey->group) { ret = EC_KEY_set_group(eckey, ecgroup); if (!ret) goto done; } ret = eccx08_generate_key(eckey, serial_number, serial_len); if (!ret) goto done; ecgroup = eckey->group; ecpoint = eckey->pub_key; if (!ecpoint) { ecpoint = EC_POINT_new(ecgroup); if (!ecpoint) goto done; } ret = EC_POINT_oct2point(ecgroup, ecpoint, tmp_buf, MEM_BLOCK_SIZE * 2 + 1, NULL); if (!ret) goto done; *p_eckey = eckey; rc = 1; done: return (rc); }
u2fs_rc decode_user_key(const unsigned char *data, u2fs_EC_KEY_t ** key) { if (key == NULL) return U2FS_MEMORY_ERROR; EC_GROUP *ecg = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); *key = (u2fs_EC_KEY_t *) EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); EC_POINT *point = EC_POINT_new(ecg); point_conversion_form_t pcf = POINT_CONVERSION_UNCOMPRESSED; EC_GROUP_set_point_conversion_form(ecg, pcf); if (EC_POINT_oct2point(ecg, point, data, U2FS_PUBLIC_KEY_LEN, NULL) == 0) { if (debug) { unsigned long err = 0; err = ERR_get_error(); fprintf(stderr, "Error: %s, %s, %s\n", ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } *key = NULL; EC_GROUP_free(ecg); ecg = NULL; EC_POINT_free(point); point = NULL; return U2FS_CRYPTO_ERROR; } EC_GROUP_free(ecg); ecg = NULL; if (EC_KEY_set_public_key((EC_KEY *) * key, point) == 0) { if (debug) { unsigned long err = 0; err = ERR_get_error(); fprintf(stderr, "Error: %s, %s, %s\n", ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); } *key = NULL; EC_POINT_free(point); point = NULL; return U2FS_CRYPTO_ERROR; } EC_POINT_free(point); point = NULL; return U2FS_OK; }
static int get_ec(const u_char *d, size_t len, EC_POINT *v, const EC_GROUP *g) { /* Refuse overlong bignums */ if (len == 0 || len > SSHBUF_MAX_ECPOINT) return SSH_ERR_ECPOINT_TOO_LARGE; /* Only handle uncompressed points */ if (*d != POINT_CONVERSION_UNCOMPRESSED) return SSH_ERR_INVALID_FORMAT; if (v != NULL && EC_POINT_oct2point(g, v, d, len, NULL) != 1) return SSH_ERR_INVALID_FORMAT; /* XXX assumption */ return 0; }
void CBAddPoints(uint8_t * point1, uint8_t * point2){ // Get group EC_GROUP * group = EC_GROUP_new_by_curve_name(NID_secp256k1); // Get OpenSSL representations of points EC_POINT * p1 = EC_POINT_new(group); EC_POINT * p2 = EC_POINT_new(group); BN_CTX * ctx = BN_CTX_new(); EC_POINT_oct2point(group, p1, point1, 33, ctx); EC_POINT_oct2point(group, p2, point2, 33, ctx); // Add points together EC_POINT * result = EC_POINT_new(group); EC_POINT_add(group, result, p1, p2, ctx); // Free points EC_POINT_free(p1); EC_POINT_free(p2); // Write result to point1 EC_POINT_point2oct(group, result, POINT_CONVERSION_COMPRESSED, point1, 33, ctx); // Free result, group and ctx EC_POINT_free(result); EC_GROUP_free(group); BN_CTX_free(ctx); }
int getOldKeyImage(CPubKey &publicKey, ec_point &keyImage) { // - PublicKey * Hash(PublicKey) if (publicKey.size() != EC_COMPRESSED_SIZE) return errorN(1, "%s: Invalid publicKey.", __func__); int rv = 0; uint256 pkHash = publicKey.GetHash(); BN_CTX_start(bnCtx); BIGNUM *bnTmp = BN_CTX_get(bnCtx); EC_POINT *ptPk = NULL; // Hash to BIGNUM if (!BN_bin2bn(pkHash.begin(), EC_SECRET_SIZE, bnTmp) && (rv = errorN(1, "%s: BN_bin2bn failed.", __func__))) goto End; // PublicKey point if (!(ptPk = EC_POINT_new(ecGrp)) && (rv = errorN(1, "%s: EC_POINT_new failed.", __func__))) goto End; if(!EC_POINT_oct2point(ecGrp, ptPk, publicKey.begin(), EC_COMPRESSED_SIZE, bnCtx) && (rv = errorN(1, "%s: EC_POINT_oct2point failed.", __func__))) goto End; // PublicKey * Hash(PublicKey) if (!EC_POINT_mul(ecGrp, ptPk, NULL, ptPk, bnTmp, bnCtx) && (rv = errorN(1, "%s: EC_POINT_mul failed.", __func__))) goto End; try { keyImage.resize(EC_COMPRESSED_SIZE); } catch (std::exception& e) { LogPrintf("%s: keyImage.resize threw: %s.\n", __func__, e.what()); rv = 1; goto End; } // Point to BIGNUM to bin if (!(EC_POINT_point2bn(ecGrp, ptPk, POINT_CONVERSION_COMPRESSED, bnTmp, bnCtx)) ||BN_num_bytes(bnTmp) != (int) EC_COMPRESSED_SIZE ||BN_bn2bin(bnTmp, &keyImage[0]) != (int) EC_COMPRESSED_SIZE) rv = errorN(1, "%s: point -> keyImage failed.", __func__); End: EC_POINT_free(ptPk); BN_CTX_end(bnCtx); return 0; }
static BOOL SATOSHI_SCRIPT_checksig(SATOSHI_OP_STACK_t * s, const unsigned char * message, uint32_t cbMessage) { BOOL rc = FALSE; if(NULL == message || cbMessage == 0) return FALSE; SATOSHI_OP_STACK_DATA_t * pubkey = NULL, * sig = NULL; pubkey = SATOSHI_OP_STACK_pop(s); sig = SATOSHI_OP_STACK_pop(s); if(NULL == pubkey || NULL == sig) { if(NULL != pubkey) SATOSHI_OP_STACK_DATA_free(pubkey); if(NULL != sig) SATOSHI_OP_STACK_DATA_free(sig); return FALSE; } // verify sig EC_KEY * p_key = EC_KEY_new_by_curve_name(NID_secp256k1); BN_CTX * ctx = BN_CTX_new(); assert(NULL != p_key && NULL != ctx); const EC_GROUP * G = EC_KEY_get0_group(p_key); EC_POINT * Q = EC_POINT_new(G); EC_POINT_oct2point(G, Q, pubkey->data, pubkey->cb, ctx); EC_KEY_set_public_key(p_key, Q); rc = ECDSA_verify(0, message, cbMessage, sig->data, sig->cb, p_key); if(rc != 1) { if(-1 == rc) { // openssl error. ERR_print_errors_fp(stderr); } rc = 0; } if(rc) { SATOSHI_OP_STACK_push_boolean(s, rc, sizeof(BOOL)); } EC_KEY_free(p_key); BN_CTX_free(ctx); SATOSHI_OP_STACK_DATA_free(pubkey); SATOSHI_OP_STACK_DATA_free(sig); return rc; }
EC_POINT *decode_base64_point(const polypseud_ctx *ctx, char *string) { unsigned char *bytes; size_t length; if(Base64Decode(string, &bytes, &length) != 0) return NULL; EC_POINT *point = EC_POINT_new(ctx->ec_group); EC_POINT_oct2point(ctx->ec_group, point, bytes, length, ctx->bn_ctx); free(bytes); return point; }
// Convert a ByteString to an OpenSSL EC POINT in the given EC GROUP EC_POINT* OSSL::byteString2pt(const ByteString& byteString, const EC_GROUP* grp) { ByteString raw = DERUTIL::octet2Raw(byteString); size_t len = raw.size(); if (len == 0) return NULL; EC_POINT* pt = EC_POINT_new(grp); if (!EC_POINT_oct2point(grp, pt, &raw[0], len, NULL)) { ERROR_MSG("EC_POINT_oct2point failed: %s", ERR_error_string(ERR_get_error(), NULL)); EC_POINT_free(pt); return NULL; } return pt; }
int conv_os2point(const EC_GROUP *grp, const ASN1_OCTET_STRING *os, EC_POINT *p, BN_CTX *ctx) { if (EC_POINT_oct2point(grp, p, os->data, os->length, ctx) <= 0) return ENOMEM; if (EC_POINT_is_on_curve(grp, p, ctx) == 0) return EINVAL; if (EC_POINT_is_at_infinity(grp, p)) return EINVAL; return 0; }
int main(int argc, char **argv) { unsigned char ecprot[128]; unsigned char pbuf[1024]; EC_KEY *pkey; EC_POINT *ptnew, *ptmpk, *ptz; BIGNUM z; unsigned char *pend = (unsigned char *) pbuf, *px; unsigned char hash1[32], hashz[32]; int n, zlen; if(argc < 3) { printf("Usage: %s <mpk> <seq>\n", argv[0]); exit(1); } OpenSSL_add_all_algorithms(); strcpy(pbuf, argv[2]); strcat(pbuf, ":0:"); zlen = strlen(pbuf); px = pbuf + zlen; for(n=0; n < 64; n++) px[n] = hex(argv[1][n*2])*16 + hex(argv[1][n*2+1]); SHA256(pbuf, zlen+64, hash1); SHA256(hash1, sizeof(hash1), hashz); BN_init(&z); BN_bin2bn(hashz, 32, &z); pkey = EC_KEY_new_by_curve_name(NID_secp256k1); ptmpk = EC_POINT_new(EC_KEY_get0_group(pkey)); pbuf[zlen-1] = 0x04; EC_POINT_oct2point(EC_KEY_get0_group(pkey), ptmpk, pbuf+zlen-1, 65, NULL); ptz = EC_POINT_new(EC_KEY_get0_group(pkey)); EC_POINT_mul(EC_KEY_get0_group(pkey), ptz, NULL, EC_GROUP_get0_generator(EC_KEY_get0_group(pkey)), &z, NULL); ptnew = EC_POINT_new(EC_KEY_get0_group(pkey)); EC_POINT_add(EC_KEY_get0_group(pkey), ptnew, ptmpk, ptz, NULL); EC_KEY_set_public_key(pkey, ptnew); i2o_ECPublicKey(pkey, &pend); b58encode_address(EC_KEY_get0_public_key(pkey), EC_KEY_get0_group(pkey), 0, ecprot); printf("%s\n", ecprot); }
int buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, EC_POINT *point) { u_char *buf; u_int len; BN_CTX *bnctx; int ret = -1; if ((buf = buffer_get_string_ret(buffer, &len)) == NULL) { error("%s: invalid point", __func__); return -1; } if ((bnctx = BN_CTX_new()) == NULL) fatal("%s: BN_CTX_new failed", __func__); if (len > BUFFER_MAX_ECPOINT_LEN) { error("%s: EC_POINT too long: %u > max %u", __func__, len, BUFFER_MAX_ECPOINT_LEN); goto out; } if (len == 0) { error("%s: EC_POINT buffer is empty", __func__); goto out; } if (buf[0] != POINT_CONVERSION_UNCOMPRESSED) { error("%s: EC_POINT is in an incorrect form: " "0x%02x (want 0x%02x)", __func__, buf[0], POINT_CONVERSION_UNCOMPRESSED); goto out; } if (EC_POINT_oct2point(curve, point, buf, len, bnctx) != 1) { error("buffer_get_bignum2_ret: BN_bin2bn failed"); goto out; } /* EC_POINT_oct2point verifies that the point is on the curve for us */ ret = 0; out: BN_CTX_free(bnctx); bzero(buf, len); xfree(buf); return ret; }
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e) { EC_POINT *p; const EC_GROUP *g; int ok; key->ecdsa_nid = nid; key->type_c = pki_key_ecdsa_nid_to_name(nid); key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid); if (key->ecdsa == NULL) { return -1; } g = EC_KEY_get0_group(key->ecdsa); p = EC_POINT_new(g); if (p == NULL) { return -1; } ok = EC_POINT_oct2point(g, p, ssh_string_data(e), ssh_string_len(e), NULL); if (!ok) { EC_POINT_free(p); return -1; } /* EC_KEY_set_public_key duplicates p */ ok = EC_KEY_set_public_key(key->ecdsa, p); EC_POINT_free(p); if (!ok) { return -1; } return 0; }
int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, BN_CTX *ctx) { if (key == NULL || key->group == NULL) return 0; if (key->pub_key == NULL) key->pub_key = EC_POINT_new(key->group); if (key->pub_key == NULL) return 0; if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0) return 0; /* * Save the point conversion form. * For non-custom curves the first octet of the buffer (excluding * the last significant bit) contains the point conversion form. * EC_POINT_oct2point() has already performed sanity checking of * the buffer so we know it is valid. */ if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01); return 1; }
static int ssl_ec_point_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret, size_t *out_secret_len, uint8_t *out_alert, const uint8_t *peer_key, size_t peer_key_len) { BIGNUM *private_key = (BIGNUM *)ctx->data; assert(private_key != NULL); *out_alert = SSL_AD_INTERNAL_ERROR; /* Set up a shared |BN_CTX| for all operations. */ BN_CTX *bn_ctx = BN_CTX_new(); if (bn_ctx == NULL) { return 0; } BN_CTX_start(bn_ctx); int ret = 0; EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid); EC_POINT *peer_point = NULL, *result = NULL; uint8_t *secret = NULL; if (group == NULL) { goto err; } /* Compute the x-coordinate of |peer_key| * |private_key|. */ peer_point = EC_POINT_new(group); result = EC_POINT_new(group); if (peer_point == NULL || result == NULL) { goto err; } BIGNUM *x = BN_CTX_get(bn_ctx); if (x == NULL) { goto err; } if (!EC_POINT_oct2point(group, peer_point, peer_key, peer_key_len, bn_ctx)) { *out_alert = SSL_AD_DECODE_ERROR; goto err; } if (!EC_POINT_mul(group, result, NULL, peer_point, private_key, bn_ctx) || !EC_POINT_get_affine_coordinates_GFp(group, result, x, NULL, bn_ctx)) { goto err; } /* Encode the x-coordinate left-padded with zeros. */ size_t secret_len = (EC_GROUP_get_degree(group) + 7) / 8; secret = OPENSSL_malloc(secret_len); if (secret == NULL || !BN_bn2bin_padded(secret, secret_len, x)) { goto err; } *out_secret = secret; *out_secret_len = secret_len; secret = NULL; ret = 1; err: EC_GROUP_free(group); EC_POINT_free(peer_point); EC_POINT_free(result); BN_CTX_end(bn_ctx); BN_CTX_free(bn_ctx); OPENSSL_free(secret); return ret; }
int EVP_PKEY_set_keys(EVP_PKEY *evp_pkey, const unsigned char *privkey, size_t privkey_len, const unsigned char *pubkey, size_t pubkey_len, BN_CTX *bn_ctx) { EC_KEY *ec_key = NULL; DH *dh = NULL; EC_POINT *ec_point = NULL; BIGNUM *bn = NULL, *dh_pub_key, *dh_priv_key; int ok = 0; const EC_GROUP *group; check(evp_pkey, "Invalid arguments"); switch (EVP_PKEY_base_id(evp_pkey)) { case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(evp_pkey); if (!ec_key) goto err; group = EC_KEY_get0_group(ec_key); if (pubkey) { ec_point = EC_POINT_new(group); if (!ec_point || !EC_POINT_oct2point(group, ec_point, pubkey, pubkey_len, bn_ctx) || !EC_KEY_set_public_key(ec_key, ec_point)) goto err; } if (privkey) { bn = BN_bin2bn(privkey, privkey_len, bn); if (!bn || !EC_KEY_set_private_key(ec_key, bn)) goto err; } if (!EVP_PKEY_set1_EC_KEY(evp_pkey, ec_key)) goto err; break; case EVP_PKEY_DH: dh = EVP_PKEY_get1_DH(evp_pkey); if (!dh) goto err; if (pubkey) { dh_pub_key = BN_bin2bn(pubkey, pubkey_len, NULL); if (!dh_pub_key || !DH_set0_key(dh, dh_pub_key, NULL)) goto err; } if (privkey) { dh_priv_key = BN_bin2bn(privkey, privkey_len, NULL); if (!dh_priv_key || !DH_set0_key(dh, NULL, dh_priv_key)) goto err; } if (!EVP_PKEY_set1_DH(evp_pkey, dh)) goto err; break; default: log_err("Unknown type of key"); goto err; break; } ok = 1; err: if (bn) BN_clear_free(bn); if (ec_key) EC_KEY_free(ec_key); if (dh) DH_free(dh); if (ec_point) EC_POINT_clear_free(ec_point); return ok; }
int main() { srand((unsigned)time(NULL)); int i; EC_KEY* key; //key = EC_KEY_new_by_curve_name(415); key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); const EC_GROUP *group = EC_KEY_get0_group(key); if (EC_KEY_generate_key(key)==0) { printf("Error generate key\n"); return -1; } unsigned char pk_b[33]; const EC_POINT *pub = EC_KEY_get0_public_key(key); if (EC_POINT_point2oct(group, pub, POINT_CONVERSION_COMPRESSED, pk_b, 33, 0)!=33) { printf("Error 2\n"); return -1; } unsigned char h1[16],h2[16]; printf("\x02"); for (i=0;i<16;i++) { h1[i]=rand()%256; printf("%c",h1[i]); } for (i=0;i<33;i++) printf("%c",pk_b[i]); fflush(stdout); //get h2 for (i=0;i<16;i++) h2[i]=rand()%256; for (i=0;i<16;i++) scanf("%c",&h2[i]); //get peerpk_b unsigned char peerpk_b[33]={2 , 30 , 25 , 50 , 17 , 242 , 232 , 55 , 157 , 18 , 106 , 115 , 214 , 193 , 192 , 39 , 207 , 226 , 184 , 216 , 244 , 147 , 111 , 188 , 125 , 230 , 38 , 125 , 231 , 50 , 56 , 152 , 148 }; for (i=0;i<33;i++) scanf("%c",&peerpk_b[i]); EC_POINT *peerpk = EC_POINT_new(group); if (EC_POINT_oct2point(group, peerpk, peerpk_b, 33, 0)==0) { printf("Error 3\n"); return -1; } unsigned char skey[33]; if (ECDH_compute_key(skey, 32, peerpk, key, NULL)==0) { printf("Error 4\n"); return -1; } SHA512_CTX shactx; unsigned char hash[SHA512_DIGEST_LENGTH]; SHA512_Init(&shactx); SHA512_Update(&shactx, h2, 16); SHA512_Update(&shactx, skey, 32); SHA512_Update(&shactx, h1, 16); SHA512_Final(hash, &shactx); for (i=0;i<64;i++) printf("%02x",hash[i]); fflush(stdout); struct cipher c; c.recvfd=0; c.sendfd=1; for (i=0;i<16;i++) c.sendkey[i]=hash[i]; for (i=0;i<4;i++) c.sendiv[i]=hash[32+i]; for (i=0;i<16;i++) c.recvkey[i]=hash[16+i]; for (i=0;i<4;i++) c.recviv[i]=hash[36+i]; c.sendcnt=0; c.recvcnt=0; unsigned char d[1000]; unsigned char oiv[8]; int op; char dlen; while (true) { scanf("%d",&op); scanf("%c",&dlen); scanf("%c",&dlen); for (i=0;i<dlen;i++) scanf("%c",&d[i]); if (op==1) { for (i=0;i<8;i++) oiv[i]=rand()%256; encrypt(c,d,dlen,oiv); c.recvcnt+=1; } else if (op==2) { for (i=0;i<8;i++) scanf("%c",&oiv[i]); decrypt(c,d,dlen,oiv, NULL); c.sendcnt+=1; } fflush(stdout); } return 0; }