Annotation of embedaddon/strongswan/src/libstrongswan/plugins/botan/botan_diffie_hellman.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2018 RenĂ© Korthaus
        !             3:  * Copyright (C) 2018 Konstantinos Kolelis
        !             4:  * Rohde & Schwarz Cybersecurity GmbH
        !             5:  *
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             7:  * of this software and associated documentation files (the "Software"), to deal
        !             8:  * in the Software without restriction, including without limitation the rights
        !             9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            10:  * copies of the Software, and to permit persons to whom the Software is
        !            11:  * furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included in
        !            14:  * all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        !            19:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            22:  * THE SOFTWARE.
        !            23:  */
        !            24: 
        !            25: #include "botan_diffie_hellman.h"
        !            26: 
        !            27: #include <botan/build.h>
        !            28: 
        !            29: #ifdef BOTAN_HAS_DIFFIE_HELLMAN
        !            30: 
        !            31: #include "botan_util.h"
        !            32: 
        !            33: #include <botan/ffi.h>
        !            34: 
        !            35: #include <utils/debug.h>
        !            36: 
        !            37: typedef struct private_botan_diffie_hellman_t private_botan_diffie_hellman_t;
        !            38: 
        !            39: /**
        !            40:  * Private data of an botan_diffie_hellman_t object.
        !            41:  */
        !            42: struct private_botan_diffie_hellman_t {
        !            43: 
        !            44:        /**
        !            45:         * Public botan_diffie_hellman_t interface
        !            46:         */
        !            47:        botan_diffie_hellman_t public;
        !            48: 
        !            49:        /**
        !            50:         * Diffie Hellman group number
        !            51:         */
        !            52:        diffie_hellman_group_t group;
        !            53: 
        !            54:        /**
        !            55:         * Private key
        !            56:         */
        !            57:        botan_privkey_t dh_key;
        !            58: 
        !            59:        /**
        !            60:         * Diffie hellman shared secret
        !            61:         */
        !            62:        chunk_t shared_secret;
        !            63: 
        !            64:        /**
        !            65:         * Generator value
        !            66:         */
        !            67:        botan_mp_t g;
        !            68: 
        !            69:        /**
        !            70:         * Modulus
        !            71:         */
        !            72:        botan_mp_t p;
        !            73: };
        !            74: 
        !            75: /**
        !            76:  * Load a DH private key
        !            77:  */
        !            78: bool load_private_key(private_botan_diffie_hellman_t *this, chunk_t value)
        !            79: {
        !            80:        botan_mp_t xa;
        !            81: 
        !            82:        if (!chunk_to_botan_mp(value, &xa))
        !            83:        {
        !            84:                return FALSE;
        !            85:        }
        !            86: 
        !            87:        if (botan_privkey_destroy(this->dh_key) ||
        !            88:                botan_privkey_load_dh(&this->dh_key, this->p, this->g, xa))
        !            89:        {
        !            90:                botan_mp_destroy(xa);
        !            91:                return FALSE;
        !            92:        }
        !            93:        botan_mp_destroy(xa);
        !            94:        return TRUE;
        !            95: }
        !            96: 
        !            97: METHOD(diffie_hellman_t, set_other_public_value, bool,
        !            98:        private_botan_diffie_hellman_t *this, chunk_t value)
        !            99: {
        !           100:        if (!diffie_hellman_verify_value(this->group, value))
        !           101:        {
        !           102:                return FALSE;
        !           103:        }
        !           104: 
        !           105:        chunk_clear(&this->shared_secret);
        !           106: 
        !           107:        return botan_dh_key_derivation(this->dh_key, value, &this->shared_secret);
        !           108: }
        !           109: 
        !           110: METHOD(diffie_hellman_t, get_my_public_value, bool,
        !           111:        private_botan_diffie_hellman_t *this, chunk_t *value)
        !           112: {
        !           113:        *value = chunk_empty;
        !           114: 
        !           115:        /* get key size of public key first */
        !           116:        if (botan_pk_op_key_agreement_export_public(this->dh_key, NULL, &value->len)
        !           117:                != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
        !           118:        {
        !           119:                return FALSE;
        !           120:        }
        !           121: 
        !           122:        *value = chunk_alloc(value->len);
        !           123:        if (botan_pk_op_key_agreement_export_public(this->dh_key, value->ptr,
        !           124:                                                                                                &value->len))
        !           125:        {
        !           126:                chunk_clear(value);
        !           127:                return FALSE;
        !           128:        }
        !           129:        return TRUE;
        !           130: }
        !           131: 
        !           132: METHOD(diffie_hellman_t, set_private_value, bool,
        !           133:        private_botan_diffie_hellman_t *this, chunk_t value)
        !           134: {
        !           135:        chunk_clear(&this->shared_secret);
        !           136:        return load_private_key(this, value);
        !           137: }
        !           138: 
        !           139: METHOD(diffie_hellman_t, get_shared_secret, bool,
        !           140:        private_botan_diffie_hellman_t *this, chunk_t *secret)
        !           141: {
        !           142:        if (!this->shared_secret.len)
        !           143:        {
        !           144:                return FALSE;
        !           145:        }
        !           146:        *secret = chunk_clone(this->shared_secret);
        !           147:        return TRUE;
        !           148: }
        !           149: 
        !           150: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
        !           151:        private_botan_diffie_hellman_t *this)
        !           152: {
        !           153:        return this->group;
        !           154: }
        !           155: 
        !           156: METHOD(diffie_hellman_t, destroy, void,
        !           157:        private_botan_diffie_hellman_t *this)
        !           158: {
        !           159:        botan_mp_destroy(this->p);
        !           160:        botan_mp_destroy(this->g);
        !           161:        botan_privkey_destroy(this->dh_key);
        !           162:        chunk_clear(&this->shared_secret);
        !           163:        free(this);
        !           164: }
        !           165: 
        !           166: /*
        !           167:  * Generic internal constructor
        !           168:  */
        !           169: static botan_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
        !           170:                                                                                chunk_t g, chunk_t p, size_t exp_len)
        !           171: {
        !           172:        private_botan_diffie_hellman_t *this;
        !           173:        chunk_t random;
        !           174:        rng_t *rng;
        !           175: 
        !           176:        INIT(this,
        !           177:                .public = {
        !           178:                        .dh = {
        !           179:                                .get_shared_secret = _get_shared_secret,
        !           180:                                .set_other_public_value = _set_other_public_value,
        !           181:                                .get_my_public_value = _get_my_public_value,
        !           182:                                .set_private_value = _set_private_value,
        !           183:                                .get_dh_group = _get_dh_group,
        !           184:                                .destroy = _destroy,
        !           185:                        },
        !           186:                },
        !           187:                .group = group,
        !           188:        );
        !           189: 
        !           190:        if (!chunk_to_botan_mp(p, &this->p))
        !           191:        {
        !           192:                destroy(this);
        !           193:                return NULL;
        !           194:        }
        !           195: 
        !           196:        if (!chunk_to_botan_mp(g, &this->g))
        !           197:        {
        !           198:                destroy(this);
        !           199:                return NULL;
        !           200:        }
        !           201: 
        !           202:        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
        !           203:        if (!rng || !rng->allocate_bytes(rng, exp_len, &random))
        !           204:        {
        !           205:                DESTROY_IF(rng);
        !           206:                destroy(this);
        !           207:                return NULL;
        !           208:        }
        !           209:        rng->destroy(rng);
        !           210: 
        !           211:        if (!load_private_key(this, random))
        !           212:        {
        !           213:                chunk_clear(&random);
        !           214:                destroy(this);
        !           215:                return NULL;
        !           216:        }
        !           217:        chunk_clear(&random);
        !           218:        return &this->public;
        !           219: }
        !           220: 
        !           221: /*
        !           222:  * Described in header.
        !           223:  */
        !           224: botan_diffie_hellman_t *botan_diffie_hellman_create(
        !           225:                                                                                        diffie_hellman_group_t group, ...)
        !           226: {
        !           227:        diffie_hellman_params_t *params;
        !           228:        chunk_t g, p;
        !           229: 
        !           230:        if (group == MODP_CUSTOM)
        !           231:        {
        !           232:                VA_ARGS_GET(group, g, p);
        !           233:                return create_generic(group, g, p, p.len);
        !           234:        }
        !           235: 
        !           236:        params = diffie_hellman_get_params(group);
        !           237:        if (!params)
        !           238:        {
        !           239:                return NULL;
        !           240:        }
        !           241:        return create_generic(group, params->generator, params->prime,
        !           242:                                                  params->exp_len);
        !           243: }
        !           244: 
        !           245: #endif

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