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>