Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_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: #ifndef NO_DH
                     26: 
                     27: #include <wolfssl/wolfcrypt/dh.h>
                     28: 
                     29: #include "wolfssl_diffie_hellman.h"
                     30: #include "wolfssl_util.h"
                     31: 
                     32: #include <utils/debug.h>
                     33: 
                     34: typedef struct private_wolfssl_diffie_hellman_t private_wolfssl_diffie_hellman_t;
                     35: 
                     36: /**
                     37:  * Private data of an wolfssl_diffie_hellman_t object.
                     38:  */
                     39: struct private_wolfssl_diffie_hellman_t {
                     40: 
                     41:        /**
                     42:         * Public wolfssl_diffie_hellman_t interface.
                     43:         */
                     44:        wolfssl_diffie_hellman_t public;
                     45: 
                     46:        /**
                     47:         * Diffie Hellman group number.
                     48:         */
                     49:        diffie_hellman_group_t group;
                     50: 
                     51:        /**
                     52:         * Diffie Hellman object
                     53:         */
                     54:        DhKey dh;
                     55: 
                     56:        /**
                     57:         * Length of public values
                     58:         */
                     59:        int len;
                     60: 
                     61:        /**
                     62:         * Private key
                     63:         */
                     64:        chunk_t priv;
                     65: 
                     66:        /**
                     67:         * Public key
                     68:         */
                     69:        chunk_t pub;
                     70: 
                     71:        /**
                     72:         * Shared secret
                     73:         */
                     74:        chunk_t shared_secret;
                     75: };
                     76: 
                     77: METHOD(diffie_hellman_t, get_my_public_value, bool,
                     78:        private_wolfssl_diffie_hellman_t *this, chunk_t *value)
                     79: {
                     80:        *value = chunk_copy_pad(chunk_alloc(this->len), this->pub, 0x00);
                     81:        return TRUE;
                     82: }
                     83: 
                     84: METHOD(diffie_hellman_t, get_shared_secret, bool,
                     85:        private_wolfssl_diffie_hellman_t *this, chunk_t *secret)
                     86: {
                     87:        if (!this->shared_secret.len)
                     88:        {
                     89:                return FALSE;
                     90:        }
                     91:        *secret = chunk_copy_pad(chunk_alloc(this->len), this->shared_secret, 0x00);
                     92:        return TRUE;
                     93: }
                     94: 
                     95: METHOD(diffie_hellman_t, set_other_public_value, bool,
                     96:        private_wolfssl_diffie_hellman_t *this, chunk_t value)
                     97: {
                     98:        word32 len;
                     99: 
                    100:        if (!diffie_hellman_verify_value(this->group, value))
                    101:        {
                    102:                return FALSE;
                    103:        }
                    104: 
                    105:        chunk_clear(&this->shared_secret);
                    106:        this->shared_secret = chunk_alloc(this->len);
                    107:        if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr,
                    108:                                   this->priv.len, value.ptr, value.len) != 0)
                    109:        {
                    110:                DBG1(DBG_LIB, "DH shared secret computation failed");
                    111:                chunk_free(&this->shared_secret);
                    112:                return FALSE;
                    113:        }
                    114:        this->shared_secret.len = len;
                    115:        return TRUE;
                    116: }
                    117: 
                    118: METHOD(diffie_hellman_t, set_private_value, bool,
                    119:        private_wolfssl_diffie_hellman_t *this, chunk_t value)
                    120: {
                    121:        bool success = FALSE;
                    122:        chunk_t g;
                    123:        word32 len;
                    124: 
                    125:        chunk_clear(&this->priv);
                    126:        this->priv = chunk_clone(value);
                    127: 
                    128:        /* calculate public value - g^priv mod p */
                    129:        if (wolfssl_mp2chunk(&this->dh.g, &g))
                    130:        {
                    131:                len = this->pub.len;
                    132:                if (wc_DhAgree(&this->dh, this->pub.ptr, &len, this->priv.ptr,
                    133:                                                 this->priv.len, g.ptr, g.len) == 0)
                    134:                {
                    135:                        this->pub.len = len;
                    136:                        success = TRUE;
                    137:                }
                    138:        }
                    139: 
                    140:        free(g.ptr);
                    141:        return success;
                    142: }
                    143: 
                    144: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
                    145:        private_wolfssl_diffie_hellman_t *this)
                    146: {
                    147:        return this->group;
                    148: }
                    149: 
                    150: METHOD(diffie_hellman_t, destroy, void,
                    151:        private_wolfssl_diffie_hellman_t *this)
                    152: {
                    153:        wc_FreeDhKey(&this->dh);
                    154:        chunk_clear(&this->pub);
                    155:        chunk_clear(&this->priv);
                    156:        chunk_clear(&this->shared_secret);
                    157:        free(this);
                    158: }
                    159: 
                    160: /**
                    161:  * Maximum private key length when generating key
                    162:  */
                    163: static int wolfssl_priv_key_size(int len)
                    164: {
                    165:        if (len <= 128)
                    166:        {
                    167:                return 21;
                    168:        }
                    169:        if (len <= 256)
                    170:        {
                    171:                return 29;
                    172:        }
                    173:        if (len <= 384)
                    174:        {
                    175:                return 34;
                    176:        }
                    177:        if (len <= 512)
                    178:        {
                    179:                return 39;
                    180:        }
                    181:        if (len <= 640)
                    182:        {
                    183:                return 42;
                    184:        }
                    185:        if (len <= 768)
                    186:        {
                    187:                return 46;
                    188:        }
                    189:        if (len <= 896)
                    190:        {
                    191:                return 49;
                    192:        }
                    193:        if (len <= 1024)
                    194:        {
                    195:                return 52;
                    196:        }
                    197:        return len / 20;
                    198: }
                    199: 
                    200: /**
                    201:  * Generic internal constructor
                    202:  */
                    203: static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
                    204:                                                                                                chunk_t g, chunk_t p)
                    205: {
                    206:        private_wolfssl_diffie_hellman_t *this;
                    207:        word32 privLen, pubLen;
                    208:        WC_RNG rng;
                    209: 
                    210:        INIT(this,
                    211:                .public = {
                    212:                        .dh = {
                    213:                                .get_shared_secret = _get_shared_secret,
                    214:                                .set_other_public_value = _set_other_public_value,
                    215:                                .get_my_public_value = _get_my_public_value,
                    216:                                .set_private_value = _set_private_value,
                    217:                                .get_dh_group = _get_dh_group,
                    218:                                .destroy = _destroy,
                    219:                        },
                    220:                },
                    221:                .group = group,
                    222:                .len = p.len,
                    223:        );
                    224: 
                    225:        if (wc_InitDhKey(&this->dh) != 0)
                    226:        {
                    227:                free(this);
                    228:                return NULL;
                    229:        }
                    230: 
                    231:        if (wc_DhSetKey(&this->dh, p.ptr, p.len, g.ptr, g.len) != 0)
                    232:        {
                    233:                destroy(this);
                    234:                return NULL;
                    235:        }
                    236: 
                    237:        if (wc_InitRng(&rng) != 0)
                    238:        {
                    239:                destroy(this);
                    240:                return NULL;
                    241:        }
                    242: 
                    243:        this->priv = chunk_alloc(wolfssl_priv_key_size(this->len));
                    244:        this->pub = chunk_alloc(this->len);
                    245:        privLen = this->priv.len;
                    246:        pubLen = this->pub.len;
                    247:        /* generate my public and private values */
                    248:        if (wc_DhGenerateKeyPair(&this->dh, &rng, this->priv.ptr, &privLen,
                    249:                                                         this->pub.ptr, &pubLen) != 0)
                    250:        {
                    251:                wc_FreeRng(&rng);
                    252:                destroy(this);
                    253:                return NULL;
                    254:        }
                    255:        this->pub.len = pubLen;
                    256:        this->priv.len = privLen;
                    257:        wc_FreeRng(&rng);
                    258: 
                    259:        return &this->public;
                    260: }
                    261: 
                    262: /*
                    263:  * Described in header
                    264:  */
                    265: wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create(
                    266:                                                                                        diffie_hellman_group_t group, ...)
                    267: {
                    268:        diffie_hellman_params_t *params;
                    269:        chunk_t g, p;
                    270: 
                    271:        if (group == MODP_CUSTOM)
                    272:        {
                    273:                VA_ARGS_GET(group, g, p);
                    274:                return create_generic(group, g, p);
                    275:        }
                    276:        params = diffie_hellman_get_params(group);
                    277:        if (!params)
                    278:        {
                    279:                return NULL;
                    280:        }
                    281:        /* wolfSSL doesn't support optimized exponent sizes according to RFC 3526 */
                    282:        return create_generic(group, params->generator, params->prime);
                    283: }
                    284: 
                    285: #endif /* NO_DH */

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