1289848Sjkim/* crypto/ecdh/ec_kdf.c */ 2289848Sjkim/* 3289848Sjkim * Written by Stephen Henson for the OpenSSL project. 4289848Sjkim */ 5289848Sjkim/* ==================================================================== 6289848Sjkim * Copyright (c) 2013 The OpenSSL Project. All rights reserved. 7289848Sjkim * 8289848Sjkim * Redistribution and use in source and binary forms, with or without 9289848Sjkim * modification, are permitted provided that the following conditions 10289848Sjkim * are met: 11289848Sjkim * 12289848Sjkim * 1. Redistributions of source code must retain the above copyright 13289848Sjkim * notice, this list of conditions and the following disclaimer. 14289848Sjkim * 15289848Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16289848Sjkim * notice, this list of conditions and the following disclaimer in 17289848Sjkim * the documentation and/or other materials provided with the 18289848Sjkim * distribution. 19289848Sjkim * 20289848Sjkim * 3. All advertising materials mentioning features or use of this 21289848Sjkim * software must display the following acknowledgment: 22289848Sjkim * "This product includes software developed by the OpenSSL Project 23289848Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24289848Sjkim * 25289848Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26289848Sjkim * endorse or promote products derived from this software without 27289848Sjkim * prior written permission. For written permission, please contact 28289848Sjkim * openssl-core@openssl.org. 29289848Sjkim * 30289848Sjkim * 5. Products derived from this software may not be called "OpenSSL" 31289848Sjkim * nor may "OpenSSL" appear in their names without prior written 32289848Sjkim * permission of the OpenSSL Project. 33289848Sjkim * 34289848Sjkim * 6. Redistributions of any form whatsoever must retain the following 35289848Sjkim * acknowledgment: 36289848Sjkim * "This product includes software developed by the OpenSSL Project 37289848Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38289848Sjkim * 39289848Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40289848Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41289848Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42289848Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43289848Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44289848Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45289848Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46289848Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47289848Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48289848Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49289848Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50289848Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 51289848Sjkim * ==================================================================== 52289848Sjkim */ 53289848Sjkim 54289848Sjkim#define OPENSSL_FIPSAPI 55289848Sjkim 56289848Sjkim#include <string.h> 57289848Sjkim#include <openssl/ecdh.h> 58289848Sjkim#include <openssl/evp.h> 59289848Sjkim 60289848Sjkim/* Key derivation function from X9.62/SECG */ 61289848Sjkim/* Way more than we will ever need */ 62289848Sjkim#define ECDH_KDF_MAX (1 << 30) 63289848Sjkim 64289848Sjkimint ECDH_KDF_X9_62(unsigned char *out, size_t outlen, 65289848Sjkim const unsigned char *Z, size_t Zlen, 66289848Sjkim const unsigned char *sinfo, size_t sinfolen, 67289848Sjkim const EVP_MD *md) 68289848Sjkim{ 69289848Sjkim EVP_MD_CTX mctx; 70289848Sjkim int rv = 0; 71289848Sjkim unsigned int i; 72289848Sjkim size_t mdlen; 73289848Sjkim unsigned char ctr[4]; 74289848Sjkim if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX 75289848Sjkim || Zlen > ECDH_KDF_MAX) 76289848Sjkim return 0; 77289848Sjkim mdlen = EVP_MD_size(md); 78289848Sjkim EVP_MD_CTX_init(&mctx); 79289848Sjkim for (i = 1;; i++) { 80289848Sjkim unsigned char mtmp[EVP_MAX_MD_SIZE]; 81289848Sjkim EVP_DigestInit_ex(&mctx, md, NULL); 82289848Sjkim ctr[3] = i & 0xFF; 83289848Sjkim ctr[2] = (i >> 8) & 0xFF; 84289848Sjkim ctr[1] = (i >> 16) & 0xFF; 85289848Sjkim ctr[0] = (i >> 24) & 0xFF; 86289848Sjkim if (!EVP_DigestUpdate(&mctx, Z, Zlen)) 87289848Sjkim goto err; 88289848Sjkim if (!EVP_DigestUpdate(&mctx, ctr, sizeof(ctr))) 89289848Sjkim goto err; 90289848Sjkim if (!EVP_DigestUpdate(&mctx, sinfo, sinfolen)) 91289848Sjkim goto err; 92289848Sjkim if (outlen >= mdlen) { 93289848Sjkim if (!EVP_DigestFinal(&mctx, out, NULL)) 94289848Sjkim goto err; 95289848Sjkim outlen -= mdlen; 96289848Sjkim if (outlen == 0) 97289848Sjkim break; 98289848Sjkim out += mdlen; 99289848Sjkim } else { 100289848Sjkim if (!EVP_DigestFinal(&mctx, mtmp, NULL)) 101289848Sjkim goto err; 102289848Sjkim memcpy(out, mtmp, outlen); 103289848Sjkim OPENSSL_cleanse(mtmp, mdlen); 104289848Sjkim break; 105289848Sjkim } 106289848Sjkim } 107289848Sjkim rv = 1; 108289848Sjkim err: 109289848Sjkim EVP_MD_CTX_cleanup(&mctx); 110289848Sjkim return rv; 111289848Sjkim} 112