diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2015-10-23 19:46:02 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2015-10-23 19:46:02 +0000 |
commit | e9fcefce9bb70f20c272a996443928c5f6ab8cd8 (patch) | |
tree | ae816a5a768ec78af3610e509ca39507b33aa9f7 /crypto/ecdh | |
parent | c07d7b3a386974c338492659291008bed07948e6 (diff) | |
download | src-e9fcefce9bb70f20c272a996443928c5f6ab8cd8.tar.gz src-e9fcefce9bb70f20c272a996443928c5f6ab8cd8.zip |
Import OpenSSL 1.0.2d.vendor/openssl/1.0.2d
Notes
Notes:
svn path=/vendor-crypto/openssl/dist/; revision=289848
svn path=/vendor-crypto/openssl/1.0.2d/; revision=289849; tag=vendor/openssl/1.0.2d
Diffstat (limited to 'crypto/ecdh')
-rw-r--r-- | crypto/ecdh/Makefile | 12 | ||||
-rw-r--r-- | crypto/ecdh/ecdh.h | 7 | ||||
-rw-r--r-- | crypto/ecdh/ecdhtest.c | 170 | ||||
-rw-r--r-- | crypto/ecdh/ech_kdf.c | 111 | ||||
-rw-r--r-- | crypto/ecdh/ech_ossl.c | 10 |
5 files changed, 308 insertions, 2 deletions
diff --git a/crypto/ecdh/Makefile b/crypto/ecdh/Makefile index f0766356a132..1b31ba1f0b3f 100644 --- a/crypto/ecdh/Makefile +++ b/crypto/ecdh/Makefile @@ -17,9 +17,9 @@ TEST=ecdhtest.c APPS= LIB=$(TOP)/libcrypto.a -LIBSRC= ech_lib.c ech_ossl.c ech_key.c ech_err.c +LIBSRC= ech_lib.c ech_ossl.c ech_key.c ech_err.c ech_kdf.c -LIBOBJ= ech_lib.o ech_ossl.o ech_key.o ech_err.o +LIBOBJ= ech_lib.o ech_ossl.o ech_key.o ech_err.o ech_kdf.o SRC= $(LIBSRC) @@ -85,6 +85,14 @@ ech_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h ech_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h ech_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h ech_err.o: ech_err.c +ech_kdf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +ech_kdf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +ech_kdf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +ech_kdf.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h +ech_kdf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +ech_kdf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +ech_kdf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +ech_kdf.o: ../../include/openssl/symhacks.h ech_kdf.c ech_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ech_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ech_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h diff --git a/crypto/ecdh/ecdh.h b/crypto/ecdh/ecdh.h index a9b811abd050..25348b30fe7c 100644 --- a/crypto/ecdh/ecdh.h +++ b/crypto/ecdh/ecdh.h @@ -85,6 +85,8 @@ extern "C" { #endif +# define EC_FLAG_COFACTOR_ECDH 0x1000 + const ECDH_METHOD *ECDH_OpenSSL(void); void ECDH_set_default_method(const ECDH_METHOD *); @@ -101,6 +103,11 @@ int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); void *ECDH_get_ex_data(EC_KEY *d, int idx); +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + /* BEGIN ERROR CODES */ /* * The following lines are auto generated by the script mkerr.pl. Any changes diff --git a/crypto/ecdh/ecdhtest.c b/crypto/ecdh/ecdhtest.c index 996321d1ee43..2fe2c66443d0 100644 --- a/crypto/ecdh/ecdhtest.c +++ b/crypto/ecdh/ecdhtest.c @@ -312,6 +312,170 @@ static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) return (ret); } +/* Keys and shared secrets from RFC 7027 */ + +static const unsigned char bp256_da[] = { + 0x81, 0xDB, 0x1E, 0xE1, 0x00, 0x15, 0x0F, 0xF2, 0xEA, 0x33, 0x8D, 0x70, + 0x82, 0x71, 0xBE, 0x38, 0x30, 0x0C, 0xB5, 0x42, 0x41, 0xD7, 0x99, 0x50, + 0xF7, 0x7B, 0x06, 0x30, 0x39, 0x80, 0x4F, 0x1D +}; + +static const unsigned char bp256_db[] = { + 0x55, 0xE4, 0x0B, 0xC4, 0x1E, 0x37, 0xE3, 0xE2, 0xAD, 0x25, 0xC3, 0xC6, + 0x65, 0x45, 0x11, 0xFF, 0xA8, 0x47, 0x4A, 0x91, 0xA0, 0x03, 0x20, 0x87, + 0x59, 0x38, 0x52, 0xD3, 0xE7, 0xD7, 0x6B, 0xD3 +}; + +static const unsigned char bp256_Z[] = { + 0x89, 0xAF, 0xC3, 0x9D, 0x41, 0xD3, 0xB3, 0x27, 0x81, 0x4B, 0x80, 0x94, + 0x0B, 0x04, 0x25, 0x90, 0xF9, 0x65, 0x56, 0xEC, 0x91, 0xE6, 0xAE, 0x79, + 0x39, 0xBC, 0xE3, 0x1F, 0x3A, 0x18, 0xBF, 0x2B +}; + +static const unsigned char bp384_da[] = { + 0x1E, 0x20, 0xF5, 0xE0, 0x48, 0xA5, 0x88, 0x6F, 0x1F, 0x15, 0x7C, 0x74, + 0xE9, 0x1B, 0xDE, 0x2B, 0x98, 0xC8, 0xB5, 0x2D, 0x58, 0xE5, 0x00, 0x3D, + 0x57, 0x05, 0x3F, 0xC4, 0xB0, 0xBD, 0x65, 0xD6, 0xF1, 0x5E, 0xB5, 0xD1, + 0xEE, 0x16, 0x10, 0xDF, 0x87, 0x07, 0x95, 0x14, 0x36, 0x27, 0xD0, 0x42 +}; + +static const unsigned char bp384_db[] = { + 0x03, 0x26, 0x40, 0xBC, 0x60, 0x03, 0xC5, 0x92, 0x60, 0xF7, 0x25, 0x0C, + 0x3D, 0xB5, 0x8C, 0xE6, 0x47, 0xF9, 0x8E, 0x12, 0x60, 0xAC, 0xCE, 0x4A, + 0xCD, 0xA3, 0xDD, 0x86, 0x9F, 0x74, 0xE0, 0x1F, 0x8B, 0xA5, 0xE0, 0x32, + 0x43, 0x09, 0xDB, 0x6A, 0x98, 0x31, 0x49, 0x7A, 0xBA, 0xC9, 0x66, 0x70 +}; + +static const unsigned char bp384_Z[] = { + 0x0B, 0xD9, 0xD3, 0xA7, 0xEA, 0x0B, 0x3D, 0x51, 0x9D, 0x09, 0xD8, 0xE4, + 0x8D, 0x07, 0x85, 0xFB, 0x74, 0x4A, 0x6B, 0x35, 0x5E, 0x63, 0x04, 0xBC, + 0x51, 0xC2, 0x29, 0xFB, 0xBC, 0xE2, 0x39, 0xBB, 0xAD, 0xF6, 0x40, 0x37, + 0x15, 0xC3, 0x5D, 0x4F, 0xB2, 0xA5, 0x44, 0x4F, 0x57, 0x5D, 0x4F, 0x42 +}; + +static const unsigned char bp512_da[] = { + 0x16, 0x30, 0x2F, 0xF0, 0xDB, 0xBB, 0x5A, 0x8D, 0x73, 0x3D, 0xAB, 0x71, + 0x41, 0xC1, 0xB4, 0x5A, 0xCB, 0xC8, 0x71, 0x59, 0x39, 0x67, 0x7F, 0x6A, + 0x56, 0x85, 0x0A, 0x38, 0xBD, 0x87, 0xBD, 0x59, 0xB0, 0x9E, 0x80, 0x27, + 0x96, 0x09, 0xFF, 0x33, 0x3E, 0xB9, 0xD4, 0xC0, 0x61, 0x23, 0x1F, 0xB2, + 0x6F, 0x92, 0xEE, 0xB0, 0x49, 0x82, 0xA5, 0xF1, 0xD1, 0x76, 0x4C, 0xAD, + 0x57, 0x66, 0x54, 0x22 +}; + +static const unsigned char bp512_db[] = { + 0x23, 0x0E, 0x18, 0xE1, 0xBC, 0xC8, 0x8A, 0x36, 0x2F, 0xA5, 0x4E, 0x4E, + 0xA3, 0x90, 0x20, 0x09, 0x29, 0x2F, 0x7F, 0x80, 0x33, 0x62, 0x4F, 0xD4, + 0x71, 0xB5, 0xD8, 0xAC, 0xE4, 0x9D, 0x12, 0xCF, 0xAB, 0xBC, 0x19, 0x96, + 0x3D, 0xAB, 0x8E, 0x2F, 0x1E, 0xBA, 0x00, 0xBF, 0xFB, 0x29, 0xE4, 0xD7, + 0x2D, 0x13, 0xF2, 0x22, 0x45, 0x62, 0xF4, 0x05, 0xCB, 0x80, 0x50, 0x36, + 0x66, 0xB2, 0x54, 0x29 +}; + +static const unsigned char bp512_Z[] = { + 0xA7, 0x92, 0x70, 0x98, 0x65, 0x5F, 0x1F, 0x99, 0x76, 0xFA, 0x50, 0xA9, + 0xD5, 0x66, 0x86, 0x5D, 0xC5, 0x30, 0x33, 0x18, 0x46, 0x38, 0x1C, 0x87, + 0x25, 0x6B, 0xAF, 0x32, 0x26, 0x24, 0x4B, 0x76, 0xD3, 0x64, 0x03, 0xC0, + 0x24, 0xD7, 0xBB, 0xF0, 0xAA, 0x08, 0x03, 0xEA, 0xFF, 0x40, 0x5D, 0x3D, + 0x24, 0xF1, 0x1A, 0x9B, 0x5C, 0x0B, 0xEF, 0x67, 0x9F, 0xE1, 0x45, 0x4B, + 0x21, 0xC4, 0xCD, 0x1F +}; + +/* Given private value and NID, create EC_KEY structure */ + +static EC_KEY *mk_eckey(int nid, const unsigned char *p, size_t plen) +{ + int ok = 0; + EC_KEY *k = NULL; + BIGNUM *priv = NULL; + EC_POINT *pub = NULL; + const EC_GROUP *grp; + k = EC_KEY_new_by_curve_name(nid); + if (!k) + goto err; + priv = BN_bin2bn(p, plen, NULL); + if (!priv) + goto err; + if (!EC_KEY_set_private_key(k, priv)) + goto err; + grp = EC_KEY_get0_group(k); + pub = EC_POINT_new(grp); + if (!pub) + goto err; + if (!EC_POINT_mul(grp, pub, priv, NULL, NULL, NULL)) + goto err; + if (!EC_KEY_set_public_key(k, pub)) + goto err; + ok = 1; + err: + if (priv) + BN_clear_free(priv); + if (pub) + EC_POINT_free(pub); + if (ok) + return k; + else if (k) + EC_KEY_free(k); + return NULL; +} + +/* + * Known answer test: compute shared secret and check it matches expected + * value. + */ + +static int ecdh_kat(BIO *out, const char *cname, int nid, + const unsigned char *k1, size_t k1_len, + const unsigned char *k2, size_t k2_len, + const unsigned char *Z, size_t Zlen) +{ + int rv = 0; + EC_KEY *key1 = NULL, *key2 = NULL; + unsigned char *Ztmp = NULL; + size_t Ztmplen; + BIO_puts(out, "Testing ECDH shared secret with "); + BIO_puts(out, cname); + key1 = mk_eckey(nid, k1, k1_len); + key2 = mk_eckey(nid, k2, k2_len); + if (!key1 || !key2) + goto err; + Ztmplen = (EC_GROUP_get_degree(EC_KEY_get0_group(key1)) + 7) / 8; + if (Ztmplen != Zlen) + goto err; + Ztmp = OPENSSL_malloc(Ztmplen); + if (!ECDH_compute_key(Ztmp, Ztmplen, + EC_KEY_get0_public_key(key2), key1, 0)) + goto err; + if (memcmp(Ztmp, Z, Zlen)) + goto err; + memset(Ztmp, 0, Zlen); + if (!ECDH_compute_key(Ztmp, Ztmplen, + EC_KEY_get0_public_key(key1), key2, 0)) + goto err; + if (memcmp(Ztmp, Z, Zlen)) + goto err; + rv = 1; + err: + if (key1) + EC_KEY_free(key1); + if (key2) + EC_KEY_free(key2); + if (Ztmp) + OPENSSL_free(Ztmp); + if (rv) + BIO_puts(out, " ok\n"); + else { + fprintf(stderr, "Error in ECDH routines\n"); + ERR_print_errors_fp(stderr); + } + return rv; +} + +# define test_ecdh_kat(bio, curve, bits) \ + ecdh_kat(bio, curve, NID_brainpoolP##bits##r1, \ + bp##bits##_da, sizeof(bp##bits##_da), \ + bp##bits##_db, sizeof(bp##bits##_db), \ + bp##bits##_Z, sizeof(bp##bits##_Z)) + int main(int argc, char *argv[]) { BN_CTX *ctx = NULL; @@ -372,6 +536,12 @@ int main(int argc, char *argv[]) if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) goto err; # endif + if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP256r1", 256)) + goto err; + if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP384r1", 384)) + goto err; + if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP512r1", 512)) + goto err; ret = 0; diff --git a/crypto/ecdh/ech_kdf.c b/crypto/ecdh/ech_kdf.c new file mode 100644 index 000000000000..ac722ac9ee69 --- /dev/null +++ b/crypto/ecdh/ech_kdf.c @@ -0,0 +1,111 @@ +/* crypto/ecdh/ec_kdf.c */ +/* + * Written by Stephen Henson for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include <string.h> +#include <openssl/ecdh.h> +#include <openssl/evp.h> + +/* Key derivation function from X9.62/SECG */ +/* Way more than we will ever need */ +#define ECDH_KDF_MAX (1 << 30) + +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md) +{ + EVP_MD_CTX mctx; + int rv = 0; + unsigned int i; + size_t mdlen; + unsigned char ctr[4]; + if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX + || Zlen > ECDH_KDF_MAX) + return 0; + mdlen = EVP_MD_size(md); + EVP_MD_CTX_init(&mctx); + for (i = 1;; i++) { + unsigned char mtmp[EVP_MAX_MD_SIZE]; + EVP_DigestInit_ex(&mctx, md, NULL); + ctr[3] = i & 0xFF; + ctr[2] = (i >> 8) & 0xFF; + ctr[1] = (i >> 16) & 0xFF; + ctr[0] = (i >> 24) & 0xFF; + if (!EVP_DigestUpdate(&mctx, Z, Zlen)) + goto err; + if (!EVP_DigestUpdate(&mctx, ctr, sizeof(ctr))) + goto err; + if (!EVP_DigestUpdate(&mctx, sinfo, sinfolen)) + goto err; + if (outlen >= mdlen) { + if (!EVP_DigestFinal(&mctx, out, NULL)) + goto err; + outlen -= mdlen; + if (outlen == 0) + break; + out += mdlen; + } else { + if (!EVP_DigestFinal(&mctx, mtmp, NULL)) + goto err; + memcpy(out, mtmp, outlen); + OPENSSL_cleanse(mtmp, mdlen); + break; + } + } + rv = 1; + err: + EVP_MD_CTX_cleanup(&mctx); + return rv; +} diff --git a/crypto/ecdh/ech_ossl.c b/crypto/ecdh/ech_ossl.c index d448b19a528f..df115cc262e5 100644 --- a/crypto/ecdh/ech_ossl.c +++ b/crypto/ecdh/ech_ossl.c @@ -138,6 +138,16 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, } group = EC_KEY_get0_group(ecdh); + + if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) { + if (!EC_GROUP_get_cofactor(group, x, ctx) || + !BN_mul(x, x, priv_key, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + priv_key = x; + } + if ((tmp = EC_POINT_new(group)) == NULL) { ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); goto err; |