File Coverage

inc/matrixssl-3-9-3-open/crypto/prng/prng.c
Criterion Covered Total %
statement 19 22 86.3
branch 2 4 50.0
condition n/a
subroutine n/a
pod n/a
total 21 26 80.7


line stmt bran cond sub pod time code
1             /**
2             * @file prng.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * Psuedo random number generation.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37             #ifdef USE_MATRIX_PRNG
38              
39             # ifdef USE_MULTITHREADING
40             static psMutex_t prngLock;
41             # endif
42              
43             static psRandom_t gMatrixPrng;
44             static short gPrngInit = 0;
45              
46             /******************************************************************************/
47             /* One-time global prng lock creation and prng context */
48 17           void psOpenPrng(void)
49             {
50             # ifdef USE_MULTITHREADING
51             psCreateMutex(&prngLock, 0);
52             # endif
53             /* NOTE: if a PRNG is enabled, the low level psGetEntropy call can't
54             have a useful userPtr context becuase there will be no session
55             context at this early stage */
56 17           psInitPrng(&gMatrixPrng, NULL);
57 17           gPrngInit = 1;
58 17           return;
59             }
60              
61             /******************************************************************************/
62             /* One-time global prng lock destruction */
63 14           void psClosePrng(void)
64             {
65             # ifdef USE_MULTITHREADING
66             psDestroyMutex(&prngLock);
67             # endif
68 14           return;
69             }
70              
71             /******************************************************************************/
72             /*
73             Main PRNG retrieval API for Matrix based apps to lock all PRNG and entropy
74             fetches
75             */
76 15662           int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size, void *userPtr)
77             {
78             int32_t rc;
79              
80 15662 50         if (gPrngInit == 0)
81             {
82 0           return PS_FAILURE;
83             }
84             # ifdef USE_MULTITHREADING
85             psLockMutex(&prngLock);
86             # endif /* USE_MULTITHREADING */
87 15662           rc = psGetPrng(&gMatrixPrng, bytes, size, userPtr);
88             # ifdef USE_MULTITHREADING
89             psUnlockMutex(&prngLock);
90             # endif /* USE_MULTITHREADING */
91 15662           return rc;
92             }
93              
94             /******************************************************************************/
95             /*
96             Priority order of PRNG algorithms and then default GetEntropy if none.
97             Does an initial entropy source and reseeding
98             */
99 17           int32_t psInitPrng(psRandom_t *ctx, void *userPtr)
100             {
101             # if defined(USE_FORTUNA) || defined(USE_YARROW)
102             unsigned char entropyBytes[RANDOM_ENTROPY_BYTES];
103             int32 rc;
104             # endif
105              
106 17           ctx->bytecount = 0;
107              
108             # if defined(USE_FORTUNA) || defined(USE_YARROW)
109             if ((rc = psGetEntropy(entropyBytes, RANDOM_ENTROPY_BYTES, userPtr)) < 0)
110             {
111             return rc;
112             }
113             # endif
114              
115             # ifdef USE_YARROW
116             if ((rc = psYarrowStart(&ctx->yarrow)) < 0)
117             {
118             return rc;
119             }
120             if ((rc = psYarrowAddEntropy(entropyBytes, RANDOM_ENTROPY_BYTES,
121             &ctx->yarrow)) < 0)
122             {
123             return rc;
124             }
125             if ((rc = psYarrowReseed(&ctx->yarrow)) < 0)
126             {
127             return rc;
128             }
129             # endif
130 17           return PS_SUCCESS;
131             }
132              
133             /******************************************************************************/
134             /*
135             Performs the read
136             */
137 15662           static int32_t readRandomData(psRandom_t *ctx, unsigned char *bytes, psSize_t size,
138             void *userPtr)
139             {
140             # if defined(USE_FORTUNA) || defined(USE_YARROW)
141             unsigned char entropyBytes[RANDOM_ENTROPY_BYTES];
142             int32 rc;
143             # endif
144             /*
145             Return random data. The defines above control how often to add
146             entropy and reseed the key.
147             */
148 15662           ctx->bytecount += size;
149              
150              
151             # ifdef USE_YARROW
152             if (ctx->bytecount >= RANDOM_BYTES_BEFORE_ENTROPY)
153             {
154             ctx->bytecount = 0;
155             if ((rc = psGetEntropy(entropyBytes, RANDOM_ENTROPY_BYTES, userPtr))
156             < 0)
157             {
158             return rc;
159             }
160             if ((rc = psYarrowAddEntropy(entropyBytes, RANDOM_ENTROPY_BYTES,
161             &ctx->yarrow)) < 0)
162             {
163             return rc;
164             }
165             if ((rc = psYarrowReseed(&ctx->yarrow)) < 0)
166             {
167             return rc;
168             }
169             }
170             return psYarrowRead(bytes, size, &ctx->yarrow);
171             # endif
172             /*
173             If no PRNG algorithms defined, default to the low level GetEntropy function
174             for all the randomness
175             */
176 15662           return psGetEntropy(bytes, size, userPtr);
177             }
178              
179             /******************************************************************************/
180             /*
181             Allow NULL context if caller is just doing a single read
182             */
183 15662           int32_t psGetPrng(psRandom_t *ctx, unsigned char *bytes, psSize_t size,
184             void *userPtr)
185             {
186             psRandom_t lctx;
187              
188 15662 50         if (ctx == NULL)
189             {
190 0           psInitPrng(&lctx, userPtr);
191 0           return readRandomData(&lctx, bytes, size, userPtr);
192             }
193 15662           return readRandomData(ctx, bytes, size, userPtr);
194             }
195              
196             #endif /* USE_MATRIX_PRNG */
197              
198             /******************************************************************************/
199