Return to wolfssl_rng.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / wolfssl |
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 */