109a3aaf3SDag-Erling Smørgrav /* 209a3aaf3SDag-Erling Smørgrav * keyraw.c - raw key operations and conversions 309a3aaf3SDag-Erling Smørgrav * 409a3aaf3SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2008 509a3aaf3SDag-Erling Smørgrav * 609a3aaf3SDag-Erling Smørgrav * See the file LICENSE for the license 709a3aaf3SDag-Erling Smørgrav */ 809a3aaf3SDag-Erling Smørgrav /** 909a3aaf3SDag-Erling Smørgrav * \file 1009a3aaf3SDag-Erling Smørgrav * Implementation of raw DNSKEY functions (work on wire rdata). 1109a3aaf3SDag-Erling Smørgrav */ 1209a3aaf3SDag-Erling Smørgrav 1309a3aaf3SDag-Erling Smørgrav #include "config.h" 1409a3aaf3SDag-Erling Smørgrav #include "sldns/keyraw.h" 1509a3aaf3SDag-Erling Smørgrav #include "sldns/rrdef.h" 1609a3aaf3SDag-Erling Smørgrav 1709a3aaf3SDag-Erling Smørgrav #ifdef HAVE_SSL 1809a3aaf3SDag-Erling Smørgrav #include <openssl/ssl.h> 1909a3aaf3SDag-Erling Smørgrav #include <openssl/evp.h> 2009a3aaf3SDag-Erling Smørgrav #include <openssl/rand.h> 2109a3aaf3SDag-Erling Smørgrav #include <openssl/err.h> 2209a3aaf3SDag-Erling Smørgrav #include <openssl/md5.h> 2309a3aaf3SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_ENGINE_H 2409a3aaf3SDag-Erling Smørgrav # include <openssl/engine.h> 2509a3aaf3SDag-Erling Smørgrav #endif 26b5663de9SDag-Erling Smørgrav #ifdef HAVE_OPENSSL_BN_H 27b5663de9SDag-Erling Smørgrav #include <openssl/bn.h> 28b5663de9SDag-Erling Smørgrav #endif 295469a995SCy Schubert #ifdef HAVE_OPENSSL_PARAM_BUILD_H 305469a995SCy Schubert # include <openssl/param_build.h> 315469a995SCy Schubert #else 32b5663de9SDag-Erling Smørgrav # ifdef HAVE_OPENSSL_RSA_H 33b5663de9SDag-Erling Smørgrav # include <openssl/rsa.h> 34b5663de9SDag-Erling Smørgrav # endif 35b5663de9SDag-Erling Smørgrav # ifdef HAVE_OPENSSL_DSA_H 36b5663de9SDag-Erling Smørgrav # include <openssl/dsa.h> 37b5663de9SDag-Erling Smørgrav # endif 385469a995SCy Schubert #endif 3909a3aaf3SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4009a3aaf3SDag-Erling Smørgrav 4109a3aaf3SDag-Erling Smørgrav size_t 4209a3aaf3SDag-Erling Smørgrav sldns_rr_dnskey_key_size_raw(const unsigned char* keydata, 4309a3aaf3SDag-Erling Smørgrav const size_t len, int alg) 4409a3aaf3SDag-Erling Smørgrav { 4509a3aaf3SDag-Erling Smørgrav /* for DSA keys */ 4609a3aaf3SDag-Erling Smørgrav uint8_t t; 4709a3aaf3SDag-Erling Smørgrav 4809a3aaf3SDag-Erling Smørgrav /* for RSA keys */ 4909a3aaf3SDag-Erling Smørgrav uint16_t exp; 5009a3aaf3SDag-Erling Smørgrav uint16_t int16; 5109a3aaf3SDag-Erling Smørgrav 5209a3aaf3SDag-Erling Smørgrav switch ((sldns_algorithm)alg) { 5309a3aaf3SDag-Erling Smørgrav case LDNS_DSA: 5409a3aaf3SDag-Erling Smørgrav case LDNS_DSA_NSEC3: 5509a3aaf3SDag-Erling Smørgrav if (len > 0) { 5609a3aaf3SDag-Erling Smørgrav t = keydata[0]; 5709a3aaf3SDag-Erling Smørgrav return (64 + t*8)*8; 5809a3aaf3SDag-Erling Smørgrav } else { 5909a3aaf3SDag-Erling Smørgrav return 0; 6009a3aaf3SDag-Erling Smørgrav } 6109a3aaf3SDag-Erling Smørgrav break; 6209a3aaf3SDag-Erling Smørgrav case LDNS_RSAMD5: 6309a3aaf3SDag-Erling Smørgrav case LDNS_RSASHA1: 6409a3aaf3SDag-Erling Smørgrav case LDNS_RSASHA1_NSEC3: 6509a3aaf3SDag-Erling Smørgrav #ifdef USE_SHA2 6609a3aaf3SDag-Erling Smørgrav case LDNS_RSASHA256: 6709a3aaf3SDag-Erling Smørgrav case LDNS_RSASHA512: 6809a3aaf3SDag-Erling Smørgrav #endif 6909a3aaf3SDag-Erling Smørgrav if (len > 0) { 7009a3aaf3SDag-Erling Smørgrav if (keydata[0] == 0) { 7109a3aaf3SDag-Erling Smørgrav /* big exponent */ 7209a3aaf3SDag-Erling Smørgrav if (len > 3) { 7309a3aaf3SDag-Erling Smørgrav memmove(&int16, keydata + 1, 2); 7409a3aaf3SDag-Erling Smørgrav exp = ntohs(int16); 7509a3aaf3SDag-Erling Smørgrav return (len - exp - 3)*8; 7609a3aaf3SDag-Erling Smørgrav } else { 7709a3aaf3SDag-Erling Smørgrav return 0; 7809a3aaf3SDag-Erling Smørgrav } 7909a3aaf3SDag-Erling Smørgrav } else { 8009a3aaf3SDag-Erling Smørgrav exp = keydata[0]; 8109a3aaf3SDag-Erling Smørgrav return (len-exp-1)*8; 8209a3aaf3SDag-Erling Smørgrav } 8309a3aaf3SDag-Erling Smørgrav } else { 8409a3aaf3SDag-Erling Smørgrav return 0; 8509a3aaf3SDag-Erling Smørgrav } 8609a3aaf3SDag-Erling Smørgrav break; 8709a3aaf3SDag-Erling Smørgrav #ifdef USE_GOST 8809a3aaf3SDag-Erling Smørgrav case LDNS_ECC_GOST: 8909a3aaf3SDag-Erling Smørgrav return 512; 9009a3aaf3SDag-Erling Smørgrav #endif 9109a3aaf3SDag-Erling Smørgrav #ifdef USE_ECDSA 9209a3aaf3SDag-Erling Smørgrav case LDNS_ECDSAP256SHA256: 9309a3aaf3SDag-Erling Smørgrav return 256; 9409a3aaf3SDag-Erling Smørgrav case LDNS_ECDSAP384SHA384: 9509a3aaf3SDag-Erling Smørgrav return 384; 9609a3aaf3SDag-Erling Smørgrav #endif 970fb34990SDag-Erling Smørgrav #ifdef USE_ED25519 980fb34990SDag-Erling Smørgrav case LDNS_ED25519: 990fb34990SDag-Erling Smørgrav return 256; 1000fb34990SDag-Erling Smørgrav #endif 1010fb34990SDag-Erling Smørgrav #ifdef USE_ED448 1020fb34990SDag-Erling Smørgrav case LDNS_ED448: 1030fb34990SDag-Erling Smørgrav return 456; 1040fb34990SDag-Erling Smørgrav #endif 10509a3aaf3SDag-Erling Smørgrav default: 10609a3aaf3SDag-Erling Smørgrav return 0; 10709a3aaf3SDag-Erling Smørgrav } 10809a3aaf3SDag-Erling Smørgrav } 10909a3aaf3SDag-Erling Smørgrav 11009a3aaf3SDag-Erling Smørgrav uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize) 11109a3aaf3SDag-Erling Smørgrav { 11209a3aaf3SDag-Erling Smørgrav if(keysize < 4) { 11309a3aaf3SDag-Erling Smørgrav return 0; 11409a3aaf3SDag-Erling Smørgrav } 11509a3aaf3SDag-Erling Smørgrav /* look at the algorithm field, copied from 2535bis */ 11609a3aaf3SDag-Erling Smørgrav if (key[3] == LDNS_RSAMD5) { 11709a3aaf3SDag-Erling Smørgrav uint16_t ac16 = 0; 11809a3aaf3SDag-Erling Smørgrav if (keysize > 4) { 11909a3aaf3SDag-Erling Smørgrav memmove(&ac16, key + keysize - 3, 2); 12009a3aaf3SDag-Erling Smørgrav } 12109a3aaf3SDag-Erling Smørgrav ac16 = ntohs(ac16); 12209a3aaf3SDag-Erling Smørgrav return (uint16_t) ac16; 12309a3aaf3SDag-Erling Smørgrav } else { 12409a3aaf3SDag-Erling Smørgrav size_t i; 12509a3aaf3SDag-Erling Smørgrav uint32_t ac32 = 0; 12609a3aaf3SDag-Erling Smørgrav for (i = 0; i < keysize; ++i) { 12709a3aaf3SDag-Erling Smørgrav ac32 += (i & 1) ? key[i] : key[i] << 8; 12809a3aaf3SDag-Erling Smørgrav } 12909a3aaf3SDag-Erling Smørgrav ac32 += (ac32 >> 16) & 0xFFFF; 13009a3aaf3SDag-Erling Smørgrav return (uint16_t) (ac32 & 0xFFFF); 13109a3aaf3SDag-Erling Smørgrav } 13209a3aaf3SDag-Erling Smørgrav } 13309a3aaf3SDag-Erling Smørgrav 13409a3aaf3SDag-Erling Smørgrav #ifdef HAVE_SSL 13509a3aaf3SDag-Erling Smørgrav #ifdef USE_GOST 13609a3aaf3SDag-Erling Smørgrav /** store GOST engine reference loaded into OpenSSL library */ 13709a3aaf3SDag-Erling Smørgrav ENGINE* sldns_gost_engine = NULL; 13809a3aaf3SDag-Erling Smørgrav 13909a3aaf3SDag-Erling Smørgrav int 14009a3aaf3SDag-Erling Smørgrav sldns_key_EVP_load_gost_id(void) 14109a3aaf3SDag-Erling Smørgrav { 14209a3aaf3SDag-Erling Smørgrav static int gost_id = 0; 14309a3aaf3SDag-Erling Smørgrav const EVP_PKEY_ASN1_METHOD* meth; 14409a3aaf3SDag-Erling Smørgrav ENGINE* e; 14509a3aaf3SDag-Erling Smørgrav 14609a3aaf3SDag-Erling Smørgrav if(gost_id) return gost_id; 14709a3aaf3SDag-Erling Smørgrav 14809a3aaf3SDag-Erling Smørgrav /* see if configuration loaded gost implementation from other engine*/ 14909a3aaf3SDag-Erling Smørgrav meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1); 15009a3aaf3SDag-Erling Smørgrav if(meth) { 15109a3aaf3SDag-Erling Smørgrav EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 15209a3aaf3SDag-Erling Smørgrav return gost_id; 15309a3aaf3SDag-Erling Smørgrav } 15409a3aaf3SDag-Erling Smørgrav 15509a3aaf3SDag-Erling Smørgrav /* see if engine can be loaded already */ 15609a3aaf3SDag-Erling Smørgrav e = ENGINE_by_id("gost"); 15709a3aaf3SDag-Erling Smørgrav if(!e) { 15809a3aaf3SDag-Erling Smørgrav /* load it ourself, in case statically linked */ 15909a3aaf3SDag-Erling Smørgrav ENGINE_load_builtin_engines(); 16009a3aaf3SDag-Erling Smørgrav ENGINE_load_dynamic(); 16109a3aaf3SDag-Erling Smørgrav e = ENGINE_by_id("gost"); 16209a3aaf3SDag-Erling Smørgrav } 16309a3aaf3SDag-Erling Smørgrav if(!e) { 16409a3aaf3SDag-Erling Smørgrav /* no gost engine in openssl */ 16509a3aaf3SDag-Erling Smørgrav return 0; 16609a3aaf3SDag-Erling Smørgrav } 16709a3aaf3SDag-Erling Smørgrav if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { 16809a3aaf3SDag-Erling Smørgrav ENGINE_finish(e); 16909a3aaf3SDag-Erling Smørgrav ENGINE_free(e); 17009a3aaf3SDag-Erling Smørgrav return 0; 17109a3aaf3SDag-Erling Smørgrav } 17209a3aaf3SDag-Erling Smørgrav 17309a3aaf3SDag-Erling Smørgrav meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1); 17409a3aaf3SDag-Erling Smørgrav if(!meth) { 17509a3aaf3SDag-Erling Smørgrav /* algo not found */ 17609a3aaf3SDag-Erling Smørgrav ENGINE_finish(e); 17709a3aaf3SDag-Erling Smørgrav ENGINE_free(e); 17809a3aaf3SDag-Erling Smørgrav return 0; 17909a3aaf3SDag-Erling Smørgrav } 18009a3aaf3SDag-Erling Smørgrav /* Note: do not ENGINE_finish and ENGINE_free the acquired engine 18109a3aaf3SDag-Erling Smørgrav * on some platforms this frees up the meth and unloads gost stuff */ 18209a3aaf3SDag-Erling Smørgrav sldns_gost_engine = e; 18309a3aaf3SDag-Erling Smørgrav 18409a3aaf3SDag-Erling Smørgrav EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 18509a3aaf3SDag-Erling Smørgrav return gost_id; 18609a3aaf3SDag-Erling Smørgrav } 18709a3aaf3SDag-Erling Smørgrav 18809a3aaf3SDag-Erling Smørgrav void sldns_key_EVP_unload_gost(void) 18909a3aaf3SDag-Erling Smørgrav { 19009a3aaf3SDag-Erling Smørgrav if(sldns_gost_engine) { 19109a3aaf3SDag-Erling Smørgrav ENGINE_finish(sldns_gost_engine); 19209a3aaf3SDag-Erling Smørgrav ENGINE_free(sldns_gost_engine); 19309a3aaf3SDag-Erling Smørgrav sldns_gost_engine = NULL; 19409a3aaf3SDag-Erling Smørgrav } 19509a3aaf3SDag-Erling Smørgrav } 19609a3aaf3SDag-Erling Smørgrav #endif /* USE_GOST */ 19709a3aaf3SDag-Erling Smørgrav 198*be771a7bSCy Schubert #ifdef USE_DSA 1995469a995SCy Schubert /* Retrieve params as BIGNUM from raw buffer */ 2005469a995SCy Schubert static int 2015469a995SCy Schubert sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p, 2025469a995SCy Schubert BIGNUM** q, BIGNUM** g, BIGNUM** y) 20309a3aaf3SDag-Erling Smørgrav { 20409a3aaf3SDag-Erling Smørgrav uint8_t T; 20509a3aaf3SDag-Erling Smørgrav uint16_t length; 20609a3aaf3SDag-Erling Smørgrav uint16_t offset; 20709a3aaf3SDag-Erling Smørgrav 20809a3aaf3SDag-Erling Smørgrav if(len == 0) 2095469a995SCy Schubert return 0; 21009a3aaf3SDag-Erling Smørgrav T = (uint8_t)key[0]; 21109a3aaf3SDag-Erling Smørgrav length = (64 + T * 8); 21209a3aaf3SDag-Erling Smørgrav offset = 1; 21309a3aaf3SDag-Erling Smørgrav 21409a3aaf3SDag-Erling Smørgrav if (T > 8) { 2155469a995SCy Schubert return 0; 21609a3aaf3SDag-Erling Smørgrav } 21709a3aaf3SDag-Erling Smørgrav if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length) 2185469a995SCy Schubert return 0; 21909a3aaf3SDag-Erling Smørgrav 2205469a995SCy Schubert *q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL); 22109a3aaf3SDag-Erling Smørgrav offset += SHA_DIGEST_LENGTH; 22209a3aaf3SDag-Erling Smørgrav 2235469a995SCy Schubert *p = BN_bin2bn(key+offset, (int)length, NULL); 22409a3aaf3SDag-Erling Smørgrav offset += length; 22509a3aaf3SDag-Erling Smørgrav 2265469a995SCy Schubert *g = BN_bin2bn(key+offset, (int)length, NULL); 22709a3aaf3SDag-Erling Smørgrav offset += length; 22809a3aaf3SDag-Erling Smørgrav 2295469a995SCy Schubert *y = BN_bin2bn(key+offset, (int)length, NULL); 23009a3aaf3SDag-Erling Smørgrav 2315469a995SCy Schubert if(!*q || !*p || !*g || !*y) { 2325469a995SCy Schubert BN_free(*q); 2335469a995SCy Schubert BN_free(*p); 2345469a995SCy Schubert BN_free(*g); 2355469a995SCy Schubert BN_free(*y); 2365469a995SCy Schubert return 0; 2375469a995SCy Schubert } 2385469a995SCy Schubert return 1; 2395469a995SCy Schubert } 2405469a995SCy Schubert 2415469a995SCy Schubert #ifndef HAVE_OSSL_PARAM_BLD_NEW 2425469a995SCy Schubert DSA * 2435469a995SCy Schubert sldns_key_buf2dsa_raw(unsigned char* key, size_t len) 2445469a995SCy Schubert { 2455469a995SCy Schubert DSA *dsa; 2465469a995SCy Schubert BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL; 2475469a995SCy Schubert if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) { 2485469a995SCy Schubert return NULL; 2495469a995SCy Schubert } 25009a3aaf3SDag-Erling Smørgrav /* create the key and set its properties */ 2515469a995SCy Schubert if(!(dsa = DSA_new())) { 25209a3aaf3SDag-Erling Smørgrav return NULL; 25309a3aaf3SDag-Erling Smørgrav } 2549cf5bc93SCy Schubert #if OPENSSL_VERSION_NUMBER < 0x10100000 || \ 2559cf5bc93SCy Schubert (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f) 25609a3aaf3SDag-Erling Smørgrav #ifndef S_SPLINT_S 25709a3aaf3SDag-Erling Smørgrav dsa->p = P; 25809a3aaf3SDag-Erling Smørgrav dsa->q = Q; 25909a3aaf3SDag-Erling Smørgrav dsa->g = G; 26009a3aaf3SDag-Erling Smørgrav dsa->pub_key = Y; 26109a3aaf3SDag-Erling Smørgrav #endif /* splint */ 26209a3aaf3SDag-Erling Smørgrav 263b5663de9SDag-Erling Smørgrav #else /* OPENSSL_VERSION_NUMBER */ 264b5663de9SDag-Erling Smørgrav if (!DSA_set0_pqg(dsa, P, Q, G)) { 265b5663de9SDag-Erling Smørgrav /* QPG not yet attached, need to free */ 266b5663de9SDag-Erling Smørgrav BN_free(Q); 267b5663de9SDag-Erling Smørgrav BN_free(P); 268b5663de9SDag-Erling Smørgrav BN_free(G); 269b5663de9SDag-Erling Smørgrav 270b5663de9SDag-Erling Smørgrav DSA_free(dsa); 271b5663de9SDag-Erling Smørgrav BN_free(Y); 272b5663de9SDag-Erling Smørgrav return NULL; 273b5663de9SDag-Erling Smørgrav } 274b5663de9SDag-Erling Smørgrav if (!DSA_set0_key(dsa, Y, NULL)) { 275b5663de9SDag-Erling Smørgrav /* QPG attached, cleaned up by DSA_fre() */ 276b5663de9SDag-Erling Smørgrav DSA_free(dsa); 277b5663de9SDag-Erling Smørgrav BN_free(Y); 278b5663de9SDag-Erling Smørgrav return NULL; 279b5663de9SDag-Erling Smørgrav } 280b5663de9SDag-Erling Smørgrav #endif 281b5663de9SDag-Erling Smørgrav 28209a3aaf3SDag-Erling Smørgrav return dsa; 28309a3aaf3SDag-Erling Smørgrav } 2845469a995SCy Schubert #endif /* HAVE_OSSL_PARAM_BLD_NEW */ 28509a3aaf3SDag-Erling Smørgrav 2865469a995SCy Schubert EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len) 2875469a995SCy Schubert { 2885469a995SCy Schubert #ifdef HAVE_OSSL_PARAM_BLD_NEW 2895469a995SCy Schubert EVP_PKEY* evp_key = NULL; 2905469a995SCy Schubert EVP_PKEY_CTX* ctx; 2915469a995SCy Schubert BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL; 2925469a995SCy Schubert OSSL_PARAM_BLD* param_bld; 2935469a995SCy Schubert OSSL_PARAM* params = NULL; 2945469a995SCy Schubert if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) { 2955469a995SCy Schubert return NULL; 2965469a995SCy Schubert } 2975469a995SCy Schubert 2985469a995SCy Schubert param_bld = OSSL_PARAM_BLD_new(); 2995469a995SCy Schubert if(!param_bld) { 3005469a995SCy Schubert BN_free(p); 3015469a995SCy Schubert BN_free(q); 3025469a995SCy Schubert BN_free(g); 3035469a995SCy Schubert BN_free(y); 3045469a995SCy Schubert return NULL; 3055469a995SCy Schubert } 3065469a995SCy Schubert if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) || 3075469a995SCy Schubert !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) || 3085469a995SCy Schubert !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) || 3095469a995SCy Schubert !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) { 3105469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 3115469a995SCy Schubert BN_free(p); 3125469a995SCy Schubert BN_free(q); 3135469a995SCy Schubert BN_free(g); 3145469a995SCy Schubert BN_free(y); 3155469a995SCy Schubert return NULL; 3165469a995SCy Schubert } 3175469a995SCy Schubert params = OSSL_PARAM_BLD_to_param(param_bld); 3185469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 3195469a995SCy Schubert 3205469a995SCy Schubert ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); 3215469a995SCy Schubert if(!ctx) { 3225469a995SCy Schubert OSSL_PARAM_free(params); 3235469a995SCy Schubert BN_free(p); 3245469a995SCy Schubert BN_free(q); 3255469a995SCy Schubert BN_free(g); 3265469a995SCy Schubert BN_free(y); 3275469a995SCy Schubert return NULL; 3285469a995SCy Schubert } 3295469a995SCy Schubert if(EVP_PKEY_fromdata_init(ctx) <= 0) { 3305469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 3315469a995SCy Schubert OSSL_PARAM_free(params); 3325469a995SCy Schubert BN_free(p); 3335469a995SCy Schubert BN_free(q); 3345469a995SCy Schubert BN_free(g); 3355469a995SCy Schubert BN_free(y); 3365469a995SCy Schubert return NULL; 3375469a995SCy Schubert } 3385469a995SCy Schubert if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) { 3395469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 3405469a995SCy Schubert OSSL_PARAM_free(params); 3415469a995SCy Schubert BN_free(p); 3425469a995SCy Schubert BN_free(q); 3435469a995SCy Schubert BN_free(g); 3445469a995SCy Schubert BN_free(y); 3455469a995SCy Schubert return NULL; 3465469a995SCy Schubert } 3475469a995SCy Schubert 3485469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 3495469a995SCy Schubert OSSL_PARAM_free(params); 3505469a995SCy Schubert BN_free(p); 3515469a995SCy Schubert BN_free(q); 3525469a995SCy Schubert BN_free(g); 3535469a995SCy Schubert BN_free(y); 3545469a995SCy Schubert return evp_key; 3555469a995SCy Schubert #else 3565469a995SCy Schubert DSA* dsa; 3575469a995SCy Schubert EVP_PKEY* evp_key = EVP_PKEY_new(); 3585469a995SCy Schubert if(!evp_key) { 3595469a995SCy Schubert return NULL; 3605469a995SCy Schubert } 3615469a995SCy Schubert dsa = sldns_key_buf2dsa_raw(key, len); 3625469a995SCy Schubert if(!dsa) { 3635469a995SCy Schubert EVP_PKEY_free(evp_key); 3645469a995SCy Schubert return NULL; 3655469a995SCy Schubert } 3665469a995SCy Schubert if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) { 3675469a995SCy Schubert DSA_free(dsa); 3685469a995SCy Schubert EVP_PKEY_free(evp_key); 3695469a995SCy Schubert return NULL; 3705469a995SCy Schubert } 3715469a995SCy Schubert return evp_key; 3725469a995SCy Schubert #endif 3735469a995SCy Schubert } 374*be771a7bSCy Schubert #endif /* USE_DSA */ 3755469a995SCy Schubert 3765469a995SCy Schubert /* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */ 3775469a995SCy Schubert static int 3785469a995SCy Schubert sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n, 3795469a995SCy Schubert BIGNUM** e) 38009a3aaf3SDag-Erling Smørgrav { 38109a3aaf3SDag-Erling Smørgrav uint16_t offset; 38209a3aaf3SDag-Erling Smørgrav uint16_t exp; 38309a3aaf3SDag-Erling Smørgrav uint16_t int16; 38409a3aaf3SDag-Erling Smørgrav 38509a3aaf3SDag-Erling Smørgrav if (len == 0) 3865469a995SCy Schubert return 0; 38709a3aaf3SDag-Erling Smørgrav if (key[0] == 0) { 38809a3aaf3SDag-Erling Smørgrav if(len < 3) 3895469a995SCy Schubert return 0; 39009a3aaf3SDag-Erling Smørgrav memmove(&int16, key+1, 2); 39109a3aaf3SDag-Erling Smørgrav exp = ntohs(int16); 39209a3aaf3SDag-Erling Smørgrav offset = 3; 39309a3aaf3SDag-Erling Smørgrav } else { 39409a3aaf3SDag-Erling Smørgrav exp = key[0]; 39509a3aaf3SDag-Erling Smørgrav offset = 1; 39609a3aaf3SDag-Erling Smørgrav } 39709a3aaf3SDag-Erling Smørgrav 39809a3aaf3SDag-Erling Smørgrav /* key length at least one */ 39909a3aaf3SDag-Erling Smørgrav if(len < (size_t)offset + exp + 1) 4005469a995SCy Schubert return 0; 40109a3aaf3SDag-Erling Smørgrav 40209a3aaf3SDag-Erling Smørgrav /* Exponent */ 4035469a995SCy Schubert *e = BN_new(); 4045469a995SCy Schubert if(!*e) return 0; 4055469a995SCy Schubert (void) BN_bin2bn(key+offset, (int)exp, *e); 40609a3aaf3SDag-Erling Smørgrav offset += exp; 40709a3aaf3SDag-Erling Smørgrav 40809a3aaf3SDag-Erling Smørgrav /* Modulus */ 4095469a995SCy Schubert *n = BN_new(); 4105469a995SCy Schubert if(!*n) { 4115469a995SCy Schubert BN_free(*e); 4125469a995SCy Schubert return 0; 41309a3aaf3SDag-Erling Smørgrav } 41409a3aaf3SDag-Erling Smørgrav /* length of the buffer must match the key length! */ 4155469a995SCy Schubert (void) BN_bin2bn(key+offset, (int)(len - offset), *n); 4165469a995SCy Schubert return 1; 4175469a995SCy Schubert } 41809a3aaf3SDag-Erling Smørgrav 4195469a995SCy Schubert #ifndef HAVE_OSSL_PARAM_BLD_NEW 4205469a995SCy Schubert RSA * 4215469a995SCy Schubert sldns_key_buf2rsa_raw(unsigned char* key, size_t len) 4225469a995SCy Schubert { 4235469a995SCy Schubert BIGNUM* modulus = NULL; 4245469a995SCy Schubert BIGNUM* exponent = NULL; 4255469a995SCy Schubert RSA *rsa; 4265469a995SCy Schubert if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent)) 4275469a995SCy Schubert return NULL; 42809a3aaf3SDag-Erling Smørgrav rsa = RSA_new(); 42909a3aaf3SDag-Erling Smørgrav if(!rsa) { 43009a3aaf3SDag-Erling Smørgrav BN_free(exponent); 43109a3aaf3SDag-Erling Smørgrav BN_free(modulus); 43209a3aaf3SDag-Erling Smørgrav return NULL; 43309a3aaf3SDag-Erling Smørgrav } 4349cf5bc93SCy Schubert #if OPENSSL_VERSION_NUMBER < 0x10100000 || \ 4359cf5bc93SCy Schubert (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f) 43609a3aaf3SDag-Erling Smørgrav #ifndef S_SPLINT_S 43709a3aaf3SDag-Erling Smørgrav rsa->n = modulus; 43809a3aaf3SDag-Erling Smørgrav rsa->e = exponent; 43909a3aaf3SDag-Erling Smørgrav #endif /* splint */ 44009a3aaf3SDag-Erling Smørgrav 441b5663de9SDag-Erling Smørgrav #else /* OPENSSL_VERSION_NUMBER */ 442b5663de9SDag-Erling Smørgrav if (!RSA_set0_key(rsa, modulus, exponent, NULL)) { 443b5663de9SDag-Erling Smørgrav BN_free(exponent); 444b5663de9SDag-Erling Smørgrav BN_free(modulus); 445b5663de9SDag-Erling Smørgrav RSA_free(rsa); 446b5663de9SDag-Erling Smørgrav return NULL; 447b5663de9SDag-Erling Smørgrav } 448b5663de9SDag-Erling Smørgrav #endif 449b5663de9SDag-Erling Smørgrav 45009a3aaf3SDag-Erling Smørgrav return rsa; 45109a3aaf3SDag-Erling Smørgrav } 4525469a995SCy Schubert #endif /* HAVE_OSSL_PARAM_BLD_NEW */ 4535469a995SCy Schubert 4545469a995SCy Schubert EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len) 4555469a995SCy Schubert { 4565469a995SCy Schubert #ifdef HAVE_OSSL_PARAM_BLD_NEW 4575469a995SCy Schubert EVP_PKEY* evp_key = NULL; 4585469a995SCy Schubert EVP_PKEY_CTX* ctx; 4595469a995SCy Schubert BIGNUM *n=NULL, *e=NULL; 4605469a995SCy Schubert OSSL_PARAM_BLD* param_bld; 4615469a995SCy Schubert OSSL_PARAM* params = NULL; 4625469a995SCy Schubert 4635469a995SCy Schubert if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) { 4645469a995SCy Schubert return NULL; 4655469a995SCy Schubert } 4665469a995SCy Schubert 4675469a995SCy Schubert param_bld = OSSL_PARAM_BLD_new(); 4685469a995SCy Schubert if(!param_bld) { 4695469a995SCy Schubert BN_free(n); 4705469a995SCy Schubert BN_free(e); 4715469a995SCy Schubert return NULL; 4725469a995SCy Schubert } 4735469a995SCy Schubert if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) { 4745469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 4755469a995SCy Schubert BN_free(n); 4765469a995SCy Schubert BN_free(e); 4775469a995SCy Schubert return NULL; 4785469a995SCy Schubert } 4795469a995SCy Schubert if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) { 4805469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 4815469a995SCy Schubert BN_free(n); 4825469a995SCy Schubert BN_free(e); 4835469a995SCy Schubert return NULL; 4845469a995SCy Schubert } 4855469a995SCy Schubert params = OSSL_PARAM_BLD_to_param(param_bld); 4865469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 4875469a995SCy Schubert 4885469a995SCy Schubert ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); 4895469a995SCy Schubert if(!ctx) { 4905469a995SCy Schubert OSSL_PARAM_free(params); 4915469a995SCy Schubert BN_free(n); 4925469a995SCy Schubert BN_free(e); 4935469a995SCy Schubert return NULL; 4945469a995SCy Schubert } 4955469a995SCy Schubert if(EVP_PKEY_fromdata_init(ctx) <= 0) { 4965469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 4975469a995SCy Schubert OSSL_PARAM_free(params); 4985469a995SCy Schubert BN_free(n); 4995469a995SCy Schubert BN_free(e); 5005469a995SCy Schubert return NULL; 5015469a995SCy Schubert } 5025469a995SCy Schubert if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) { 5035469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 5045469a995SCy Schubert OSSL_PARAM_free(params); 5055469a995SCy Schubert BN_free(n); 5065469a995SCy Schubert BN_free(e); 5075469a995SCy Schubert return NULL; 5085469a995SCy Schubert } 5095469a995SCy Schubert 5105469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 5115469a995SCy Schubert OSSL_PARAM_free(params); 5125469a995SCy Schubert BN_free(n); 5135469a995SCy Schubert BN_free(e); 5145469a995SCy Schubert return evp_key; 5155469a995SCy Schubert #else 5165469a995SCy Schubert RSA* rsa; 5175469a995SCy Schubert EVP_PKEY *evp_key = EVP_PKEY_new(); 5185469a995SCy Schubert if(!evp_key) { 5195469a995SCy Schubert return NULL; 5205469a995SCy Schubert } 5215469a995SCy Schubert rsa = sldns_key_buf2rsa_raw(key, len); 5225469a995SCy Schubert if(!rsa) { 5235469a995SCy Schubert EVP_PKEY_free(evp_key); 5245469a995SCy Schubert return NULL; 5255469a995SCy Schubert } 5265469a995SCy Schubert if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) { 5275469a995SCy Schubert RSA_free(rsa); 5285469a995SCy Schubert EVP_PKEY_free(evp_key); 5295469a995SCy Schubert return NULL; 5305469a995SCy Schubert } 5315469a995SCy Schubert return evp_key; 5325469a995SCy Schubert #endif 5335469a995SCy Schubert } 53409a3aaf3SDag-Erling Smørgrav 53509a3aaf3SDag-Erling Smørgrav #ifdef USE_GOST 53609a3aaf3SDag-Erling Smørgrav EVP_PKEY* 53709a3aaf3SDag-Erling Smørgrav sldns_gost2pkey_raw(unsigned char* key, size_t keylen) 53809a3aaf3SDag-Erling Smørgrav { 53909a3aaf3SDag-Erling Smørgrav /* prefix header for X509 encoding */ 54009a3aaf3SDag-Erling Smørgrav uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 54109a3aaf3SDag-Erling Smørgrav 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 54209a3aaf3SDag-Erling Smørgrav 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 54309a3aaf3SDag-Erling Smørgrav 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40}; 54409a3aaf3SDag-Erling Smørgrav unsigned char encoded[37+64]; 54509a3aaf3SDag-Erling Smørgrav const unsigned char* pp; 54609a3aaf3SDag-Erling Smørgrav if(keylen != 64) { 54709a3aaf3SDag-Erling Smørgrav /* key wrong size */ 54809a3aaf3SDag-Erling Smørgrav return NULL; 54909a3aaf3SDag-Erling Smørgrav } 55009a3aaf3SDag-Erling Smørgrav 55109a3aaf3SDag-Erling Smørgrav /* create evp_key */ 55209a3aaf3SDag-Erling Smørgrav memmove(encoded, asn, 37); 55309a3aaf3SDag-Erling Smørgrav memmove(encoded+37, key, 64); 55409a3aaf3SDag-Erling Smørgrav pp = (unsigned char*)&encoded[0]; 55509a3aaf3SDag-Erling Smørgrav 55609a3aaf3SDag-Erling Smørgrav return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded)); 55709a3aaf3SDag-Erling Smørgrav } 55809a3aaf3SDag-Erling Smørgrav #endif /* USE_GOST */ 55909a3aaf3SDag-Erling Smørgrav 56009a3aaf3SDag-Erling Smørgrav #ifdef USE_ECDSA 56109a3aaf3SDag-Erling Smørgrav EVP_PKEY* 56209a3aaf3SDag-Erling Smørgrav sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo) 56309a3aaf3SDag-Erling Smørgrav { 5645469a995SCy Schubert #ifdef HAVE_OSSL_PARAM_BLD_NEW 5655469a995SCy Schubert unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 5665469a995SCy Schubert EVP_PKEY *evp_key = NULL; 5675469a995SCy Schubert EVP_PKEY_CTX* ctx; 5685469a995SCy Schubert OSSL_PARAM_BLD* param_bld; 5695469a995SCy Schubert OSSL_PARAM* params = NULL; 5705469a995SCy Schubert char* group = NULL; 5715469a995SCy Schubert 5725469a995SCy Schubert /* check length, which uncompressed must be 2 bignums */ 5735469a995SCy Schubert if(algo == LDNS_ECDSAP256SHA256) { 5745469a995SCy Schubert if(keylen != 2*256/8) return NULL; 5755469a995SCy Schubert group = "prime256v1"; 5765469a995SCy Schubert } else if(algo == LDNS_ECDSAP384SHA384) { 5775469a995SCy Schubert if(keylen != 2*384/8) return NULL; 5785469a995SCy Schubert group = "P-384"; 5795469a995SCy Schubert } else { 5805469a995SCy Schubert return NULL; 5815469a995SCy Schubert } 5825469a995SCy Schubert if(keylen+1 > sizeof(buf)) { /* sanity check */ 5835469a995SCy Schubert return NULL; 5845469a995SCy Schubert } 5855469a995SCy Schubert /* prepend the 0x04 for uncompressed format */ 5865469a995SCy Schubert buf[0] = POINT_CONVERSION_UNCOMPRESSED; 5875469a995SCy Schubert memmove(buf+1, key, keylen); 5885469a995SCy Schubert 5895469a995SCy Schubert param_bld = OSSL_PARAM_BLD_new(); 5905469a995SCy Schubert if(!param_bld) { 5915469a995SCy Schubert return NULL; 5925469a995SCy Schubert } 5935469a995SCy Schubert if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) || 5945469a995SCy Schubert !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) { 5955469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 5965469a995SCy Schubert return NULL; 5975469a995SCy Schubert } 5985469a995SCy Schubert params = OSSL_PARAM_BLD_to_param(param_bld); 5995469a995SCy Schubert OSSL_PARAM_BLD_free(param_bld); 6005469a995SCy Schubert 6015469a995SCy Schubert ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); 6025469a995SCy Schubert if(!ctx) { 6035469a995SCy Schubert OSSL_PARAM_free(params); 6045469a995SCy Schubert return NULL; 6055469a995SCy Schubert } 6065469a995SCy Schubert if(EVP_PKEY_fromdata_init(ctx) <= 0) { 6075469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 6085469a995SCy Schubert OSSL_PARAM_free(params); 6095469a995SCy Schubert return NULL; 6105469a995SCy Schubert } 6115469a995SCy Schubert if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) { 6125469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 6135469a995SCy Schubert OSSL_PARAM_free(params); 6145469a995SCy Schubert return NULL; 6155469a995SCy Schubert } 6165469a995SCy Schubert EVP_PKEY_CTX_free(ctx); 6175469a995SCy Schubert OSSL_PARAM_free(params); 6185469a995SCy Schubert return evp_key; 6195469a995SCy Schubert #else 62009a3aaf3SDag-Erling Smørgrav unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ 62109a3aaf3SDag-Erling Smørgrav const unsigned char* pp = buf; 62209a3aaf3SDag-Erling Smørgrav EVP_PKEY *evp_key; 62309a3aaf3SDag-Erling Smørgrav EC_KEY *ec; 62409a3aaf3SDag-Erling Smørgrav /* check length, which uncompressed must be 2 bignums */ 62509a3aaf3SDag-Erling Smørgrav if(algo == LDNS_ECDSAP256SHA256) { 62609a3aaf3SDag-Erling Smørgrav if(keylen != 2*256/8) return NULL; 62709a3aaf3SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 62809a3aaf3SDag-Erling Smørgrav } else if(algo == LDNS_ECDSAP384SHA384) { 62909a3aaf3SDag-Erling Smørgrav if(keylen != 2*384/8) return NULL; 63009a3aaf3SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 63109a3aaf3SDag-Erling Smørgrav } else ec = NULL; 63209a3aaf3SDag-Erling Smørgrav if(!ec) return NULL; 63309a3aaf3SDag-Erling Smørgrav if(keylen+1 > sizeof(buf)) { /* sanity check */ 63409a3aaf3SDag-Erling Smørgrav EC_KEY_free(ec); 63509a3aaf3SDag-Erling Smørgrav return NULL; 63609a3aaf3SDag-Erling Smørgrav } 63709a3aaf3SDag-Erling Smørgrav /* prepend the 0x02 (from docs) (or actually 0x04 from implementation 63809a3aaf3SDag-Erling Smørgrav * of openssl) for uncompressed data */ 63909a3aaf3SDag-Erling Smørgrav buf[0] = POINT_CONVERSION_UNCOMPRESSED; 64009a3aaf3SDag-Erling Smørgrav memmove(buf+1, key, keylen); 64109a3aaf3SDag-Erling Smørgrav if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) { 64209a3aaf3SDag-Erling Smørgrav EC_KEY_free(ec); 64309a3aaf3SDag-Erling Smørgrav return NULL; 64409a3aaf3SDag-Erling Smørgrav } 64509a3aaf3SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 64609a3aaf3SDag-Erling Smørgrav if(!evp_key) { 64709a3aaf3SDag-Erling Smørgrav EC_KEY_free(ec); 64809a3aaf3SDag-Erling Smørgrav return NULL; 64909a3aaf3SDag-Erling Smørgrav } 65009a3aaf3SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { 65109a3aaf3SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 65209a3aaf3SDag-Erling Smørgrav EC_KEY_free(ec); 65309a3aaf3SDag-Erling Smørgrav return NULL; 65409a3aaf3SDag-Erling Smørgrav } 65509a3aaf3SDag-Erling Smørgrav return evp_key; 6565469a995SCy Schubert #endif /* HAVE_OSSL_PARAM_BLD_NEW */ 65709a3aaf3SDag-Erling Smørgrav } 65809a3aaf3SDag-Erling Smørgrav #endif /* USE_ECDSA */ 65909a3aaf3SDag-Erling Smørgrav 660c7f4d7adSDag-Erling Smørgrav #ifdef USE_ED25519 661c7f4d7adSDag-Erling Smørgrav EVP_PKEY* 662c7f4d7adSDag-Erling Smørgrav sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen) 663c7f4d7adSDag-Erling Smørgrav { 664c7f4d7adSDag-Erling Smørgrav /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */ 665c7f4d7adSDag-Erling Smørgrav uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 666c7f4d7adSDag-Erling Smørgrav 0x70, 0x03, 0x21, 0x00}; 667c7f4d7adSDag-Erling Smørgrav int pre_len = 12; 668c7f4d7adSDag-Erling Smørgrav uint8_t buf[256]; 669c7f4d7adSDag-Erling Smørgrav EVP_PKEY *evp_key; 670c7f4d7adSDag-Erling Smørgrav /* pp gets modified by d2i() */ 671c7f4d7adSDag-Erling Smørgrav const unsigned char* pp = (unsigned char*)buf; 672c7f4d7adSDag-Erling Smørgrav if(keylen != 32 || keylen + pre_len > sizeof(buf)) 673c7f4d7adSDag-Erling Smørgrav return NULL; /* wrong length */ 674c7f4d7adSDag-Erling Smørgrav memmove(buf, pre, pre_len); 675c7f4d7adSDag-Erling Smørgrav memmove(buf+pre_len, key, keylen); 676c7f4d7adSDag-Erling Smørgrav evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen)); 677c7f4d7adSDag-Erling Smørgrav return evp_key; 678c7f4d7adSDag-Erling Smørgrav } 679c7f4d7adSDag-Erling Smørgrav #endif /* USE_ED25519 */ 680c7f4d7adSDag-Erling Smørgrav 6810fb34990SDag-Erling Smørgrav #ifdef USE_ED448 6820fb34990SDag-Erling Smørgrav EVP_PKEY* 6830fb34990SDag-Erling Smørgrav sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen) 6840fb34990SDag-Erling Smørgrav { 6850fb34990SDag-Erling Smørgrav /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */ 6860fb34990SDag-Erling Smørgrav uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 6870fb34990SDag-Erling Smørgrav 0x71, 0x03, 0x3a, 0x00}; 6880fb34990SDag-Erling Smørgrav int pre_len = 12; 6890fb34990SDag-Erling Smørgrav uint8_t buf[256]; 6900fb34990SDag-Erling Smørgrav EVP_PKEY *evp_key; 6910fb34990SDag-Erling Smørgrav /* pp gets modified by d2i() */ 6920fb34990SDag-Erling Smørgrav const unsigned char* pp = (unsigned char*)buf; 6930fb34990SDag-Erling Smørgrav if(keylen != 57 || keylen + pre_len > sizeof(buf)) 6940fb34990SDag-Erling Smørgrav return NULL; /* wrong length */ 6950fb34990SDag-Erling Smørgrav memmove(buf, pre, pre_len); 6960fb34990SDag-Erling Smørgrav memmove(buf+pre_len, key, keylen); 6970fb34990SDag-Erling Smørgrav evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen)); 6980fb34990SDag-Erling Smørgrav return evp_key; 6990fb34990SDag-Erling Smørgrav } 7000fb34990SDag-Erling Smørgrav #endif /* USE_ED448 */ 7010fb34990SDag-Erling Smørgrav 70209a3aaf3SDag-Erling Smørgrav int 70309a3aaf3SDag-Erling Smørgrav sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest, 70409a3aaf3SDag-Erling Smørgrav const EVP_MD* md) 70509a3aaf3SDag-Erling Smørgrav { 70609a3aaf3SDag-Erling Smørgrav EVP_MD_CTX* ctx; 70709a3aaf3SDag-Erling Smørgrav ctx = EVP_MD_CTX_create(); 70809a3aaf3SDag-Erling Smørgrav if(!ctx) 70909a3aaf3SDag-Erling Smørgrav return 0; 71009a3aaf3SDag-Erling Smørgrav if(!EVP_DigestInit_ex(ctx, md, NULL) || 71109a3aaf3SDag-Erling Smørgrav !EVP_DigestUpdate(ctx, data, len) || 71209a3aaf3SDag-Erling Smørgrav !EVP_DigestFinal_ex(ctx, dest, NULL)) { 71309a3aaf3SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 71409a3aaf3SDag-Erling Smørgrav return 0; 71509a3aaf3SDag-Erling Smørgrav } 71609a3aaf3SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 71709a3aaf3SDag-Erling Smørgrav return 1; 71809a3aaf3SDag-Erling Smørgrav } 71909a3aaf3SDag-Erling Smørgrav #endif /* HAVE_SSL */ 720