5832599943147268f9a4383d3dde39f8489bf339Evan Hunt * Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt * This Source Code Form is subject to the terms of the Mozilla Public
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt * License, v. 2.0. If a copy of the MPL was not distributed with this
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt#if defined(OPENSSL) && \
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt (defined(HAVE_OPENSSL_ED25519) || defined(HAVE_OPENSSL_ED448))
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt/* OpenSSL doesn't provide direct access to key values */
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic const unsigned char ed25519_pub_prefix[] = {
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic EVP_PKEY *pub_ed25519_to_ossl(const unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED25519SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt const unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(buf + PUBPREFIXLEN, key, DNS_KEY_ED25519SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt return (d2i_PUBKEY(NULL, &p, PUBPREFIXLEN + DNS_KEY_ED25519SIZE));
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic isc_result_t pub_ed25519_from_ossl(EVP_PKEY *pkey,
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED25519SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(key, buf + len - DNS_KEY_ED25519SIZE, DNS_KEY_ED25519SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic EVP_PKEY *pub_ed448_to_ossl(const unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED448SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt const unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(buf + PUBPREFIXLEN, key, DNS_KEY_ED448SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt return (d2i_PUBKEY(NULL, &p, PUBPREFIXLEN + DNS_KEY_ED448SIZE));
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic isc_result_t pub_ed448_from_ossl(EVP_PKEY *pkey,
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED448SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(key, buf + len - DNS_KEY_ED448SIZE, DNS_KEY_ED448SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic const unsigned char ed25519_priv_prefix[] = {
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic EVP_PKEY *priv_ed25519_to_ossl(const unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED25519SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt const unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(buf + PRIVPREFIXLEN, key, DNS_KEY_ED25519SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic isc_result_t priv_ed25519_from_ossl(EVP_PKEY *pkey,
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED25519SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(key, buf + len - DNS_KEY_ED25519SIZE, DNS_KEY_ED25519SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic EVP_PKEY *priv_ed448_to_ossl(const unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED448SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt const unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(buf + PRIVPREFIXLEN, key, DNS_KEY_ED448SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic isc_result_t priv_ed448_from_ossl(EVP_PKEY *pkey,
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *key)
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED448SIZE];
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt unsigned char *p;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt memmove(key, buf + len - DNS_KEY_ED448SIZE, DNS_KEY_ED448SIZE);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntstatic isc_result_t openssleddsa_todns(const dst_key_t *key,
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt result = isc_buffer_allocate(dctx->mctx, &buf, 64);
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt length = isc_buffer_length(buf) + data->length + 64;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt result = isc_buffer_allocate(dctx->mctx, &nbuf, length);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt if (!EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey))
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt "EVP_DigestSignInit",
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt "EVP_DigestSign",
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt "EVP_DigestVerifyInit",
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt "EVP_DigestVerify",
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt return (dst__openssl_toresult2("EVP_PKEY_CTX_new_id",
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt DST_RET (dst__openssl_toresult2("EVP_PKEY_keygen_init",
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt DST_RET (dst__openssl_toresult2("EVP_PKEY_keygen",
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt /* can check if first error is EC_R_INVALID_PRIVATE_KEY */
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) {
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_tofile(const dst_key_t *key, const char *directory) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt return (dst__privstruct_writefile(key, &priv, directory));
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt ret = dst__privstruct_writefile(key, &priv, directory);
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt ret = dst__privstruct_writefile(key, &priv, directory);
5832599943147268f9a4383d3dde39f8489bf339Evan Huntopenssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt /* read private key file */
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt ret = dst__privstruct_parse(key, DST_ALG_ED25519, lexer, mctx, &priv);
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt pkey = priv_ed25519_to_ossl(priv.elements[0].data);
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt#else /* HAVE_OPENSSL_EDxxx */
5832599943147268f9a4383d3dde39f8489bf339Evan Hunt#endif /* HAVE_OPENSSL_EDxxx */