Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c, revision 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>