/** * ECDH key derivation method (replaces ossl_ecdh_compute_key) * Implementation for OpenSSL 1.1.0-pre4 and later * * @param out derived key * @param outlen derived key length * @param peer_point public key point * @param ecdh private key * @return 1 on success or 0 on error */ static int pkcs11_ec_ckey(unsigned char **out, size_t *outlen, const EC_POINT *peer_point, const EC_KEY *ecdh) { PKCS11_KEY *key; CK_ECDH1_DERIVE_PARAMS *parms; unsigned char *buf = NULL; size_t buflen; int rv; key = (PKCS11_KEY *)EC_KEY_get_ex_data(ecdh, ec_ex_index); if (key == NULL) /* The private key is not handled by PKCS#11 */ return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh); /* TODO: Add an atfork check */ /* both peer and ecdh use same group parameters */ parms = pkcs11_ecdh_params_alloc(EC_KEY_get0_group(ecdh), peer_point); if (parms == NULL) return 0; rv = pkcs11_ecdh_derive(&buf, &buflen, CKM_ECDH1_DERIVE, parms, NULL, key); pkcs11_ecdh_params_free(parms); if (rv < 0) return 0; *out = buf; *outlen = buflen; return 1; }
/** * ECDH key derivation method (replaces ossl_ecdh_compute_key) * Implementation for OpenSSL 1.1.0-pre4 and later * * @param out derived key * @param outlen derived key length * @param peer_point public key point * @param ecdh private key * @return 1 on success or 0 on error */ static int pkcs11_ec_ckey(unsigned char **out, size_t *outlen, const EC_POINT *peer_point, const EC_KEY *ecdh) { PKCS11_KEY *key; CK_ECDH1_DERIVE_PARAMS *parms; unsigned char *buf = NULL; size_t buflen; int rv; key = pkcs11_get_ex_data_ec(ecdh); if (check_key_fork(key) < 0) return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh); /* both peer and ecdh use same group parameters */ parms = pkcs11_ecdh_params_alloc(EC_KEY_get0_group(ecdh), peer_point); if (parms == NULL) return 0; rv = pkcs11_ecdh_derive(&buf, &buflen, CKM_ECDH1_DERIVE, parms, NULL, key); pkcs11_ecdh_params_free(parms); if (rv < 0) return 0; *out = buf; *outlen = buflen; return 1; }
/** * ECDH key derivation method (replaces ossl_ecdh_compute_key) * Implementation for OpenSSL 1.1.0-pre3 and earlier * * @param out derived key * @param outlen derived key length * @param peer_point public key point * @param ecdh private key * @param KCF key derivation function * @return the length of the derived key or -1 if an error occurred */ static int pkcs11_ec_ckey(void *out, size_t outlen, const EC_POINT *peer_point, const EC_KEY *ecdh, void *(*KDF)(const void *, size_t, void *, size_t *)) { PKCS11_KEY *key; CK_ECDH1_DERIVE_PARAMS *parms; unsigned char *buf = NULL; size_t buflen; int rv; #if OPENSSL_VERSION_NUMBER >= 0x10100000L key = (PKCS11_KEY *)EC_KEY_get_ex_data(ecdh, ec_ex_index); #else key = (PKCS11_KEY *)ECDSA_get_ex_data((EC_KEY *)ecdh, ec_ex_index); #endif if (key == NULL) /* The private key is not handled by PKCS#11 */ return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh, KDF); /* TODO: Add an atfork check */ /* both peer and ecdh use same group parameters */ parms = pkcs11_ecdh_params_alloc(EC_KEY_get0_group(ecdh), peer_point); if (parms == NULL) return -1; rv = pkcs11_ecdh_derive(&buf, &buflen, CKM_ECDH1_DERIVE, parms, NULL, key); pkcs11_ecdh_params_free(parms); if (rv < 0) return -1; if (KDF) { if (KDF(buf, buflen, out, &outlen) == NULL) { OPENSSL_free(buf); return -1; } } else { if (outlen > buflen) outlen = buflen; memcpy(out, buf, outlen); } OPENSSL_free(buf); return outlen; }
/** * ECDH key derivation method (replaces ossl_ecdh_compute_key) * Implementation for OpenSSL 1.1.0-pre3 and earlier * * @param out derived key * @param outlen derived key length * @param peer_point public key point * @param ecdh private key * @param KCF key derivation function * @return the length of the derived key or -1 if an error occurred */ static int pkcs11_ec_ckey(void *out, size_t outlen, const EC_POINT *peer_point, const EC_KEY *ecdh, void *(*KDF)(const void *, size_t, void *, size_t *)) { PKCS11_KEY *key; CK_ECDH1_DERIVE_PARAMS *parms; unsigned char *buf = NULL; size_t buflen; int rv; key = pkcs11_get_ex_data_ec(ecdh); if (check_key_fork(key) < 0) return ossl_ecdh_compute_key(out, outlen, peer_point, ecdh, KDF); /* both peer and ecdh use same group parameters */ parms = pkcs11_ecdh_params_alloc(EC_KEY_get0_group(ecdh), peer_point); if (parms == NULL) return -1; rv = pkcs11_ecdh_derive(&buf, &buflen, CKM_ECDH1_DERIVE, parms, NULL, key); pkcs11_ecdh_params_free(parms); if (rv < 0) return -1; if (KDF) { if (KDF(buf, buflen, out, &outlen) == NULL) { OPENSSL_free(buf); return -1; } } else { if (outlen > buflen) outlen = buflen; memcpy(out, buf, outlen); } OPENSSL_free(buf); return outlen; }