Annotation of embedaddon/strongswan/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2018 RenĂ© Korthaus
                      3:  * Rohde & Schwarz Cybersecurity GmbH
                      4:  *
                      5:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      6:  * of this software and associated documentation files (the "Software"), to deal
                      7:  * in the Software without restriction, including without limitation the rights
                      8:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                      9:  * copies of the Software, and to permit persons to whom the Software is
                     10:  * furnished to do so, subject to the following conditions:
                     11:  *
                     12:  * The above copyright notice and this permission notice shall be included in
                     13:  * all copies or substantial portions of the Software.
                     14:  *
                     15:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     16:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     17:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     18:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     19:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     20:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     21:  * THE SOFTWARE.
                     22:  */
                     23: 
                     24: #include "botan_ec_diffie_hellman.h"
                     25: 
                     26: #include <botan/build.h>
                     27: 
                     28: #ifdef BOTAN_HAS_ECDH
                     29: 
                     30: #include "botan_util.h"
                     31: 
                     32: #include <utils/debug.h>
                     33: 
                     34: #include <botan/ffi.h>
                     35: 
                     36: typedef struct private_botan_ec_diffie_hellman_t private_botan_ec_diffie_hellman_t;
                     37: 
                     38: /**
                     39:  * Private data of a botan_ec_diffie_hellman_t object.
                     40:  */
                     41: struct private_botan_ec_diffie_hellman_t {
                     42: 
                     43:        /**
                     44:         * Public interface
                     45:         */
                     46:        botan_ec_diffie_hellman_t public;
                     47: 
                     48:        /**
                     49:         * Diffie Hellman group
                     50:         */
                     51:        diffie_hellman_group_t group;
                     52: 
                     53:        /**
                     54:         * EC curve name
                     55:         */
                     56:        const char* curve_name;
                     57: 
                     58:        /**
                     59:         * EC private key
                     60:         */
                     61:        botan_privkey_t key;
                     62: 
                     63:        /**
                     64:         * Shared secret
                     65:         */
                     66:        chunk_t shared_secret;
                     67: };
                     68: 
                     69: METHOD(diffie_hellman_t, set_other_public_value, bool,
                     70:        private_botan_ec_diffie_hellman_t *this, chunk_t value)
                     71: {
                     72:        if (!diffie_hellman_verify_value(this->group, value))
                     73:        {
                     74:                return FALSE;
                     75:        }
                     76: 
                     77:        chunk_clear(&this->shared_secret);
                     78: 
                     79:        /* prepend 0x04 to indicate uncompressed point format */
                     80:        value = chunk_cata("cc", chunk_from_chars(0x04), value);
                     81: 
                     82:        return botan_dh_key_derivation(this->key, value, &this->shared_secret);
                     83: }
                     84: 
                     85: METHOD(diffie_hellman_t, get_my_public_value, bool,
                     86:        private_botan_ec_diffie_hellman_t *this, chunk_t *value)
                     87: {
                     88:        chunk_t pkey = chunk_empty;
                     89: 
                     90:        if (botan_pk_op_key_agreement_export_public(this->key, NULL, &pkey.len)
                     91:                != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
                     92:        {
                     93:                return FALSE;
                     94:        }
                     95: 
                     96:        pkey = chunk_alloca(pkey.len);
                     97:        if (botan_pk_op_key_agreement_export_public(this->key, pkey.ptr, &pkey.len))
                     98:        {
                     99:                return FALSE;
                    100:        }
                    101: 
                    102:        /* skip 0x04 byte prepended by botan */
                    103:        *value = chunk_clone(chunk_skip(pkey, 1));
                    104:        return TRUE;
                    105: }
                    106: 
                    107: METHOD(diffie_hellman_t, set_private_value, bool,
                    108:        private_botan_ec_diffie_hellman_t *this, chunk_t value)
                    109: {
                    110:        botan_mp_t scalar;
                    111: 
                    112:        chunk_clear(&this->shared_secret);
                    113: 
                    114:        if (!chunk_to_botan_mp(value, &scalar))
                    115:        {
                    116:                return FALSE;
                    117:        }
                    118: 
                    119:        if (botan_privkey_destroy(this->key))
                    120:        {
                    121:                botan_mp_destroy(scalar);
                    122:                return FALSE;
                    123:        }
                    124: 
                    125:        if (botan_privkey_load_ecdh(&this->key, scalar, this->curve_name))
                    126:        {
                    127:                botan_mp_destroy(scalar);
                    128:                return FALSE;
                    129:        }
                    130: 
                    131:        botan_mp_destroy(scalar);
                    132:        return TRUE;
                    133: }
                    134: 
                    135: METHOD(diffie_hellman_t, get_shared_secret, bool,
                    136:        private_botan_ec_diffie_hellman_t *this, chunk_t *secret)
                    137: {
                    138:        if (!this->shared_secret.len)
                    139:        {
                    140:                return FALSE;
                    141:        }
                    142:        *secret = chunk_clone(this->shared_secret);
                    143:        return TRUE;
                    144: }
                    145: 
                    146: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
                    147:        private_botan_ec_diffie_hellman_t *this)
                    148: {
                    149:        return this->group;
                    150: }
                    151: 
                    152: METHOD(diffie_hellman_t, destroy, void,
                    153:        private_botan_ec_diffie_hellman_t *this)
                    154: {
                    155:        botan_privkey_destroy(this->key);
                    156:        chunk_clear(&this->shared_secret);
                    157:        free(this);
                    158: }
                    159: 
                    160: /*
                    161:  * Described in header.
                    162:  */
                    163: botan_ec_diffie_hellman_t *botan_ec_diffie_hellman_create(
                    164:                                                                                                diffie_hellman_group_t group)
                    165: {
                    166:        private_botan_ec_diffie_hellman_t *this;
                    167:        botan_rng_t rng;
                    168: 
                    169:        INIT(this,
                    170:                .public = {
                    171:                        .dh = {
                    172:                                .get_shared_secret = _get_shared_secret,
                    173:                                .set_other_public_value = _set_other_public_value,
                    174:                                .get_my_public_value = _get_my_public_value,
                    175:                                .set_private_value = _set_private_value,
                    176:                                .get_dh_group = _get_dh_group,
                    177:                                .destroy = _destroy,
                    178:                        },
                    179:                },
                    180:                .group = group,
                    181:        );
                    182: 
                    183:        switch (group)
                    184:        {
                    185:                case ECP_256_BIT:
                    186:                        this->curve_name = "secp256r1";
                    187:                        break;
                    188:                case ECP_384_BIT:
                    189:                        this->curve_name = "secp384r1";
                    190:                        break;
                    191:                case ECP_521_BIT:
                    192:                        this->curve_name = "secp521r1";
                    193:                        break;
                    194:                case ECP_256_BP:
                    195:                        this->curve_name = "brainpool256r1";
                    196:                        break;
                    197:                case ECP_384_BP:
                    198:                        this->curve_name = "brainpool384r1";
                    199:                        break;
                    200:                case ECP_512_BP:
                    201:                        this->curve_name = "brainpool512r1";
                    202:                        break;
                    203:                default:
                    204:                        free(this);
                    205:                        return NULL;
                    206:        }
                    207: 
                    208:        if (botan_rng_init(&rng, "user"))
                    209:        {
                    210:                free(this);
                    211:                return NULL;
                    212:        }
                    213: 
                    214:        if (botan_privkey_create(&this->key, "ECDH", this->curve_name, rng))
                    215:        {
                    216:                DBG1(DBG_LIB, "ECDH private key generation failed");
                    217:                botan_rng_destroy(rng);
                    218:                free(this);
                    219:                return NULL;
                    220:        }
                    221: 
                    222:        botan_rng_destroy(rng);
                    223:        return &this->public;
                    224: }
                    225: 
                    226: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>