diff options
Diffstat (limited to 'thirdparty/openssl/crypto/ecdh/ech_lib.c')
| -rw-r--r-- | thirdparty/openssl/crypto/ecdh/ech_lib.c | 265 | 
1 files changed, 265 insertions, 0 deletions
diff --git a/thirdparty/openssl/crypto/ecdh/ech_lib.c b/thirdparty/openssl/crypto/ecdh/ech_lib.c new file mode 100644 index 0000000000..cbc21d1a27 --- /dev/null +++ b/thirdparty/openssl/crypto/ecdh/ech_lib.c @@ -0,0 +1,265 @@ +/* crypto/ecdh/ech_lib.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com).  This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ech_locl.h" +#include <string.h> +#ifndef OPENSSL_NO_ENGINE +# include <openssl/engine.h> +#endif +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif + +const char ECDH_version[] = "ECDH" OPENSSL_VERSION_PTEXT; + +static const ECDH_METHOD *default_ECDH_method = NULL; + +static void *ecdh_data_new(void); +static void *ecdh_data_dup(void *); +static void ecdh_data_free(void *); + +void ECDH_set_default_method(const ECDH_METHOD *meth) +{ +    default_ECDH_method = meth; +} + +const ECDH_METHOD *ECDH_get_default_method(void) +{ +    if (!default_ECDH_method) { +#ifdef OPENSSL_FIPS +        if (FIPS_mode()) +            return FIPS_ecdh_openssl(); +        else +            return ECDH_OpenSSL(); +#else +        default_ECDH_method = ECDH_OpenSSL(); +#endif +    } +    return default_ECDH_method; +} + +int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth) +{ +    ECDH_DATA *ecdh; + +    ecdh = ecdh_check(eckey); + +    if (ecdh == NULL) +        return 0; + +#if 0 +    mtmp = ecdh->meth; +    if (mtmp->finish) +        mtmp->finish(eckey); +#endif +#ifndef OPENSSL_NO_ENGINE +    if (ecdh->engine) { +        ENGINE_finish(ecdh->engine); +        ecdh->engine = NULL; +    } +#endif +    ecdh->meth = meth; +#if 0 +    if (meth->init) +        meth->init(eckey); +#endif +    return 1; +} + +static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine) +{ +    ECDH_DATA *ret; + +    ret = (ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA)); +    if (ret == NULL) { +        ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); +        return (NULL); +    } + +    ret->init = NULL; + +    ret->meth = ECDH_get_default_method(); +    ret->engine = engine; +#ifndef OPENSSL_NO_ENGINE +    if (!ret->engine) +        ret->engine = ENGINE_get_default_ECDH(); +    if (ret->engine) { +        ret->meth = ENGINE_get_ECDH(ret->engine); +        if (!ret->meth) { +            ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); +            ENGINE_finish(ret->engine); +            OPENSSL_free(ret); +            return NULL; +        } +    } +#endif + +    ret->flags = ret->meth->flags; +    CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); +#if 0 +    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); +        OPENSSL_free(ret); +        ret = NULL; +    } +#endif +    return (ret); +} + +static void *ecdh_data_new(void) +{ +    return (void *)ECDH_DATA_new_method(NULL); +} + +static void *ecdh_data_dup(void *data) +{ +    ECDH_DATA *r = (ECDH_DATA *)data; + +    /* XXX: dummy operation */ +    if (r == NULL) +        return NULL; + +    return (void *)ecdh_data_new(); +} + +void ecdh_data_free(void *data) +{ +    ECDH_DATA *r = (ECDH_DATA *)data; + +#ifndef OPENSSL_NO_ENGINE +    if (r->engine) +        ENGINE_finish(r->engine); +#endif + +    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data); + +    OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA)); + +    OPENSSL_free(r); +} + +ECDH_DATA *ecdh_check(EC_KEY *key) +{ +    ECDH_DATA *ecdh_data; + +    void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup, +                                            ecdh_data_free, ecdh_data_free); +    if (data == NULL) { +        ecdh_data = (ECDH_DATA *)ecdh_data_new(); +        if (ecdh_data == NULL) +            return NULL; +        data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data, +                                             ecdh_data_dup, ecdh_data_free, +                                             ecdh_data_free); +        if (data != NULL) { +            /* +             * Another thread raced us to install the key_method data and +             * won. +             */ +            ecdh_data_free(ecdh_data); +            ecdh_data = (ECDH_DATA *)data; +        } +    } else +        ecdh_data = (ECDH_DATA *)data; +#ifdef OPENSSL_FIPS +    if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) +        && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { +        ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD); +        return NULL; +    } +#endif + +    return ecdh_data; +} + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, +                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ +    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp, +                                   new_func, dup_func, free_func); +} + +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg) +{ +    ECDH_DATA *ecdh; +    ecdh = ecdh_check(d); +    if (ecdh == NULL) +        return 0; +    return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg)); +} + +void *ECDH_get_ex_data(EC_KEY *d, int idx) +{ +    ECDH_DATA *ecdh; +    ecdh = ecdh_check(d); +    if (ecdh == NULL) +        return NULL; +    return (CRYPTO_get_ex_data(&ecdh->ex_data, idx)); +}  |