// returns a 32-byte secret unique to these two keys. At least one private key must be known. static void getECIESSecret (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key) { EC_KEY* privkey = (EC_KEY*) secretKey.get(); EC_KEY* pubkey = (EC_KEY*) publicKey.get(); // Retrieve a secret generated from an EC key pair. At least one private key must be known. if (privkey == nullptr || pubkey == nullptr) throw std::runtime_error ("missing key"); if (! EC_KEY_get0_private_key (privkey)) { throw std::runtime_error ("not a private key"); } unsigned char rawbuf[512]; int buflen = ECDH_compute_key (rawbuf, 512, EC_KEY_get0_public_key (pubkey), privkey, nullptr); if (buflen < ECIES_MIN_SEC) throw std::runtime_error ("ecdh key failed"); unsigned char hbuf[ECIES_KEY_LENGTH]; ECIES_KEY_HASH (rawbuf, buflen, hbuf); memset (rawbuf, 0, ECIES_HMAC_KEY_SIZE); assert ((ECIES_ENC_KEY_SIZE + ECIES_HMAC_KEY_SIZE) >= ECIES_KEY_LENGTH); memcpy (enc_key.begin (), hbuf, ECIES_ENC_KEY_SIZE); memcpy (hmac_key.begin (), hbuf + ECIES_ENC_KEY_SIZE, ECIES_HMAC_KEY_SIZE); memset (hbuf, 0, ECIES_KEY_LENGTH); }
void CKey::getECIESSecret (CKey& otherKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key) { // Retrieve a secret generated from an EC key pair. At least one private key must be known. if (!pkey || !otherKey.pkey) throw std::runtime_error ("missing key"); EC_KEY* pubkey, *privkey; if (EC_KEY_get0_private_key (pkey)) { privkey = pkey; pubkey = otherKey.pkey; } else if (EC_KEY_get0_private_key (otherKey.pkey)) { privkey = otherKey.pkey; pubkey = pkey; } else throw std::runtime_error ("no private key"); unsigned char rawbuf[512]; int buflen = ECDH_compute_key (rawbuf, 512, EC_KEY_get0_public_key (pubkey), privkey, NULL); if (buflen < ECIES_MIN_SEC) throw std::runtime_error ("ecdh key failed"); unsigned char hbuf[ECIES_KEY_LENGTH]; ECIES_KEY_HASH (rawbuf, buflen, hbuf); memset (rawbuf, 0, ECIES_HMAC_KEY_SIZE); assert ((ECIES_ENC_KEY_SIZE + ECIES_HMAC_KEY_SIZE) >= ECIES_KEY_LENGTH); memcpy (enc_key.begin (), hbuf, ECIES_ENC_KEY_SIZE); memcpy (hmac_key.begin (), hbuf + ECIES_ENC_KEY_SIZE, ECIES_HMAC_KEY_SIZE); memset (hbuf, 0, ECIES_KEY_LENGTH); }