1*fa353a8fSclaudio /* $OpenBSD: crypto.c,v 1.47 2024/11/21 13:26:49 claudio Exp $ */ 245ae9d61Sreyk 345ae9d61Sreyk /* 4fcebd35dSreyk * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 545ae9d61Sreyk * 645ae9d61Sreyk * Permission to use, copy, modify, and distribute this software for any 745ae9d61Sreyk * purpose with or without fee is hereby granted, provided that the above 845ae9d61Sreyk * copyright notice and this permission notice appear in all copies. 945ae9d61Sreyk * 1045ae9d61Sreyk * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1145ae9d61Sreyk * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1245ae9d61Sreyk * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1345ae9d61Sreyk * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1445ae9d61Sreyk * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1545ae9d61Sreyk * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1645ae9d61Sreyk * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1745ae9d61Sreyk */ 1845ae9d61Sreyk 19d8ea035bSderaadt #include <sys/types.h> 2045ae9d61Sreyk #include <sys/queue.h> 2145ae9d61Sreyk #include <sys/socket.h> 2245ae9d61Sreyk #include <sys/uio.h> 2345ae9d61Sreyk 2445ae9d61Sreyk #include <stdio.h> 2545ae9d61Sreyk #include <stdlib.h> 2645ae9d61Sreyk #include <unistd.h> 2745ae9d61Sreyk #include <string.h> 2845ae9d61Sreyk #include <errno.h> 2945ae9d61Sreyk #include <fcntl.h> 3045ae9d61Sreyk #include <event.h> 3145ae9d61Sreyk 3208c24fddStobhe #include <openssl/ecdsa.h> 3345ae9d61Sreyk #include <openssl/hmac.h> 3445ae9d61Sreyk #include <openssl/evp.h> 3545ae9d61Sreyk #include <openssl/sha.h> 3645ae9d61Sreyk #include <openssl/md5.h> 3745ae9d61Sreyk #include <openssl/x509.h> 38a4194998Sjsg #include <openssl/rsa.h> 3945ae9d61Sreyk 4045ae9d61Sreyk #include "iked.h" 4145ae9d61Sreyk #include "ikev2.h" 4245ae9d61Sreyk 435e4d3a37Sreyk /* RFC 7427, A.1 RSA */ 445e4d3a37Sreyk static const uint8_t sha256WithRSA[] = { 4548b975e3Smarkus 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 4648b975e3Smarkus 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00 4748b975e3Smarkus }; 485e4d3a37Sreyk static const uint8_t sha384WithRSA[] = { 4948b975e3Smarkus 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 5048b975e3Smarkus 0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00 5148b975e3Smarkus }; 525e4d3a37Sreyk static const uint8_t sha512WithRSA[] = { 5348b975e3Smarkus 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 5448b975e3Smarkus 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00 5548b975e3Smarkus }; 565e4d3a37Sreyk /* RFC 7427, A.3 ECDSA */ 575e4d3a37Sreyk static const uint8_t ecdsa_sha256[] = { 585e4d3a37Sreyk 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 595e4d3a37Sreyk 0x3d, 0x04, 0x03, 0x02 605e4d3a37Sreyk }; 615e4d3a37Sreyk static const uint8_t ecdsa_sha384[] = { 625e4d3a37Sreyk 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 635e4d3a37Sreyk 0x3d, 0x04, 0x03, 0x03 645e4d3a37Sreyk }; 655e4d3a37Sreyk static const uint8_t ecdsa_sha512[] = { 665e4d3a37Sreyk 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 675e4d3a37Sreyk 0x3d, 0x04, 0x03, 0x04 685e4d3a37Sreyk }; 69753a20acStobhe /* RFC 7427, A.4.3 RSASSA-PSS with SHA-256 */ 70753a20acStobhe static const uint8_t rsapss_sha256[] = { 71753a20acStobhe 0x30, 0x46, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 72753a20acStobhe 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x39, 0xa0, 73753a20acStobhe 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 74753a20acStobhe 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 75753a20acStobhe 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 76753a20acStobhe 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 77753a20acStobhe 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 78753a20acStobhe 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 79753a20acStobhe 0x02, 0x01, 0x20, 0xa3, 0x03, 0x02, 0x01, 0x01 80753a20acStobhe }; 81753a20acStobhe /* RSASSA-PSS SHA-384 */ 82753a20acStobhe static const uint8_t rsapss_sha384[] = { 83753a20acStobhe 0x30, 0x46, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 84753a20acStobhe 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 85753a20acStobhe 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 86753a20acStobhe 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 87753a20acStobhe 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 88753a20acStobhe 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 89753a20acStobhe 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 90753a20acStobhe 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 91753a20acStobhe 0x02, 0x01, 0x30, 0xa3, 0x03, 0x02, 0x01, 0x01 92753a20acStobhe }; 93753a20acStobhe /* RSASSA-PSS SHA-512 */ 94753a20acStobhe static const uint8_t rsapss_sha512[] = { 95753a20acStobhe 0x30, 0x46, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 96753a20acStobhe 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 97753a20acStobhe 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 98753a20acStobhe 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 99753a20acStobhe 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 100753a20acStobhe 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 101753a20acStobhe 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 102753a20acStobhe 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 103753a20acStobhe 0x02, 0x01, 0x40, 0xa3, 0x03, 0x02, 0x01, 0x01 104753a20acStobhe }; 105753a20acStobhe /* RSASSA-PSS SHA-256, no trailer */ 106753a20acStobhe static const uint8_t rsapss_sha256nt[] = { 107753a20acStobhe 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 108753a20acStobhe 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 109753a20acStobhe 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 110753a20acStobhe 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 111753a20acStobhe 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 112753a20acStobhe 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 113753a20acStobhe 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 114753a20acStobhe 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 115753a20acStobhe 0x02, 0x01, 0x20 116753a20acStobhe }; 117753a20acStobhe /* RSASSA-PSS SHA-384, no trailer */ 118753a20acStobhe static const uint8_t rsapss_sha384nt[] = { 119753a20acStobhe 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 120753a20acStobhe 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 121753a20acStobhe 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 122753a20acStobhe 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 123753a20acStobhe 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 124753a20acStobhe 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 125753a20acStobhe 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 126753a20acStobhe 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 127753a20acStobhe 0x02, 0x01, 0x30 128753a20acStobhe }; 129753a20acStobhe /* RSASSA-PSS SHA-512, no trailer */ 130753a20acStobhe static const uint8_t rsapss_sha512nt[] = { 131753a20acStobhe 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 132753a20acStobhe 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 133753a20acStobhe 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 134753a20acStobhe 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 135753a20acStobhe 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 136753a20acStobhe 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 137753a20acStobhe 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 138753a20acStobhe 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 139753a20acStobhe 0x02, 0x01, 0x40 140753a20acStobhe }; 141753a20acStobhe 142753a20acStobhe #define FLAG_RSA_PSS 0x00001 143466d2dbaStobhe int force_rsa_pss = 0; /* XXX move to API */ 14448b975e3Smarkus 1455e4d3a37Sreyk static const struct { 1465e4d3a37Sreyk int sc_keytype; 1475e4d3a37Sreyk const EVP_MD *(*sc_md)(void); 148d09d3a7dSreyk uint8_t sc_len; 149d09d3a7dSreyk const uint8_t *sc_oid; 150753a20acStobhe uint32_t sc_flags; 15148b975e3Smarkus } schemes[] = { 152753a20acStobhe { EVP_PKEY_RSA, EVP_sha256, sizeof(sha256WithRSA), sha256WithRSA, 0 }, 153753a20acStobhe { EVP_PKEY_RSA, EVP_sha384, sizeof(sha384WithRSA), sha384WithRSA, 0 }, 154753a20acStobhe { EVP_PKEY_RSA, EVP_sha512, sizeof(sha512WithRSA), sha512WithRSA, 0 }, 155753a20acStobhe { EVP_PKEY_EC, EVP_sha256, sizeof(ecdsa_sha256), ecdsa_sha256, 0 }, 156753a20acStobhe { EVP_PKEY_EC, EVP_sha384, sizeof(ecdsa_sha384), ecdsa_sha384, 0 }, 157753a20acStobhe { EVP_PKEY_EC, EVP_sha512, sizeof(ecdsa_sha512), ecdsa_sha512, 0 }, 158753a20acStobhe { EVP_PKEY_RSA, EVP_sha256, sizeof(rsapss_sha256), rsapss_sha256, 159753a20acStobhe FLAG_RSA_PSS }, 160753a20acStobhe { EVP_PKEY_RSA, EVP_sha384, sizeof(rsapss_sha384), rsapss_sha384, 161753a20acStobhe FLAG_RSA_PSS }, 162753a20acStobhe { EVP_PKEY_RSA, EVP_sha512, sizeof(rsapss_sha512), rsapss_sha512, 163753a20acStobhe FLAG_RSA_PSS }, 164753a20acStobhe { EVP_PKEY_RSA, EVP_sha256, sizeof(rsapss_sha256nt), rsapss_sha256nt, 165753a20acStobhe FLAG_RSA_PSS }, 166753a20acStobhe { EVP_PKEY_RSA, EVP_sha384, sizeof(rsapss_sha384nt), rsapss_sha384nt, 167753a20acStobhe FLAG_RSA_PSS }, 168753a20acStobhe { EVP_PKEY_RSA, EVP_sha512, sizeof(rsapss_sha512nt), rsapss_sha512nt, 169753a20acStobhe FLAG_RSA_PSS }, 17048b975e3Smarkus }; 17148b975e3Smarkus 172466d2dbaStobhe int _dsa_verify_init(struct iked_dsa *, const uint8_t *, size_t); 1735e4d3a37Sreyk int _dsa_verify_prepare(struct iked_dsa *, uint8_t **, size_t *, 1745e4d3a37Sreyk uint8_t **); 175cb2fef99Stobhe int _dsa_sign_encode(struct iked_dsa *, uint8_t *, size_t, size_t *); 1765e4d3a37Sreyk int _dsa_sign_ecdsa(struct iked_dsa *, uint8_t *, size_t); 17748b975e3Smarkus 17845ae9d61Sreyk struct iked_hash * 179d09d3a7dSreyk hash_new(uint8_t type, uint16_t id) 18045ae9d61Sreyk { 18145ae9d61Sreyk struct iked_hash *hash; 18245ae9d61Sreyk const EVP_MD *md = NULL; 18315863c3aStobhe int length = 0, fixedkey = 0, trunc = 0, isaead = 0; 18445ae9d61Sreyk 18545ae9d61Sreyk switch (type) { 18645ae9d61Sreyk case IKEV2_XFORMTYPE_PRF: 18745ae9d61Sreyk switch (id) { 18845ae9d61Sreyk case IKEV2_XFORMPRF_HMAC_MD5: 18945ae9d61Sreyk md = EVP_md5(); 19045ae9d61Sreyk length = MD5_DIGEST_LENGTH; 19145ae9d61Sreyk break; 19245ae9d61Sreyk case IKEV2_XFORMPRF_HMAC_SHA1: 19345ae9d61Sreyk md = EVP_sha1(); 19445ae9d61Sreyk length = SHA_DIGEST_LENGTH; 19545ae9d61Sreyk break; 19645ae9d61Sreyk case IKEV2_XFORMPRF_HMAC_SHA2_256: 19745ae9d61Sreyk md = EVP_sha256(); 19845ae9d61Sreyk length = SHA256_DIGEST_LENGTH; 19945ae9d61Sreyk break; 20045ae9d61Sreyk case IKEV2_XFORMPRF_HMAC_SHA2_384: 20145ae9d61Sreyk md = EVP_sha384(); 20245ae9d61Sreyk length = SHA384_DIGEST_LENGTH; 20345ae9d61Sreyk break; 20445ae9d61Sreyk case IKEV2_XFORMPRF_HMAC_SHA2_512: 20545ae9d61Sreyk md = EVP_sha512(); 20645ae9d61Sreyk length = SHA512_DIGEST_LENGTH; 20745ae9d61Sreyk break; 20845ae9d61Sreyk case IKEV2_XFORMPRF_AES128_XCBC: 20945ae9d61Sreyk fixedkey = 128 / 8; 21045ae9d61Sreyk length = fixedkey; 21145ae9d61Sreyk /* FALLTHROUGH */ 21245ae9d61Sreyk case IKEV2_XFORMPRF_HMAC_TIGER: 21345ae9d61Sreyk case IKEV2_XFORMPRF_AES128_CMAC: 21445ae9d61Sreyk default: 2157eced9f4Smikeb log_debug("%s: prf %s not supported", __func__, 21645ae9d61Sreyk print_map(id, ikev2_xformprf_map)); 21745ae9d61Sreyk break; 21845ae9d61Sreyk } 21945ae9d61Sreyk break; 22045ae9d61Sreyk case IKEV2_XFORMTYPE_INTEGR: 22145ae9d61Sreyk switch (id) { 22245ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_MD5_96: 22345ae9d61Sreyk md = EVP_md5(); 22445ae9d61Sreyk length = MD5_DIGEST_LENGTH; 22545ae9d61Sreyk trunc = 12; 22645ae9d61Sreyk break; 22745ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_SHA1_96: 22845ae9d61Sreyk md = EVP_sha1(); 22945ae9d61Sreyk length = SHA_DIGEST_LENGTH; 23045ae9d61Sreyk trunc = 12; 23145ae9d61Sreyk break; 23245ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_SHA2_256_128: 23345ae9d61Sreyk md = EVP_sha256(); 23445ae9d61Sreyk length = SHA256_DIGEST_LENGTH; 23545ae9d61Sreyk trunc = 16; 23645ae9d61Sreyk break; 23745ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_SHA2_384_192: 23845ae9d61Sreyk md = EVP_sha384(); 23945ae9d61Sreyk length = SHA384_DIGEST_LENGTH; 24045ae9d61Sreyk trunc = 24; 24145ae9d61Sreyk break; 24245ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_SHA2_512_256: 24345ae9d61Sreyk md = EVP_sha512(); 24445ae9d61Sreyk length = SHA512_DIGEST_LENGTH; 24545ae9d61Sreyk trunc = 32; 24645ae9d61Sreyk break; 24715863c3aStobhe case IKEV2_XFORMAUTH_AES_GCM_12: 24815863c3aStobhe length = 12; 24915863c3aStobhe isaead = 1; 25015863c3aStobhe break; 25115863c3aStobhe case IKEV2_XFORMAUTH_AES_GCM_16: 25215863c3aStobhe length = 16; 25315863c3aStobhe isaead = 1; 25415863c3aStobhe break; 25545ae9d61Sreyk case IKEV2_XFORMAUTH_NONE: 25645ae9d61Sreyk case IKEV2_XFORMAUTH_DES_MAC: 25745ae9d61Sreyk case IKEV2_XFORMAUTH_KPDK_MD5: 25845ae9d61Sreyk case IKEV2_XFORMAUTH_AES_XCBC_96: 25945ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_MD5_128: 26045ae9d61Sreyk case IKEV2_XFORMAUTH_HMAC_SHA1_160: 26145ae9d61Sreyk case IKEV2_XFORMAUTH_AES_CMAC_96: 26245ae9d61Sreyk case IKEV2_XFORMAUTH_AES_128_GMAC: 26345ae9d61Sreyk case IKEV2_XFORMAUTH_AES_192_GMAC: 26445ae9d61Sreyk case IKEV2_XFORMAUTH_AES_256_GMAC: 26545ae9d61Sreyk default: 2667eced9f4Smikeb log_debug("%s: auth %s not supported", __func__, 26745ae9d61Sreyk print_map(id, ikev2_xformauth_map)); 26845ae9d61Sreyk break; 26945ae9d61Sreyk } 27045ae9d61Sreyk break; 27145ae9d61Sreyk default: 2727eced9f4Smikeb log_debug("%s: hash type %s not supported", __func__, 27345ae9d61Sreyk print_map(id, ikev2_xformtype_map)); 27445ae9d61Sreyk break; 27545ae9d61Sreyk } 27615863c3aStobhe if (!isaead && md == NULL) 27745ae9d61Sreyk return (NULL); 27845ae9d61Sreyk 27945ae9d61Sreyk if ((hash = calloc(1, sizeof(*hash))) == NULL) { 28045ae9d61Sreyk log_debug("%s: alloc hash", __func__); 28145ae9d61Sreyk return (NULL); 28245ae9d61Sreyk } 28345ae9d61Sreyk 28445ae9d61Sreyk hash->hash_type = type; 28545ae9d61Sreyk hash->hash_id = id; 28645ae9d61Sreyk hash->hash_priv = md; 28745ae9d61Sreyk hash->hash_ctx = NULL; 28845ae9d61Sreyk hash->hash_trunc = trunc; 28945ae9d61Sreyk hash->hash_length = length; 29045ae9d61Sreyk hash->hash_fixedkey = fixedkey; 29115863c3aStobhe hash->hash_isaead = isaead; 29215863c3aStobhe 29315863c3aStobhe if (isaead) 29415863c3aStobhe return (hash); 29545ae9d61Sreyk 29608c24fddStobhe hash->hash_ctx = HMAC_CTX_new(); 29708c24fddStobhe if (hash->hash_ctx == NULL) { 29845ae9d61Sreyk log_debug("%s: alloc hash ctx", __func__); 29945ae9d61Sreyk hash_free(hash); 30045ae9d61Sreyk return (NULL); 30145ae9d61Sreyk } 30245ae9d61Sreyk 30345ae9d61Sreyk return (hash); 30445ae9d61Sreyk } 30545ae9d61Sreyk 30645ae9d61Sreyk struct ibuf * 30745ae9d61Sreyk hash_setkey(struct iked_hash *hash, void *key, size_t keylen) 30845ae9d61Sreyk { 309be2b38f5Sclaudio ibuf_free(hash->hash_key); 31045ae9d61Sreyk if ((hash->hash_key = ibuf_new(key, keylen)) == NULL) { 31145ae9d61Sreyk log_debug("%s: alloc hash key", __func__); 31245ae9d61Sreyk return (NULL); 31345ae9d61Sreyk } 31445ae9d61Sreyk return (hash->hash_key); 31545ae9d61Sreyk } 31645ae9d61Sreyk 31745ae9d61Sreyk void 31845ae9d61Sreyk hash_free(struct iked_hash *hash) 31945ae9d61Sreyk { 32045ae9d61Sreyk if (hash == NULL) 32145ae9d61Sreyk return; 32208c24fddStobhe HMAC_CTX_free(hash->hash_ctx); 323be2b38f5Sclaudio ibuf_free(hash->hash_key); 32445ae9d61Sreyk free(hash); 32545ae9d61Sreyk } 32645ae9d61Sreyk 32745ae9d61Sreyk void 32845ae9d61Sreyk hash_init(struct iked_hash *hash) 32945ae9d61Sreyk { 330a699afcaSclaudio HMAC_Init_ex(hash->hash_ctx, ibuf_data(hash->hash_key), 331eef6c82aSclaudio ibuf_size(hash->hash_key), hash->hash_priv, NULL); 33245ae9d61Sreyk } 33345ae9d61Sreyk 33445ae9d61Sreyk void 33545ae9d61Sreyk hash_update(struct iked_hash *hash, void *buf, size_t len) 33645ae9d61Sreyk { 33745ae9d61Sreyk HMAC_Update(hash->hash_ctx, buf, len); 33845ae9d61Sreyk } 33945ae9d61Sreyk 34045ae9d61Sreyk void 34145ae9d61Sreyk hash_final(struct iked_hash *hash, void *buf, size_t *len) 34245ae9d61Sreyk { 343d09d3a7dSreyk unsigned int length = 0; 34445ae9d61Sreyk 34545ae9d61Sreyk HMAC_Final(hash->hash_ctx, buf, &length); 34645ae9d61Sreyk *len = (size_t)length; 34745ae9d61Sreyk 34845ae9d61Sreyk /* Truncate the result if required by the alg */ 34945ae9d61Sreyk if (hash->hash_trunc && *len > hash->hash_trunc) 35045ae9d61Sreyk *len = hash->hash_trunc; 35145ae9d61Sreyk } 35245ae9d61Sreyk 35345ae9d61Sreyk size_t 35445ae9d61Sreyk hash_length(struct iked_hash *hash) 35545ae9d61Sreyk { 35645ae9d61Sreyk if (hash->hash_trunc) 35745ae9d61Sreyk return (hash->hash_trunc); 35845ae9d61Sreyk return (hash->hash_length); 35945ae9d61Sreyk } 36045ae9d61Sreyk 36145ae9d61Sreyk size_t 36245ae9d61Sreyk hash_keylength(struct iked_hash *hash) 36345ae9d61Sreyk { 36445ae9d61Sreyk return (hash->hash_length); 36545ae9d61Sreyk } 36645ae9d61Sreyk 36745ae9d61Sreyk struct iked_cipher * 368d09d3a7dSreyk cipher_new(uint8_t type, uint16_t id, uint16_t id_length) 36945ae9d61Sreyk { 37045ae9d61Sreyk struct iked_cipher *encr; 37145ae9d61Sreyk const EVP_CIPHER *cipher = NULL; 37245ae9d61Sreyk int length = 0, fixedkey = 0, ivlength = 0; 37315863c3aStobhe int saltlength = 0, authid = 0; 37445ae9d61Sreyk 37545ae9d61Sreyk switch (type) { 37645ae9d61Sreyk case IKEV2_XFORMTYPE_ENCR: 37745ae9d61Sreyk switch (id) { 37845ae9d61Sreyk case IKEV2_XFORMENCR_3DES: 37945ae9d61Sreyk cipher = EVP_des_ede3_cbc(); 38045ae9d61Sreyk length = EVP_CIPHER_block_size(cipher); 38145ae9d61Sreyk fixedkey = EVP_CIPHER_key_length(cipher); 38245ae9d61Sreyk ivlength = EVP_CIPHER_iv_length(cipher); 38345ae9d61Sreyk break; 38445ae9d61Sreyk case IKEV2_XFORMENCR_AES_CBC: 38545ae9d61Sreyk switch (id_length) { 38645ae9d61Sreyk case 128: 38745ae9d61Sreyk cipher = EVP_aes_128_cbc(); 38845ae9d61Sreyk break; 38945ae9d61Sreyk case 192: 39045ae9d61Sreyk cipher = EVP_aes_192_cbc(); 39145ae9d61Sreyk break; 39245ae9d61Sreyk case 256: 39345ae9d61Sreyk cipher = EVP_aes_256_cbc(); 39445ae9d61Sreyk break; 39545ae9d61Sreyk default: 39645ae9d61Sreyk log_debug("%s: invalid key length %d" 39745ae9d61Sreyk " for cipher %s", __func__, id_length, 39845ae9d61Sreyk print_map(id, ikev2_xformencr_map)); 39945ae9d61Sreyk break; 40045ae9d61Sreyk } 40145ae9d61Sreyk if (cipher == NULL) 40245ae9d61Sreyk break; 403953685aaSreyk length = EVP_CIPHER_block_size(cipher); 40445ae9d61Sreyk ivlength = EVP_CIPHER_iv_length(cipher); 40545ae9d61Sreyk fixedkey = EVP_CIPHER_key_length(cipher); 40645ae9d61Sreyk break; 40715863c3aStobhe case IKEV2_XFORMENCR_AES_GCM_16: 40815863c3aStobhe case IKEV2_XFORMENCR_AES_GCM_12: 40915863c3aStobhe switch (id_length) { 41015863c3aStobhe case 128: 41115863c3aStobhe cipher = EVP_aes_128_gcm(); 41215863c3aStobhe break; 41315863c3aStobhe case 256: 41415863c3aStobhe cipher = EVP_aes_256_gcm(); 41515863c3aStobhe break; 41615863c3aStobhe default: 41715863c3aStobhe log_debug("%s: invalid key length %d" 41815863c3aStobhe " for cipher %s", __func__, id_length, 41915863c3aStobhe print_map(id, ikev2_xformencr_map)); 42015863c3aStobhe break; 42115863c3aStobhe } 42215863c3aStobhe if (cipher == NULL) 42315863c3aStobhe break; 42415863c3aStobhe switch(id) { 42515863c3aStobhe case IKEV2_XFORMENCR_AES_GCM_16: 42615863c3aStobhe authid = IKEV2_XFORMAUTH_AES_GCM_16; 42715863c3aStobhe break; 42815863c3aStobhe case IKEV2_XFORMENCR_AES_GCM_12: 42915863c3aStobhe authid = IKEV2_XFORMAUTH_AES_GCM_12; 43015863c3aStobhe break; 43115863c3aStobhe } 43215863c3aStobhe length = EVP_CIPHER_block_size(cipher); 43315863c3aStobhe ivlength = 8; 43415863c3aStobhe saltlength = 4; 43515863c3aStobhe fixedkey = EVP_CIPHER_key_length(cipher) + saltlength; 43615863c3aStobhe break; 43745ae9d61Sreyk case IKEV2_XFORMENCR_DES_IV64: 43845ae9d61Sreyk case IKEV2_XFORMENCR_DES: 43945ae9d61Sreyk case IKEV2_XFORMENCR_RC5: 44045ae9d61Sreyk case IKEV2_XFORMENCR_IDEA: 44145ae9d61Sreyk case IKEV2_XFORMENCR_CAST: 44245ae9d61Sreyk case IKEV2_XFORMENCR_BLOWFISH: 44345ae9d61Sreyk case IKEV2_XFORMENCR_3IDEA: 44445ae9d61Sreyk case IKEV2_XFORMENCR_DES_IV32: 44545ae9d61Sreyk case IKEV2_XFORMENCR_NULL: 44645ae9d61Sreyk case IKEV2_XFORMENCR_AES_CTR: 44745ae9d61Sreyk /* FALLTHROUGH */ 44845ae9d61Sreyk default: 4497eced9f4Smikeb log_debug("%s: cipher %s not supported", __func__, 45045ae9d61Sreyk print_map(id, ikev2_xformencr_map)); 45145ae9d61Sreyk cipher = NULL; 45245ae9d61Sreyk break; 45345ae9d61Sreyk } 45445ae9d61Sreyk break; 45545ae9d61Sreyk default: 4567eced9f4Smikeb log_debug("%s: cipher type %s not supported", __func__, 45745ae9d61Sreyk print_map(id, ikev2_xformtype_map)); 45845ae9d61Sreyk break; 45945ae9d61Sreyk } 46045ae9d61Sreyk if (cipher == NULL) 46145ae9d61Sreyk return (NULL); 46245ae9d61Sreyk 46345ae9d61Sreyk if ((encr = calloc(1, sizeof(*encr))) == NULL) { 46445ae9d61Sreyk log_debug("%s: alloc cipher", __func__); 46545ae9d61Sreyk return (NULL); 46645ae9d61Sreyk } 46745ae9d61Sreyk 46845ae9d61Sreyk encr->encr_id = id; 46945ae9d61Sreyk encr->encr_priv = cipher; 47045ae9d61Sreyk encr->encr_ctx = NULL; 47145ae9d61Sreyk encr->encr_length = length; 47245ae9d61Sreyk encr->encr_fixedkey = fixedkey; 47345ae9d61Sreyk encr->encr_ivlength = ivlength ? ivlength : length; 47415863c3aStobhe encr->encr_saltlength = saltlength; 47515863c3aStobhe encr->encr_authid = authid; 47645ae9d61Sreyk 47708c24fddStobhe encr->encr_ctx = EVP_CIPHER_CTX_new(); 47808c24fddStobhe if (encr->encr_ctx == NULL) { 47945ae9d61Sreyk log_debug("%s: alloc cipher ctx", __func__); 48045ae9d61Sreyk cipher_free(encr); 48145ae9d61Sreyk return (NULL); 48245ae9d61Sreyk } 48345ae9d61Sreyk 48445ae9d61Sreyk return (encr); 48545ae9d61Sreyk } 48645ae9d61Sreyk 48745ae9d61Sreyk struct ibuf * 488a9a2a639Stobhe cipher_setkey(struct iked_cipher *encr, const void *key, size_t keylen) 48945ae9d61Sreyk { 490be2b38f5Sclaudio ibuf_free(encr->encr_key); 49145ae9d61Sreyk if ((encr->encr_key = ibuf_new(key, keylen)) == NULL) { 49245ae9d61Sreyk log_debug("%s: alloc cipher key", __func__); 49345ae9d61Sreyk return (NULL); 49445ae9d61Sreyk } 49545ae9d61Sreyk return (encr->encr_key); 49645ae9d61Sreyk } 49745ae9d61Sreyk 49845ae9d61Sreyk struct ibuf * 499a9a2a639Stobhe cipher_setiv(struct iked_cipher *encr, const void *iv, size_t len) 50045ae9d61Sreyk { 501be2b38f5Sclaudio ibuf_free(encr->encr_iv); 5025e4d3a37Sreyk encr->encr_iv = NULL; 50345ae9d61Sreyk if (iv != NULL) { 50445ae9d61Sreyk if (len < encr->encr_ivlength) { 505328746baSreyk log_debug("%s: invalid IV length %zu", __func__, len); 50645ae9d61Sreyk return (NULL); 50745ae9d61Sreyk } 50845ae9d61Sreyk encr->encr_iv = ibuf_new(iv, encr->encr_ivlength); 50945ae9d61Sreyk } else { 510c4530a33Stobhe switch (encr->encr_id) { 511c4530a33Stobhe case IKEV2_XFORMENCR_AES_GCM_16: 512c4530a33Stobhe case IKEV2_XFORMENCR_AES_GCM_12: 513c4530a33Stobhe if (encr->encr_ivlength != sizeof(encr->encr_civ)) { 514c4530a33Stobhe log_info("%s: ivlen does not match %zu != %zu", 515c4530a33Stobhe __func__, encr->encr_ivlength, 516c4530a33Stobhe sizeof(encr->encr_civ)); 517c4530a33Stobhe return (NULL); 518c4530a33Stobhe } 519c4530a33Stobhe encr->encr_iv = ibuf_new(&encr->encr_civ, sizeof(encr->encr_civ)); 520c4530a33Stobhe encr->encr_civ++; 521c4530a33Stobhe break; 522c4530a33Stobhe default: 52345ae9d61Sreyk /* Get new random IV */ 52445ae9d61Sreyk encr->encr_iv = ibuf_random(encr->encr_ivlength); 52545ae9d61Sreyk } 526c4530a33Stobhe } 52745ae9d61Sreyk if (encr->encr_iv == NULL) { 52845ae9d61Sreyk log_debug("%s: failed to set IV", __func__); 52945ae9d61Sreyk return (NULL); 53045ae9d61Sreyk } 53145ae9d61Sreyk return (encr->encr_iv); 53245ae9d61Sreyk } 53345ae9d61Sreyk 53415863c3aStobhe int 53515863c3aStobhe cipher_settag(struct iked_cipher *encr, uint8_t *data, size_t len) 53615863c3aStobhe { 53715863c3aStobhe return (EVP_CIPHER_CTX_ctrl(encr->encr_ctx, 53815863c3aStobhe EVP_CTRL_GCM_SET_TAG, len, data) != 1); 53915863c3aStobhe } 54015863c3aStobhe 54115863c3aStobhe int 54215863c3aStobhe cipher_gettag(struct iked_cipher *encr, uint8_t *data, size_t len) 54315863c3aStobhe { 54415863c3aStobhe return (EVP_CIPHER_CTX_ctrl(encr->encr_ctx, 54515863c3aStobhe EVP_CTRL_GCM_GET_TAG, len, data) != 1); 54615863c3aStobhe } 54715863c3aStobhe 54845ae9d61Sreyk void 54945ae9d61Sreyk cipher_free(struct iked_cipher *encr) 55045ae9d61Sreyk { 55145ae9d61Sreyk if (encr == NULL) 55245ae9d61Sreyk return; 553422a8d39Stb EVP_CIPHER_CTX_free(encr->encr_ctx); 554be2b38f5Sclaudio ibuf_free(encr->encr_iv); 555be2b38f5Sclaudio ibuf_free(encr->encr_key); 55645ae9d61Sreyk free(encr); 55745ae9d61Sreyk } 55845ae9d61Sreyk 55981b8fecaStobhe int 56045ae9d61Sreyk cipher_init(struct iked_cipher *encr, int enc) 56145ae9d61Sreyk { 56215863c3aStobhe struct ibuf *nonce = NULL; 56315863c3aStobhe int ret = -1; 56415863c3aStobhe 56581b8fecaStobhe if (EVP_CipherInit_ex(encr->encr_ctx, encr->encr_priv, NULL, 56615863c3aStobhe NULL, NULL, enc) != 1) 56715863c3aStobhe return (-1); 56815863c3aStobhe if (encr->encr_saltlength > 0) { 56915863c3aStobhe /* For AEADs the nonce is salt + IV (see RFC5282) */ 5705001b11bSclaudio nonce = ibuf_new(ibuf_seek(encr->encr_key, 57115863c3aStobhe ibuf_size(encr->encr_key) - encr->encr_saltlength, 5725001b11bSclaudio encr->encr_saltlength), encr->encr_saltlength); 57315863c3aStobhe if (nonce == NULL) 57415863c3aStobhe return (-1); 575*fa353a8fSclaudio if (ibuf_add_ibuf(nonce, encr->encr_iv) != 0) 57615863c3aStobhe goto done; 57715863c3aStobhe if (EVP_CipherInit_ex(encr->encr_ctx, NULL, NULL, 57815863c3aStobhe ibuf_data(encr->encr_key), ibuf_data(nonce), enc) != 1) 57915863c3aStobhe goto done; 58015863c3aStobhe } else 58115863c3aStobhe if (EVP_CipherInit_ex(encr->encr_ctx, NULL, NULL, 58281b8fecaStobhe ibuf_data(encr->encr_key), ibuf_data(encr->encr_iv), enc) != 1) 58381b8fecaStobhe return (-1); 5843189733aSmikeb EVP_CIPHER_CTX_set_padding(encr->encr_ctx, 0); 58515863c3aStobhe ret = 0; 58615863c3aStobhe done: 58715863c3aStobhe ibuf_free(nonce); 58815863c3aStobhe return (ret); 58945ae9d61Sreyk } 59045ae9d61Sreyk 59181b8fecaStobhe int 59245ae9d61Sreyk cipher_init_encrypt(struct iked_cipher *encr) 59345ae9d61Sreyk { 59481b8fecaStobhe return (cipher_init(encr, 1)); 59545ae9d61Sreyk } 59645ae9d61Sreyk 59781b8fecaStobhe int 59845ae9d61Sreyk cipher_init_decrypt(struct iked_cipher *encr) 59945ae9d61Sreyk { 60081b8fecaStobhe return (cipher_init(encr, 0)); 60145ae9d61Sreyk } 60245ae9d61Sreyk 60315863c3aStobhe void 604a9a2a639Stobhe cipher_aad(struct iked_cipher *encr, const void *in, size_t inlen, 60515863c3aStobhe size_t *outlen) 60615863c3aStobhe { 60715863c3aStobhe int olen = 0; 60815863c3aStobhe 60915863c3aStobhe if (EVP_CipherUpdate(encr->encr_ctx, NULL, &olen, in, inlen) != 1) { 61015863c3aStobhe ca_sslerror(__func__); 61115863c3aStobhe *outlen = 0; 61215863c3aStobhe return; 61315863c3aStobhe } 61415863c3aStobhe *outlen = (size_t)olen; 61515863c3aStobhe } 61615863c3aStobhe 61781b8fecaStobhe int 618a9a2a639Stobhe cipher_update(struct iked_cipher *encr, const void *in, size_t inlen, 61945ae9d61Sreyk void *out, size_t *outlen) 62045ae9d61Sreyk { 62145ae9d61Sreyk int olen; 62245ae9d61Sreyk 62345ae9d61Sreyk olen = 0; 62481b8fecaStobhe if (EVP_CipherUpdate(encr->encr_ctx, out, &olen, in, inlen) != 1) { 62586cf9d9cSmarkus ca_sslerror(__func__); 6263189733aSmikeb *outlen = 0; 62781b8fecaStobhe return (-1); 6283189733aSmikeb } 62945ae9d61Sreyk *outlen = (size_t)olen; 63081b8fecaStobhe return (0); 63145ae9d61Sreyk } 63245ae9d61Sreyk 63381b8fecaStobhe int 63481b8fecaStobhe cipher_final(struct iked_cipher *encr) 63545ae9d61Sreyk { 63645ae9d61Sreyk int olen; 63745ae9d61Sreyk 63881b8fecaStobhe /* 63981b8fecaStobhe * We always have EVP_CIPH_NO_PADDING set. This means arg 64081b8fecaStobhe * out is not used and olen should always be 0. 64181b8fecaStobhe */ 64281b8fecaStobhe if (EVP_CipherFinal_ex(encr->encr_ctx, NULL, &olen) != 1) { 64386cf9d9cSmarkus ca_sslerror(__func__); 64481b8fecaStobhe return (-1); 64545ae9d61Sreyk } 64681b8fecaStobhe return (0); 64745ae9d61Sreyk } 64845ae9d61Sreyk 64945ae9d61Sreyk size_t 65045ae9d61Sreyk cipher_length(struct iked_cipher *encr) 65145ae9d61Sreyk { 65245ae9d61Sreyk return (encr->encr_length); 65345ae9d61Sreyk } 65445ae9d61Sreyk 65545ae9d61Sreyk size_t 65645ae9d61Sreyk cipher_keylength(struct iked_cipher *encr) 65745ae9d61Sreyk { 65845ae9d61Sreyk if (encr->encr_fixedkey) 65945ae9d61Sreyk return (encr->encr_fixedkey); 66045ae9d61Sreyk 66145ae9d61Sreyk /* Might return zero */ 66245ae9d61Sreyk return (ibuf_length(encr->encr_key)); 66345ae9d61Sreyk } 66445ae9d61Sreyk 66545ae9d61Sreyk size_t 66645ae9d61Sreyk cipher_ivlength(struct iked_cipher *encr) 66745ae9d61Sreyk { 66845ae9d61Sreyk return (encr->encr_ivlength); 66945ae9d61Sreyk } 67045ae9d61Sreyk 67145ae9d61Sreyk size_t 67245ae9d61Sreyk cipher_outlength(struct iked_cipher *encr, size_t inlen) 67345ae9d61Sreyk { 674d5cae38cSmikeb return (roundup(inlen, encr->encr_length)); 67545ae9d61Sreyk } 67645ae9d61Sreyk 67745ae9d61Sreyk struct iked_dsa * 6786368155eStobhe dsa_new(uint8_t id, struct iked_hash *prf, int sign) 67945ae9d61Sreyk { 68045ae9d61Sreyk struct iked_dsa *dsap = NULL, dsa; 68145ae9d61Sreyk 68245ae9d61Sreyk bzero(&dsa, sizeof(dsa)); 68345ae9d61Sreyk 68445ae9d61Sreyk switch (id) { 68548b975e3Smarkus case IKEV2_AUTH_SIG: 68648b975e3Smarkus if (sign) 68748b975e3Smarkus dsa.dsa_priv = EVP_sha256(); /* XXX should be passed */ 68848b975e3Smarkus else 68948b975e3Smarkus dsa.dsa_priv = NULL; /* set later by dsa_init() */ 69048b975e3Smarkus break; 69145ae9d61Sreyk case IKEV2_AUTH_RSA_SIG: 692ab77649aSmikeb /* RFC5996 says we SHOULD use SHA1 here */ 693ab77649aSmikeb dsa.dsa_priv = EVP_sha1(); 69445ae9d61Sreyk break; 69545ae9d61Sreyk case IKEV2_AUTH_SHARED_KEY_MIC: 69645ae9d61Sreyk if (prf == NULL || prf->hash_priv == NULL) 69745ae9d61Sreyk fatalx("dsa_new: invalid PRF"); 69845ae9d61Sreyk dsa.dsa_priv = prf->hash_priv; 69945ae9d61Sreyk dsa.dsa_hmac = 1; 70045ae9d61Sreyk break; 70145ae9d61Sreyk case IKEV2_AUTH_DSS_SIG: 70208c24fddStobhe dsa.dsa_priv = EVP_sha1(); 70345ae9d61Sreyk break; 70445ae9d61Sreyk case IKEV2_AUTH_ECDSA_256: 70545ae9d61Sreyk dsa.dsa_priv = EVP_sha256(); 70645ae9d61Sreyk break; 70745ae9d61Sreyk case IKEV2_AUTH_ECDSA_384: 70845ae9d61Sreyk dsa.dsa_priv = EVP_sha384(); 70945ae9d61Sreyk break; 710ada108cbSnaddy case IKEV2_AUTH_ECDSA_521: 71145ae9d61Sreyk dsa.dsa_priv = EVP_sha512(); 71245ae9d61Sreyk break; 71345ae9d61Sreyk default: 7147eced9f4Smikeb log_debug("%s: auth method %s not supported", __func__, 71545ae9d61Sreyk print_map(id, ikev2_auth_map)); 71645ae9d61Sreyk break; 71745ae9d61Sreyk } 71845ae9d61Sreyk 71945ae9d61Sreyk if ((dsap = calloc(1, sizeof(*dsap))) == NULL) { 72045ae9d61Sreyk log_debug("%s: alloc dsa ctx", __func__); 72145ae9d61Sreyk 72245ae9d61Sreyk return (NULL); 72345ae9d61Sreyk } 72445ae9d61Sreyk memcpy(dsap, &dsa, sizeof(*dsap)); 72545ae9d61Sreyk 72645ae9d61Sreyk dsap->dsa_method = id; 72745ae9d61Sreyk dsap->dsa_sign = sign; 72845ae9d61Sreyk 72945ae9d61Sreyk if (dsap->dsa_hmac) { 73008c24fddStobhe if ((dsap->dsa_ctx = HMAC_CTX_new()) == NULL) { 73145ae9d61Sreyk log_debug("%s: alloc hash ctx", __func__); 73245ae9d61Sreyk dsa_free(dsap); 73345ae9d61Sreyk return (NULL); 73445ae9d61Sreyk } 73545ae9d61Sreyk } else { 73645ae9d61Sreyk if ((dsap->dsa_ctx = EVP_MD_CTX_create()) == NULL) { 73745ae9d61Sreyk log_debug("%s: alloc digest ctx", __func__); 73845ae9d61Sreyk dsa_free(dsap); 73945ae9d61Sreyk return (NULL); 74045ae9d61Sreyk } 74145ae9d61Sreyk } 74245ae9d61Sreyk 74345ae9d61Sreyk return (dsap); 74445ae9d61Sreyk } 74545ae9d61Sreyk 74645ae9d61Sreyk struct iked_dsa * 7476368155eStobhe dsa_sign_new(uint8_t id, struct iked_hash *prf) 74845ae9d61Sreyk { 74945ae9d61Sreyk return (dsa_new(id, prf, 1)); 75045ae9d61Sreyk } 75145ae9d61Sreyk 75245ae9d61Sreyk struct iked_dsa * 7536368155eStobhe dsa_verify_new(uint8_t id, struct iked_hash *prf) 75445ae9d61Sreyk { 75545ae9d61Sreyk return (dsa_new(id, prf, 0)); 75645ae9d61Sreyk } 75745ae9d61Sreyk 75845ae9d61Sreyk void 75945ae9d61Sreyk dsa_free(struct iked_dsa *dsa) 76045ae9d61Sreyk { 76145ae9d61Sreyk if (dsa == NULL) 76245ae9d61Sreyk return; 76345ae9d61Sreyk if (dsa->dsa_hmac) { 76408c24fddStobhe HMAC_CTX_free((HMAC_CTX *)dsa->dsa_ctx); 76545ae9d61Sreyk } else { 7667199b42cStobhe EVP_MD_CTX_free((EVP_MD_CTX *)dsa->dsa_ctx); 76745ae9d61Sreyk EVP_PKEY_free(dsa->dsa_key); 76845ae9d61Sreyk } 76945ae9d61Sreyk 770be2b38f5Sclaudio ibuf_free(dsa->dsa_keydata); 77164449014Sreyk free(dsa); 77245ae9d61Sreyk } 77345ae9d61Sreyk 77445ae9d61Sreyk struct ibuf * 775d09d3a7dSreyk dsa_setkey(struct iked_dsa *dsa, void *key, size_t keylen, uint8_t type) 77645ae9d61Sreyk { 77745ae9d61Sreyk BIO *rawcert = NULL; 77845ae9d61Sreyk X509 *cert = NULL; 77945ae9d61Sreyk RSA *rsa = NULL; 7805e4d3a37Sreyk EC_KEY *ec = NULL; 78145ae9d61Sreyk EVP_PKEY *pkey = NULL; 78245ae9d61Sreyk 783be2b38f5Sclaudio ibuf_free(dsa->dsa_keydata); 78445ae9d61Sreyk if ((dsa->dsa_keydata = ibuf_new(key, keylen)) == NULL) { 78545ae9d61Sreyk log_debug("%s: alloc signature key", __func__); 78645ae9d61Sreyk return (NULL); 78745ae9d61Sreyk } 78845ae9d61Sreyk 78945ae9d61Sreyk if ((rawcert = BIO_new_mem_buf(key, keylen)) == NULL) 79045ae9d61Sreyk goto err; 79145ae9d61Sreyk 79245ae9d61Sreyk switch (type) { 79345ae9d61Sreyk case IKEV2_CERT_X509_CERT: 79445ae9d61Sreyk if ((cert = d2i_X509_bio(rawcert, NULL)) == NULL) 79545ae9d61Sreyk goto sslerr; 79645ae9d61Sreyk if ((pkey = X509_get_pubkey(cert)) == NULL) 79745ae9d61Sreyk goto sslerr; 79845ae9d61Sreyk dsa->dsa_key = pkey; 79945ae9d61Sreyk break; 80045ae9d61Sreyk case IKEV2_CERT_RSA_KEY: 80145ae9d61Sreyk if (dsa->dsa_sign) { 80245ae9d61Sreyk if ((rsa = d2i_RSAPrivateKey_bio(rawcert, 80345ae9d61Sreyk NULL)) == NULL) 80445ae9d61Sreyk goto sslerr; 80545ae9d61Sreyk } else { 80645ae9d61Sreyk if ((rsa = d2i_RSAPublicKey_bio(rawcert, 80745ae9d61Sreyk NULL)) == NULL) 80845ae9d61Sreyk goto sslerr; 80945ae9d61Sreyk } 81045ae9d61Sreyk 81145ae9d61Sreyk if ((pkey = EVP_PKEY_new()) == NULL) 81245ae9d61Sreyk goto sslerr; 81345ae9d61Sreyk if (!EVP_PKEY_set1_RSA(pkey, rsa)) 81445ae9d61Sreyk goto sslerr; 81545ae9d61Sreyk 81664660e80Smarkus RSA_free(rsa); /* pkey now has the reference */ 81745ae9d61Sreyk dsa->dsa_key = pkey; 81845ae9d61Sreyk break; 8195e4d3a37Sreyk case IKEV2_CERT_ECDSA: 8205e4d3a37Sreyk if (dsa->dsa_sign) { 8215e4d3a37Sreyk if ((ec = d2i_ECPrivateKey_bio(rawcert, NULL)) == NULL) 8225e4d3a37Sreyk goto sslerr; 8235e4d3a37Sreyk } else { 8245e4d3a37Sreyk if ((ec = d2i_EC_PUBKEY_bio(rawcert, NULL)) == NULL) 8255e4d3a37Sreyk goto sslerr; 8265e4d3a37Sreyk } 8275e4d3a37Sreyk 8285e4d3a37Sreyk if ((pkey = EVP_PKEY_new()) == NULL) 8295e4d3a37Sreyk goto sslerr; 8305e4d3a37Sreyk if (!EVP_PKEY_set1_EC_KEY(pkey, ec)) 8315e4d3a37Sreyk goto sslerr; 8325e4d3a37Sreyk 8335e4d3a37Sreyk EC_KEY_free(ec); /* pkey now has the reference */ 8345e4d3a37Sreyk dsa->dsa_key = pkey; 8355e4d3a37Sreyk break; 83645ae9d61Sreyk default: 83745ae9d61Sreyk if (dsa->dsa_hmac) 83845ae9d61Sreyk break; 83945ae9d61Sreyk log_debug("%s: unsupported key type", __func__); 84045ae9d61Sreyk goto err; 84145ae9d61Sreyk } 84245ae9d61Sreyk 8437e0422b2Stobhe X509_free(cert); 8447e0422b2Stobhe BIO_free(rawcert); /* temporary for parsing */ 8457e0422b2Stobhe 84645ae9d61Sreyk return (dsa->dsa_keydata); 84745ae9d61Sreyk 84845ae9d61Sreyk sslerr: 84986cf9d9cSmarkus ca_sslerror(__func__); 85045ae9d61Sreyk err: 85145ae9d61Sreyk log_debug("%s: error", __func__); 85245ae9d61Sreyk 85345ae9d61Sreyk RSA_free(rsa); 8545e4d3a37Sreyk EC_KEY_free(ec); 85545ae9d61Sreyk EVP_PKEY_free(pkey); 85645ae9d61Sreyk X509_free(cert); 85745ae9d61Sreyk BIO_free(rawcert); 858be2b38f5Sclaudio ibuf_free(dsa->dsa_keydata); 8595e4d3a37Sreyk dsa->dsa_keydata = NULL; 86045ae9d61Sreyk return (NULL); 86145ae9d61Sreyk } 86245ae9d61Sreyk 86345ae9d61Sreyk int 864466d2dbaStobhe _dsa_verify_init(struct iked_dsa *dsa, const uint8_t *sig, size_t len) 86548b975e3Smarkus { 866d09d3a7dSreyk uint8_t oidlen; 86748b975e3Smarkus size_t i; 8685e4d3a37Sreyk int keytype; 86948b975e3Smarkus 87048b975e3Smarkus if (dsa->dsa_priv != NULL) 87148b975e3Smarkus return (0); 87248b975e3Smarkus /* 87348b975e3Smarkus * For IKEV2_AUTH_SIG the oid of the authentication signature 87448b975e3Smarkus * is encoded in the first bytes of the auth message. 87548b975e3Smarkus */ 87648b975e3Smarkus if (dsa->dsa_method != IKEV2_AUTH_SIG) { 87748b975e3Smarkus log_debug("%s: dsa_priv not set for %s", __func__, 87848b975e3Smarkus print_map(dsa->dsa_method, ikev2_auth_map)); 87948b975e3Smarkus return (-1); 88048b975e3Smarkus } 8815e4d3a37Sreyk if (dsa->dsa_key == NULL) { 8825e4d3a37Sreyk log_debug("%s: dsa_key not set for %s", __func__, 8835e4d3a37Sreyk print_map(dsa->dsa_method, ikev2_auth_map)); 8845e4d3a37Sreyk return (-1); 8855e4d3a37Sreyk } 88608c24fddStobhe keytype = EVP_PKEY_type(EVP_PKEY_id(((EVP_PKEY *)dsa->dsa_key))); 88748b975e3Smarkus if (sig == NULL) { 88848b975e3Smarkus log_debug("%s: signature missing", __func__); 88948b975e3Smarkus return (-1); 89048b975e3Smarkus } 8915e4d3a37Sreyk if (len < sizeof(oidlen)) { 89248b975e3Smarkus log_debug("%s: signature (%zu) too small for oid length", 89348b975e3Smarkus __func__, len); 89448b975e3Smarkus return (-1); 89548b975e3Smarkus } 89648b975e3Smarkus memcpy(&oidlen, sig, sizeof(oidlen)); 8975e4d3a37Sreyk if (len < (size_t)oidlen + sizeof(oidlen)) { 89848b975e3Smarkus log_debug("%s: signature (%zu) too small for oid (%u)", 89948b975e3Smarkus __func__, len, oidlen); 90048b975e3Smarkus return (-1); 90148b975e3Smarkus } 90248b975e3Smarkus for (i = 0; i < nitems(schemes); i++) { 9035e4d3a37Sreyk if (keytype == schemes[i].sc_keytype && 9045e4d3a37Sreyk oidlen == schemes[i].sc_len && 90572178c58Sreyk memcmp(sig + 1, schemes[i].sc_oid, 90672178c58Sreyk schemes[i].sc_len) == 0) { 90748b975e3Smarkus dsa->dsa_priv = (*schemes[i].sc_md)(); 908466d2dbaStobhe dsa->dsa_flags = schemes[i].sc_flags; 90948b975e3Smarkus log_debug("%s: signature scheme %zd selected", 91048b975e3Smarkus __func__, i); 91148b975e3Smarkus return (0); 91248b975e3Smarkus } 91348b975e3Smarkus } 91448b975e3Smarkus log_debug("%s: unsupported signature (%d)", __func__, oidlen); 91548b975e3Smarkus return (-1); 91648b975e3Smarkus } 91748b975e3Smarkus 91848b975e3Smarkus int 91948b975e3Smarkus dsa_init(struct iked_dsa *dsa, const void *buf, size_t len) 92045ae9d61Sreyk { 921466d2dbaStobhe int ret; 922753a20acStobhe EVP_PKEY_CTX *pctx = NULL; 92345ae9d61Sreyk 92445ae9d61Sreyk if (dsa->dsa_hmac) { 92580ff32ddSmikeb if (!HMAC_Init_ex(dsa->dsa_ctx, ibuf_data(dsa->dsa_keydata), 926eef6c82aSclaudio ibuf_size(dsa->dsa_keydata), dsa->dsa_priv, NULL)) 92780ff32ddSmikeb return (-1); 92845ae9d61Sreyk return (0); 92945ae9d61Sreyk } 93045ae9d61Sreyk 931466d2dbaStobhe if (dsa->dsa_sign) { 932466d2dbaStobhe if (force_rsa_pss && 933466d2dbaStobhe EVP_PKEY_base_id(dsa->dsa_key) == EVP_PKEY_RSA) 934466d2dbaStobhe dsa->dsa_flags = FLAG_RSA_PSS; 935466d2dbaStobhe ret = EVP_DigestSignInit(dsa->dsa_ctx, &pctx, dsa->dsa_priv, 936cb2fef99Stobhe NULL, dsa->dsa_key); 937466d2dbaStobhe } else { 938466d2dbaStobhe /* sets dsa_priv, dsa_flags */ 939466d2dbaStobhe if ((ret = _dsa_verify_init(dsa, buf, len)) != 0) 94048b975e3Smarkus return (ret); 941753a20acStobhe ret = EVP_DigestVerifyInit(dsa->dsa_ctx, &pctx, dsa->dsa_priv, 942cb2fef99Stobhe NULL, dsa->dsa_key); 943466d2dbaStobhe } 944466d2dbaStobhe if (ret == 1 && dsa->dsa_flags == FLAG_RSA_PSS) { 945753a20acStobhe if (EVP_PKEY_CTX_set_rsa_padding(pctx, 946753a20acStobhe RSA_PKCS1_PSS_PADDING) <= 0 || 947753a20acStobhe EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) 948753a20acStobhe return (-1); 949753a20acStobhe } 9506802616fStobhe if (_dsa_sign_encode(dsa, NULL, 0, NULL) < 0) 9516802616fStobhe return (-1); 95245ae9d61Sreyk 953cb2fef99Stobhe return (ret == 1 ? 0 : -1); 95445ae9d61Sreyk } 95545ae9d61Sreyk 95645ae9d61Sreyk int 95745ae9d61Sreyk dsa_update(struct iked_dsa *dsa, const void *buf, size_t len) 95845ae9d61Sreyk { 959cb2fef99Stobhe int ret; 96045ae9d61Sreyk 96145ae9d61Sreyk if (dsa->dsa_hmac) 96280ff32ddSmikeb ret = HMAC_Update(dsa->dsa_ctx, buf, len); 96345ae9d61Sreyk else if (dsa->dsa_sign) 964cb2fef99Stobhe ret = EVP_DigestSignUpdate(dsa->dsa_ctx, buf, len); 96545ae9d61Sreyk else 966cb2fef99Stobhe ret = EVP_DigestVerifyUpdate(dsa->dsa_ctx, buf, len); 96745ae9d61Sreyk 968cb2fef99Stobhe return (ret == 1 ? 0 : -1); 96945ae9d61Sreyk } 97045ae9d61Sreyk 97148b975e3Smarkus /* Prefix signature hash with encoded type */ 97248b975e3Smarkus int 973cb2fef99Stobhe _dsa_sign_encode(struct iked_dsa *dsa, uint8_t *ptr, size_t len, size_t *offp) 97448b975e3Smarkus { 9755e4d3a37Sreyk int keytype; 976cb2fef99Stobhe size_t i, need; 9775e4d3a37Sreyk 97848b975e3Smarkus if (offp) 97948b975e3Smarkus *offp = 0; 98048b975e3Smarkus if (dsa->dsa_method != IKEV2_AUTH_SIG) 98148b975e3Smarkus return (0); 9825e4d3a37Sreyk if (dsa->dsa_key == NULL) 9835e4d3a37Sreyk return (-1); 98408c24fddStobhe keytype = EVP_PKEY_type(EVP_PKEY_id(((EVP_PKEY *)dsa->dsa_key))); 9855e4d3a37Sreyk for (i = 0; i < nitems(schemes); i++) { 9865e4d3a37Sreyk /* XXX should avoid calling sc_md() each time... */ 9875e4d3a37Sreyk if (keytype == schemes[i].sc_keytype && 988466d2dbaStobhe dsa->dsa_flags == schemes[i].sc_flags && 9895e4d3a37Sreyk (dsa->dsa_priv == (*schemes[i].sc_md)())) 9905e4d3a37Sreyk break; 9915e4d3a37Sreyk } 9925e4d3a37Sreyk if (i >= nitems(schemes)) 99348b975e3Smarkus return (-1); 994cb2fef99Stobhe log_debug("%s: signature scheme %zd selected", __func__, i); 995cb2fef99Stobhe need = sizeof(ptr[0]) + schemes[i].sc_len; 99648b975e3Smarkus if (ptr) { 997cb2fef99Stobhe if (len < need) 998cb2fef99Stobhe return (-1); 9995e4d3a37Sreyk ptr[0] = schemes[i].sc_len; 10005e4d3a37Sreyk memcpy(ptr + sizeof(ptr[0]), schemes[i].sc_oid, 10015e4d3a37Sreyk schemes[i].sc_len); 100248b975e3Smarkus } 100348b975e3Smarkus if (offp) 1004cb2fef99Stobhe *offp = need; 100548b975e3Smarkus return (0); 100648b975e3Smarkus } 100748b975e3Smarkus 10085e4d3a37Sreyk /* Export size of encoded signature hash type */ 10095e4d3a37Sreyk size_t 10105e4d3a37Sreyk dsa_prefix(struct iked_dsa *dsa) 10115e4d3a37Sreyk { 10125e4d3a37Sreyk size_t off = 0; 10135e4d3a37Sreyk 1014cb2fef99Stobhe if (_dsa_sign_encode(dsa, NULL, 0, &off) < 0) 10155e4d3a37Sreyk fatal("dsa_prefix: internal error"); 10165e4d3a37Sreyk return off; 10175e4d3a37Sreyk } 10185e4d3a37Sreyk 101945ae9d61Sreyk size_t 102045ae9d61Sreyk dsa_length(struct iked_dsa *dsa) 102145ae9d61Sreyk { 102245ae9d61Sreyk if (dsa->dsa_hmac) 102345ae9d61Sreyk return (EVP_MD_size(dsa->dsa_priv)); 10245e4d3a37Sreyk switch (dsa->dsa_method) { 10255e4d3a37Sreyk case IKEV2_AUTH_ECDSA_256: 10265e4d3a37Sreyk case IKEV2_AUTH_ECDSA_384: 10275e4d3a37Sreyk case IKEV2_AUTH_ECDSA_521: 10285e4d3a37Sreyk /* size of concat(r|s) */ 10295e4d3a37Sreyk return (2 * ((EVP_PKEY_bits(dsa->dsa_key) + 7) / 8)); 10305e4d3a37Sreyk } 10315e4d3a37Sreyk return (dsa_prefix(dsa) + EVP_PKEY_size(dsa->dsa_key)); 10325e4d3a37Sreyk } 10335e4d3a37Sreyk 10345e4d3a37Sreyk int 10355e4d3a37Sreyk _dsa_sign_ecdsa(struct iked_dsa *dsa, uint8_t *ptr, size_t len) 10365e4d3a37Sreyk { 10375e4d3a37Sreyk ECDSA_SIG *obj = NULL; 1038cb2fef99Stobhe uint8_t *tmp = NULL; 10394e7f824bSotto const uint8_t *p; 1040cb2fef99Stobhe size_t tmplen; 10415e4d3a37Sreyk int ret = -1; 10425e4d3a37Sreyk int bnlen, off; 104308c24fddStobhe const BIGNUM *r, *s; 10445e4d3a37Sreyk 10455e4d3a37Sreyk if (len % 2) 10465e4d3a37Sreyk goto done; /* must be even */ 10475e4d3a37Sreyk bnlen = len/2; 10485e4d3a37Sreyk /* 10495e4d3a37Sreyk * (a) create DER signature into 'tmp' buffer 10505e4d3a37Sreyk * (b) convert buffer to ECDSA_SIG object 10515e4d3a37Sreyk * (c) concatenate the padded r|s BIGNUMS into 'ptr' 10525e4d3a37Sreyk */ 1053cb2fef99Stobhe if (EVP_DigestSignFinal(dsa->dsa_ctx, NULL, &tmplen) != 1) 10545e4d3a37Sreyk goto done; 1055cb2fef99Stobhe if ((tmp = calloc(1, tmplen)) == NULL) 10565e4d3a37Sreyk goto done; 1057cb2fef99Stobhe if (EVP_DigestSignFinal(dsa->dsa_ctx, tmp, &tmplen) != 1) 10585e4d3a37Sreyk goto done; 10594e7f824bSotto p = tmp; 1060f0ca6b40Stb if ((obj = d2i_ECDSA_SIG(NULL, &p, tmplen)) == NULL) 10615e4d3a37Sreyk goto done; 106208c24fddStobhe ECDSA_SIG_get0(obj, &r, &s); 106308c24fddStobhe if (BN_num_bytes(r) > bnlen || BN_num_bytes(s) > bnlen) 10645e4d3a37Sreyk goto done; 10655e4d3a37Sreyk memset(ptr, 0, len); 106608c24fddStobhe off = bnlen - BN_num_bytes(r); 106708c24fddStobhe BN_bn2bin(r, ptr + off); 106808c24fddStobhe off = 2 * bnlen - BN_num_bytes(s); 106908c24fddStobhe BN_bn2bin(s, ptr + off); 10705e4d3a37Sreyk ret = 0; 10715e4d3a37Sreyk done: 1072cb2fef99Stobhe free(tmp); 10735e4d3a37Sreyk ECDSA_SIG_free(obj); 10747199b42cStobhe 10755e4d3a37Sreyk return (ret); 107645ae9d61Sreyk } 107745ae9d61Sreyk 107845ae9d61Sreyk ssize_t 107945ae9d61Sreyk dsa_sign_final(struct iked_dsa *dsa, void *buf, size_t len) 108045ae9d61Sreyk { 1081cb2fef99Stobhe unsigned int hmaclen; 108248b975e3Smarkus size_t off = 0; 1083d09d3a7dSreyk uint8_t *ptr = buf; 108445ae9d61Sreyk 108545ae9d61Sreyk if (len < dsa_length(dsa)) 108645ae9d61Sreyk return (-1); 108745ae9d61Sreyk 108880ff32ddSmikeb if (dsa->dsa_hmac) { 1089cb2fef99Stobhe if (!HMAC_Final(dsa->dsa_ctx, buf, &hmaclen)) 109080ff32ddSmikeb return (-1); 1091cb2fef99Stobhe if (hmaclen > INT_MAX) 1092cb2fef99Stobhe return (-1); 1093cb2fef99Stobhe return (ssize_t)hmaclen; 109480ff32ddSmikeb } else { 10955e4d3a37Sreyk switch (dsa->dsa_method) { 10965e4d3a37Sreyk case IKEV2_AUTH_ECDSA_256: 10975e4d3a37Sreyk case IKEV2_AUTH_ECDSA_384: 10985e4d3a37Sreyk case IKEV2_AUTH_ECDSA_521: 10995e4d3a37Sreyk if (_dsa_sign_ecdsa(dsa, buf, len) < 0) 11005e4d3a37Sreyk return (-1); 1101cb2fef99Stobhe return (len); 11025e4d3a37Sreyk default: 1103cb2fef99Stobhe if (_dsa_sign_encode(dsa, ptr, len, &off) < 0) 110448b975e3Smarkus return (-1); 1105cb2fef99Stobhe if (off > len) 110645ae9d61Sreyk return (-1); 1107cb2fef99Stobhe len -= off; 1108cb2fef99Stobhe ptr += off; 1109cb2fef99Stobhe if (EVP_DigestSignFinal(dsa->dsa_ctx, ptr, &len) != 1) 1110cb2fef99Stobhe return (-1); 1111cb2fef99Stobhe return (len + off); 11125e4d3a37Sreyk } 111345ae9d61Sreyk } 1114cb2fef99Stobhe return (-1); 111545ae9d61Sreyk } 111645ae9d61Sreyk 11175e4d3a37Sreyk int 11185e4d3a37Sreyk _dsa_verify_prepare(struct iked_dsa *dsa, uint8_t **sigp, size_t *lenp, 11195e4d3a37Sreyk uint8_t **freemep) 112048b975e3Smarkus { 11215e4d3a37Sreyk ECDSA_SIG *obj = NULL; 11225e4d3a37Sreyk uint8_t *ptr = NULL; 1123959c447eSbluhm size_t bnlen, off; 1124959c447eSbluhm ssize_t len; 11255e4d3a37Sreyk int ret = -1; 112608c24fddStobhe BIGNUM *r = NULL, *s = NULL; 11275e4d3a37Sreyk 11285e4d3a37Sreyk *freemep = NULL; /* don't return garbage in case of an error */ 11295e4d3a37Sreyk 11305e4d3a37Sreyk switch (dsa->dsa_method) { 11315e4d3a37Sreyk case IKEV2_AUTH_SIG: 113248b975e3Smarkus /* 11335e4d3a37Sreyk * The first byte of the signature encodes the OID 11345e4d3a37Sreyk * prefix length which we need to skip. 113548b975e3Smarkus */ 11365e4d3a37Sreyk off = (*sigp)[0] + 1; 11375e4d3a37Sreyk *sigp = *sigp + off; 11385e4d3a37Sreyk *lenp = *lenp - off; 11395e4d3a37Sreyk *freemep = NULL; 11405e4d3a37Sreyk ret = 0; 11415e4d3a37Sreyk break; 11425e4d3a37Sreyk case IKEV2_AUTH_ECDSA_256: 11435e4d3a37Sreyk case IKEV2_AUTH_ECDSA_384: 11445e4d3a37Sreyk case IKEV2_AUTH_ECDSA_521: 11455e4d3a37Sreyk /* 11465e4d3a37Sreyk * sigp points to concatenation r|s, while EVP_VerifyFinal() 11475e4d3a37Sreyk * expects the signature as a DER-encoded blob (of the two 11485e4d3a37Sreyk * values), so we need to convert the signature in a new 11495e4d3a37Sreyk * buffer (we cannot override the given buffer) and the caller 11505e4d3a37Sreyk * has to free this buffer ('freeme'). 11515e4d3a37Sreyk */ 11525e4d3a37Sreyk if (*lenp < 64 || *lenp > 132 || *lenp % 2) 11535e4d3a37Sreyk goto done; 11545e4d3a37Sreyk bnlen = (*lenp)/2; 11555e4d3a37Sreyk /* sigp points to concatenation: r|s */ 11565e4d3a37Sreyk if ((obj = ECDSA_SIG_new()) == NULL || 115708c24fddStobhe (r = BN_bin2bn(*sigp, bnlen, NULL)) == NULL || 115808c24fddStobhe (s = BN_bin2bn(*sigp+bnlen, bnlen, NULL)) == NULL || 115908c24fddStobhe ECDSA_SIG_set0(obj, r, s) == 0 || 1160959c447eSbluhm (len = i2d_ECDSA_SIG(obj, &ptr)) <= 0) 11615e4d3a37Sreyk goto done; 116208c24fddStobhe r = s = NULL; 11635e4d3a37Sreyk *lenp = len; 11645e4d3a37Sreyk *sigp = ptr; 11655e4d3a37Sreyk *freemep = ptr; 11665e4d3a37Sreyk ptr = NULL; 11675e4d3a37Sreyk ret = 0; 11685e4d3a37Sreyk break; 11695e4d3a37Sreyk default: 117048b975e3Smarkus return (0); 117148b975e3Smarkus } 11725e4d3a37Sreyk done: 117308c24fddStobhe BN_clear_free(r); 117408c24fddStobhe BN_clear_free(s); 11755e4d3a37Sreyk free(ptr); 11765e4d3a37Sreyk ECDSA_SIG_free(obj); 11777199b42cStobhe 11785e4d3a37Sreyk return (ret); 11795e4d3a37Sreyk } 118048b975e3Smarkus 118145ae9d61Sreyk ssize_t 118245ae9d61Sreyk dsa_verify_final(struct iked_dsa *dsa, void *buf, size_t len) 118345ae9d61Sreyk { 1184d09d3a7dSreyk uint8_t sig[EVP_MAX_MD_SIZE]; 11855e4d3a37Sreyk uint8_t *ptr = buf, *freeme = NULL; 1186d09d3a7dSreyk unsigned int siglen = sizeof(sig); 118745ae9d61Sreyk 118845ae9d61Sreyk if (dsa->dsa_hmac) { 118980ff32ddSmikeb if (!HMAC_Final(dsa->dsa_ctx, sig, &siglen)) 119080ff32ddSmikeb return (-1); 119145ae9d61Sreyk if (siglen != len || memcmp(buf, sig, siglen) != 0) 119245ae9d61Sreyk return (-1); 119345ae9d61Sreyk } else { 11945e4d3a37Sreyk if (_dsa_verify_prepare(dsa, &ptr, &len, &freeme) < 0) 119548b975e3Smarkus return (-1); 1196cb2fef99Stobhe if (EVP_DigestVerifyFinal(dsa->dsa_ctx, ptr, len) != 1) { 1197bac832a5Stobhe OPENSSL_free(freeme); 119886cf9d9cSmarkus ca_sslerror(__func__); 119945ae9d61Sreyk return (-1); 120045ae9d61Sreyk } 1201bac832a5Stobhe OPENSSL_free(freeme); 120245ae9d61Sreyk } 120345ae9d61Sreyk 120445ae9d61Sreyk return (0); 120545ae9d61Sreyk } 1206