Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_rng.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 WC_NO_RNG
        !            26: 
        !            27: #include <library.h>
        !            28: #include <utils/debug.h>
        !            29: 
        !            30: #include <wolfssl/wolfcrypt/random.h>
        !            31: 
        !            32: #include "wolfssl_rng.h"
        !            33: 
        !            34: typedef struct private_wolfssl_rng_t private_wolfssl_rng_t;
        !            35: 
        !            36: #ifndef SINGLE_THREADED
        !            37: wolfSSL_Mutex globalRngMutex;
        !            38: #endif
        !            39: static WC_RNG globalRng;
        !            40: static bool globalRngInit;
        !            41: 
        !            42: /**
        !            43:  * Private data of wolfssl_rng_t
        !            44:  */
        !            45: struct private_wolfssl_rng_t {
        !            46: 
        !            47:        /**
        !            48:         * Public part of this class.
        !            49:         */
        !            50:        wolfssl_rng_t public;
        !            51: 
        !            52:        /**
        !            53:         * Random number generator to use
        !            54:         * Either own instance or reference to global.
        !            55:         */
        !            56:        WC_RNG *rng;
        !            57: };
        !            58: 
        !            59: METHOD(rng_t, get_bytes, bool,
        !            60:        private_wolfssl_rng_t *this, size_t bytes, uint8_t *buffer)
        !            61: {
        !            62:        int ret;
        !            63: 
        !            64: #ifndef SINGLE_THREADED
        !            65:        if (this->rng == &globalRng)
        !            66:        {
        !            67:                ret = wc_LockMutex(&globalRngMutex);
        !            68:                if (ret != 0)
        !            69:                {
        !            70:                        DBG1(DBG_LIB, "locking failed, get bytes failed");
        !            71:                        return FALSE;
        !            72:                }
        !            73:        }
        !            74: #endif
        !            75:        ret = wc_RNG_GenerateBlock(this->rng, buffer, bytes);
        !            76: #ifndef SINGLE_THREADED
        !            77:        if (this->rng == &globalRng)
        !            78:        {
        !            79:                wc_UnLockMutex(&globalRngMutex);
        !            80:        }
        !            81: #endif
        !            82: 
        !            83:        return ret == 0;
        !            84: }
        !            85: 
        !            86: METHOD(rng_t, allocate_bytes, bool,
        !            87:        private_wolfssl_rng_t *this, size_t bytes, chunk_t *chunk)
        !            88: {
        !            89:        *chunk = chunk_alloc(bytes);
        !            90:        if (!get_bytes(this, chunk->len, chunk->ptr))
        !            91:        {
        !            92:                chunk_free(chunk);
        !            93:                return FALSE;
        !            94:        }
        !            95:        return TRUE;
        !            96: }
        !            97: 
        !            98: METHOD(rng_t, destroy, void,
        !            99:        private_wolfssl_rng_t *this)
        !           100: {
        !           101:        if (this->rng != &globalRng)
        !           102:        {
        !           103:                wc_FreeRng(this->rng);
        !           104:                free(this->rng);
        !           105:        }
        !           106:        free(this);
        !           107: }
        !           108: 
        !           109: /*
        !           110:  * Described in header
        !           111:  */
        !           112: wolfssl_rng_t *wolfssl_rng_create(rng_quality_t quality)
        !           113: {
        !           114:        private_wolfssl_rng_t *this;
        !           115: 
        !           116:        INIT(this,
        !           117:                .public = {
        !           118:                        .rng = {
        !           119:                                .get_bytes = _get_bytes,
        !           120:                                .allocate_bytes = _allocate_bytes,
        !           121:                                .destroy = _destroy,
        !           122:                        },
        !           123:                },
        !           124:                .rng = &globalRng,
        !           125:        );
        !           126: 
        !           127:        if (quality > RNG_WEAK)
        !           128:        {
        !           129:                this->rng = malloc(sizeof(*this->rng));
        !           130:                if (wc_InitRng(this->rng) != 0)
        !           131:                {
        !           132:                        DBG1(DBG_LIB, "init RNG failed, rng create failed");
        !           133:                        free(this->rng);
        !           134:                        free(this);
        !           135:                        return NULL;
        !           136:                }
        !           137:        }
        !           138:        return &this->public;
        !           139: }
        !           140: 
        !           141: /*
        !           142:  * Described in header
        !           143:  */
        !           144: int wolfssl_rng_global_init()
        !           145: {
        !           146:        int ret = 0;
        !           147: 
        !           148:        if (!globalRngInit)
        !           149:        {
        !           150:                ret = wc_InitRng(&globalRng);
        !           151:                if (ret != 0)
        !           152:                {
        !           153:                        DBG1(DBG_LIB, "init RNG failed, rng global init failed");
        !           154:                }
        !           155: #ifndef SINGLE_THREADED
        !           156:                else if ((ret = wc_InitMutex(&globalRngMutex)) != 0)
        !           157:                {
        !           158:                        DBG1(DBG_LIB, "init Mutex failed, rng global init failed");
        !           159:                }
        !           160: #endif
        !           161:                else
        !           162:                {
        !           163:                        globalRngInit = TRUE;
        !           164:                }
        !           165:        }
        !           166:        return ret == 0;
        !           167: }
        !           168: 
        !           169: /*
        !           170:  * Described in header
        !           171:  */
        !           172: void wolfssl_rng_global_final()
        !           173: {
        !           174:        if (globalRngInit)
        !           175:        {
        !           176: #ifndef SINGLE_THREADED
        !           177:                wc_FreeMutex(&globalRngMutex);
        !           178: #endif
        !           179:                wc_FreeRng(&globalRng);
        !           180:                globalRngInit = FALSE;
        !           181:        }
        !           182: }
        !           183: 
        !           184: #endif /* WC_NO_RNG */

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