Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_rng.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 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>