1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The Elliptic Curve Public-Key Crypto Library (ECC Code) included 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * herein is developed by SUN MICROSYSTEMS, INC., and is contributed 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to the OpenSSL project. 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The ECC Code is licensed pursuant to the OpenSSL open source 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * license provided below. 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The ECDH software is originally written by Douglas Stebila of 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Sun Microsystems Laboratories. 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * licensing@OpenSSL.org. 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */ 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ecdh.h> 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bn.h> 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/digest.h> 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY *priv_key, void *(*KDF)(const void *in, size_t inlen, 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley void *out, size_t *outlen)) { 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *ctx; 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT *tmp = NULL; 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *x = NULL, *y = NULL; 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const BIGNUM *priv; 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const EC_GROUP *group; 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret = -1; 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t buflen; 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t *buf = NULL; 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if ((ctx = BN_CTX_new()) == NULL) { 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_start(ctx); 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley x = BN_CTX_get(ctx); 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley y = BN_CTX_get(ctx); 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley priv = EC_KEY_get0_private_key(priv_key); 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (priv == NULL) { 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_NO_PRIVATE_VALUE); 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley group = EC_KEY_get0_group(priv_key); 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley tmp = EC_POINT_new(group); 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (tmp == NULL) { 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE); 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv, ctx)) { 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_POINT_ARITHMETIC_FAILURE); 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) { 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_POINT_ARITHMETIC_FAILURE); 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley buflen = (EC_GROUP_get_degree(group) + 7) / 8; 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley buf = OPENSSL_malloc(buflen); 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (buf == NULL) { 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE); 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_bn2bin_padded(buf, buflen, x)) { 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_INTERNAL_ERROR); 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (KDF != 0) { 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (KDF(buf, buflen, out, &outlen) == NULL) { 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_KDF_FAILED); 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = outlen; 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* no KDF, just copy as much as we can */ 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (outlen > buflen) { 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = buflen; 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley memcpy(out, buf, outlen); 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = outlen; 145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 148e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (tmp) { 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT_free(tmp); 150e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 151e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (ctx) { 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_end(ctx); 153e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 154e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (ctx) { 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_free(ctx); 156e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 157e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (buf) { 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(buf); 159e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 162