Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
                      3:  *
                      4:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      5:  * of this software and associated documentation files (the "Software"), to deal
                      6:  * in the Software without restriction, including without limitation the rights
                      7:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                      8:  * copies of the Software, and to permit persons to whom the Software is
                      9:  * furnished to do so, subject to the following conditions:
                     10:  *
                     11:  * The above copyright notice and this permission notice shall be included in
                     12:  * all copies or substantial portions of the Software.
                     13:  *
                     14:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     15:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     17:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     18:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     19:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     20:  * THE SOFTWARE.
                     21:  */
                     22: 
                     23: #include "wolfssl_common.h"
                     24: 
                     25: #ifdef HAVE_CURVE25519
                     26: 
                     27: #include "wolfssl_x_diffie_hellman.h"
                     28: 
                     29: #include <utils/debug.h>
                     30: 
                     31: #include <wolfssl/wolfcrypt/curve25519.h>
                     32: #include <wolfssl/wolfcrypt/fe_operations.h>
                     33: 
                     34: typedef struct private_diffie_hellman_t private_diffie_hellman_t;
                     35: 
                     36: /**
                     37:  * Private data
                     38:  */
                     39: struct private_diffie_hellman_t {
                     40:        /**
                     41:         * Public interface.
                     42:         */
                     43:        diffie_hellman_t public;
                     44: 
                     45:        /**
                     46:         * Diffie Hellman group number.
                     47:         */
                     48:        diffie_hellman_group_t group;
                     49: 
                     50:        /**
                     51:         * Private (public) key
                     52:         */
                     53:        curve25519_key key;
                     54: 
                     55:        /**
                     56:         * Shared secret
                     57:         */
                     58:        chunk_t shared_secret;
                     59: };
                     60: 
                     61: /**
                     62:  * Compute the shared secret
                     63:  */
                     64: static bool compute_shared_key(private_diffie_hellman_t *this,
                     65:                                                           curve25519_key *pub, chunk_t *shared_secret)
                     66: {
                     67:        word32 len = CURVE25519_KEYSIZE;
                     68:        int ret;
                     69: 
                     70:        *shared_secret = chunk_alloc(len);
                     71:        ret = wc_curve25519_shared_secret_ex(&this->key, pub, shared_secret->ptr,
                     72:                                                                                 &len, EC25519_LITTLE_ENDIAN);
                     73:        return ret == 0;
                     74: }
                     75: 
                     76: METHOD(diffie_hellman_t, set_other_public_value, bool,
                     77:        private_diffie_hellman_t *this, chunk_t value)
                     78: {
                     79:        curve25519_key pub;
                     80:        int ret;
                     81: 
                     82:        if (!diffie_hellman_verify_value(this->group, value))
                     83:        {
                     84:                return FALSE;
                     85:        }
                     86: 
                     87:        ret = wc_curve25519_init(&pub);
                     88:        if (ret != 0)
                     89:        {
                     90:                DBG1(DBG_LIB, "%N public key initialization failed",
                     91:                         diffie_hellman_group_names, this->group);
                     92:                return FALSE;
                     93:        }
                     94: 
                     95:        ret = wc_curve25519_import_public_ex(value.ptr, value.len, &pub,
                     96:                                                                                 EC25519_LITTLE_ENDIAN);
                     97:        if (ret != 0)
                     98:        {
                     99:                DBG1(DBG_LIB, "%N public value is malformed",
                    100:                         diffie_hellman_group_names, this->group);
                    101:                return FALSE;
                    102:        }
                    103: 
                    104:        chunk_clear(&this->shared_secret);
                    105: 
                    106:        if (!compute_shared_key(this, &pub, &this->shared_secret))
                    107:        {
                    108:                DBG1(DBG_LIB, "%N shared secret computation failed",
                    109:                         diffie_hellman_group_names, this->group);
                    110:                chunk_clear(&this->shared_secret);
                    111:                wc_curve25519_free(&pub);
                    112:                return FALSE;
                    113:        }
                    114:        wc_curve25519_free(&pub);
                    115:        return TRUE;
                    116: }
                    117: 
                    118: METHOD(diffie_hellman_t, get_my_public_value, bool,
                    119:        private_diffie_hellman_t *this, chunk_t *value)
                    120: {
                    121:        word32 len = CURVE25519_KEYSIZE;
                    122: 
                    123:        *value = chunk_alloc(len);
                    124:        if (wc_curve25519_export_public_ex(&this->key, value->ptr, &len,
                    125:                                                                           EC25519_LITTLE_ENDIAN) != 0)
                    126:        {
                    127:                chunk_free(value);
                    128:                return FALSE;
                    129:        }
                    130:        return TRUE;
                    131: }
                    132: 
                    133: METHOD(diffie_hellman_t, set_private_value, bool,
                    134:        private_diffie_hellman_t *this, chunk_t value)
                    135: {
                    136:        curve25519_key pub;
                    137:        u_char basepoint[CURVE25519_KEYSIZE] = {9};
                    138:        word32 len = CURVE25519_KEYSIZE;
                    139:        int ret;
                    140: 
                    141:        ret = wc_curve25519_init(&pub);
                    142:        /* create base point for calculating public key */
                    143:        if (ret == 0)
                    144:        {
                    145:                ret = wc_curve25519_import_public_ex(basepoint, CURVE25519_KEYSIZE,
                    146:                                                                                         &pub, EC25519_LITTLE_ENDIAN);
                    147:        }
                    148:        if (ret == 0)
                    149:        {
                    150:                ret = wc_curve25519_import_private_ex(value.ptr, value.len, &this->key,
                    151:                                                                                          EC25519_LITTLE_ENDIAN);
                    152:        }
                    153:        if (ret == 0)
                    154:        {
                    155:                ret = wc_curve25519_shared_secret_ex(&this->key, &pub,
                    156:                                                                this->key.p.point, &len, EC25519_LITTLE_ENDIAN);
                    157:        }
                    158:        return ret == 0;
                    159: }
                    160: 
                    161: METHOD(diffie_hellman_t, get_shared_secret, bool,
                    162:        private_diffie_hellman_t *this, chunk_t *secret)
                    163: {
                    164:        if (!this->shared_secret.len)
                    165:        {
                    166:                return FALSE;
                    167:        }
                    168:        *secret = chunk_clone(this->shared_secret);
                    169:        return TRUE;
                    170: }
                    171: 
                    172: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
                    173:        private_diffie_hellman_t *this)
                    174: {
                    175:        return this->group;
                    176: }
                    177: 
                    178: METHOD(diffie_hellman_t, destroy, void,
                    179:        private_diffie_hellman_t *this)
                    180: {
                    181:        wc_curve25519_free(&this->key);
                    182:        chunk_clear(&this->shared_secret);
                    183:        free(this);
                    184: }
                    185: 
                    186: /*
                    187:  * Described in header
                    188:  */
                    189: diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group)
                    190: {
                    191:        private_diffie_hellman_t *this;
                    192:        WC_RNG rng;
                    193:        int ret;
                    194: 
                    195:        INIT(this,
                    196:                .public = {
                    197:                        .get_shared_secret = _get_shared_secret,
                    198:                        .set_other_public_value = _set_other_public_value,
                    199:                        .get_my_public_value = _get_my_public_value,
                    200:                        .set_private_value = _set_private_value,
                    201:                        .get_dh_group = _get_dh_group,
                    202:                        .destroy = _destroy,
                    203:                },
                    204:                .group = group,
                    205:        );
                    206: 
                    207:        if (wc_curve25519_init(&this->key) != 0)
                    208:        {
                    209:                DBG1(DBG_LIB, "initializing key failed");
                    210:                free(this);
                    211:                return NULL;
                    212:        }
                    213: 
                    214:        if (wc_InitRng(&rng) != 0)
                    215:        {
                    216:                DBG1(DBG_LIB, "initializing a random number generator failed");
                    217:                destroy(this);
                    218:                return NULL;
                    219:        }
                    220:        ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &this->key);
                    221:        wc_FreeRng(&rng);
                    222:        if (ret != 0)
                    223:        {
                    224:                DBG1(DBG_LIB, "making a key failed");
                    225:                destroy(this);
                    226:                return NULL;
                    227:        }
                    228:        return &this->public;
                    229: }
                    230: 
                    231: #endif /* HAVE_CURVE25519 */

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