~ubuntu-branches/ubuntu/karmic/nss/karmic-updates

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/freebl/drbg.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2009-06-16 13:23:47 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090616132347-311ysb8oep74b98y
Tags: 3.12.3-0ubuntu1
* new upstream release 3.12.3 RTM (NSS_3_12_3_RTM) (LP: #387751)
* adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
* needs nspr >= 4.7.4
  - update debian/control
* update 85_security_load.patch to latest debian version
  - update debian/patches/85_security_load.patch
* add new symbols for 3.12.3
  - update debian/libnss3-1d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is the Network Security Services libraries.
 
15
 *
 
16
 * The Initial Developer of the Original Code is Red Hat, Inc.
 
17
 * Portions created by the Initial Developer are Copyright (C) 2009
 
18
 * the Initial Developer. All Rights Reserved.
 
19
 *
 
20
 * Portions created by Netscape Communications Corporation
 
21
 * are Copyright (C) 1994-2000 Netscape Communications Corporation.
 
22
 * All Rights Reserved.
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * Alternatively, the contents of this file may be used under the terms of
 
27
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
28
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
29
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
30
 * of those above. If you wish to allow use of your version of this file only
 
31
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
32
 * use your version of this file under the terms of the MPL, indicate your
 
33
 * decision by deleting the provisions above and replace them with the notice
 
34
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
35
 * the provisions above, a recipient may use your version of this file under
 
36
 * the terms of any one of the MPL, the GPL or the LGPL.
 
37
 *
 
38
 * ***** END LICENSE BLOCK ***** */
 
39
/* $Id: drbg.c,v 1.8 2009/04/01 03:37:29 wtc%google.com Exp $ */
 
40
 
 
41
#ifdef FREEBL_NO_DEPEND
 
42
#include "stubs.h"
 
43
#endif
 
44
 
 
45
#include "prerror.h"
 
46
#include "secerr.h"
 
47
 
 
48
#include "prtypes.h"
 
49
#include "prinit.h"
 
50
#include "blapi.h"
 
51
#include "blapii.h"
 
52
#include "nssilock.h"
 
53
#include "secitem.h"
 
54
#include "sha_fast.h"
 
55
#include "sha256.h"
 
56
#include "secrng.h"     /* for RNG_SystemRNG() */
 
57
#include "secmpi.h"
 
58
 
 
59
/* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1 
 
60
 * for SHA-1, SHA-224, and SHA-256 it's 440 bits.
 
61
 * for SHA-384 and SHA-512 it's 888 bits */
 
62
#define PRNG_SEEDLEN      (440/PR_BITS_PER_BYTE)
 
63
static const PRInt64 PRNG_MAX_ADDITIONAL_BYTES = LL_INIT(0x1, 0x0);
 
64
                                                /* 2^35 bits or 2^32 bytes */
 
65
#define PRNG_MAX_REQUEST_SIZE 0x10000           /* 2^19 bits or 2^16 bytes */
 
66
#define PRNG_ADDITONAL_DATA_CACHE_SIZE (8*1024) /* must be less than
 
67
                                                 *  PRNG_MAX_ADDITIONAL_BYTES
 
68
                                                 */
 
69
 
 
70
 
 
71
/* RESEED_COUNT is how many calls to the prng before we need to reseed 
 
72
 * under normal NIST rules, you must return an error. In the NSS case, we
 
73
 * self-reseed with RNG_SystemRNG(). Count can be a large number. For code
 
74
 * simplicity, we specify count with 2 components: RESEED_BYTE (which is 
 
75
 * the same as LOG256(RESEED_COUNT)) and RESEED_VALUE (which is the same as
 
76
 * RESEED_COUNT / (256 ^ RESEED_BYTE)). Another way to look at this is
 
77
 * RESEED_COUNT = RESEED_VALUE * (256 ^ RESEED_BYTE). For Hash based DRBG
 
78
 * we use the maximum count value, 2^48, or RESEED_BYTE=6 and RESEED_VALUE=1
 
79
 */
 
80
#define RESEED_BYTE 6
 
81
#define RESEED_VALUE 1
 
82
 
 
83
#define PRNG_RESET_RESEED_COUNT(rng) \
 
84
        PORT_Memset((rng)->reseed_counter, 0, sizeof (rng)->reseed_counter); \
 
85
        (rng)->reseed_counter[RESEED_BYTE] = 1;
 
86
 
 
87
 
 
88
/*
 
89
 * The actual values of this enum are specified in SP 800-90, 10.1.1.*
 
90
 * The spec does not name the types, it only uses bare values 
 
91
 */
 
92
typedef enum {
 
93
   prngCGenerateType = 0,       /* used when creating a new 'C' */
 
94
   prngReseedType = 1,          /* used in reseeding */
 
95
   prngAdditionalDataType = 2,  /* used in mixing additional data */
 
96
   prngGenerateByteType = 3     /* used when mixing internal state while
 
97
                                 * generating bytes */
 
98
} prngVTypes;
 
99
 
 
100
/*
 
101
 * Global RNG context
 
102
 */ 
 
103
struct RNGContextStr {
 
104
    PZLock   *lock;        /* Lock to serialize access to global rng */
 
105
    /*
 
106
     * NOTE, a number of steps in the drbg algorithm need to hash 
 
107
     * V_type || V. The code, therefore, depends on the V array following 
 
108
     * immediately after V_type to avoid extra copies. To accomplish this
 
109
     * in a way that compiliers can't perturb, we declare V_type and V
 
110
     * as a V_Data array and reference them by macros */
 
111
    PRUint8  V_Data[PRNG_SEEDLEN+1]; /* internal state variables */
 
112
#define  V_type  V_Data[0]
 
113
#define  V(rng)       (((rng)->V_Data)+1)
 
114
#define  VSize(rng)   ((sizeof (rng)->V_Data) -1)
 
115
    PRUint8  C[PRNG_SEEDLEN];        /* internal state variables */
 
116
    PRUint8  oldV[PRNG_SEEDLEN];     /* for continuous rng checking */
 
117
    /* If we get calls for the PRNG to return less than the length of our
 
118
     * hash, we extend the request for a full hash (since we'll be doing
 
119
     * the full hash anyway). Future requests for random numbers are fulfilled
 
120
     * from the remainder of the bytes we generated. Requests for bytes longer
 
121
     * than the hash size are fulfilled directly from the HashGen function
 
122
     * of the random number generator. */
 
123
    PRUint8  reseed_counter[RESEED_BYTE+1]; /* number of requests since the 
 
124
                                             * last reseed. Need only be
 
125
                                             * big enough to hold the whole
 
126
                                             * reseed count */
 
127
    PRUint8  data[SHA256_LENGTH];       /* when we request less than a block
 
128
                                         * save the rest of the rng output for 
 
129
                                         * another partial block */
 
130
    PRUint8  dataAvail;            /* # bytes of output available in our cache,
 
131
                                    * [0...SHA256_LENGTH] */
 
132
    /* store additional data that has been shovelled off to us by
 
133
     * RNG_RandomUpdate. */
 
134
    PRUint8  additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
 
135
    PRUint32 additionalAvail;
 
136
    PRBool   isValid;          /* false if RNG reaches an invalid state */
 
137
};
 
138
 
 
139
typedef struct RNGContextStr RNGContext;
 
140
static RNGContext *globalrng = NULL;
 
141
static RNGContext theGlobalRng;
 
142
 
 
143
 
 
144
/*
 
145
 * The next several functions are derived from the NIST SP 800-90
 
146
 * spec. In these functions, an attempt was made to use names consistent
 
147
 * with the names in the spec, even if they differ from normal NSS usage.
 
148
 */
 
149
 
 
150
/*
 
151
 * Hash Derive function defined in NISP SP 800-90 Section 10.4.1.
 
152
 * This function is used in the Instantiate and Reseed functions.
 
153
 * 
 
154
 * NOTE: requested_bytes cannot overlap with input_string_1 or input_string_2.
 
155
 * input_string_1 and input_string_2 are logically concatentated. 
 
156
 * input_string_1 must be supplied.
 
157
 * if input_string_2 is not supplied, NULL should be passed for this parameter.
 
158
 */
 
159
static SECStatus
 
160
prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return, 
 
161
        const PRUint8 *input_string_1, unsigned int input_string_1_len, 
 
162
        const PRUint8 *input_string_2, unsigned int input_string_2_len)
 
163
{
 
164
    SHA256Context ctx;
 
165
    PRUint32 tmp;
 
166
    PRUint8 counter;
 
167
 
 
168
    tmp=SHA_HTONL(no_of_bytes_to_return*8);
 
169
 
 
170
    for (counter = 1 ; no_of_bytes_to_return > 0; counter++) {
 
171
        unsigned int hash_return_len;
 
172
        SHA256_Begin(&ctx);
 
173
        SHA256_Update(&ctx, &counter, 1);
 
174
        SHA256_Update(&ctx, (unsigned char *)&tmp, sizeof tmp);
 
175
        SHA256_Update(&ctx, input_string_1, input_string_1_len);
 
176
        if (input_string_2) {
 
177
            SHA256_Update(&ctx, input_string_2, input_string_2_len);
 
178
        }
 
179
        SHA256_End(&ctx, requested_bytes, &hash_return_len,
 
180
                no_of_bytes_to_return);
 
181
        requested_bytes += hash_return_len;
 
182
        no_of_bytes_to_return -= hash_return_len;
 
183
    }
 
184
    return SECSuccess;
 
185
}
 
186
 
 
187
 
 
188
/*
 
189
 * Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2
 
190
 *
 
191
 * NOTE: bytes & len are entropy || nonce || personalization_string. In
 
192
 * normal operation, NSS calculates them all together in a single call.
 
193
 */
 
194
static SECStatus
 
195
prng_instantiate(RNGContext *rng, PRUint8 *bytes, unsigned int len)
 
196
{
 
197
    prng_Hash_df(V(rng), VSize(rng), bytes, len, NULL, 0);
 
198
    rng->V_type = prngCGenerateType;
 
199
    prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0);
 
200
    PRNG_RESET_RESEED_COUNT(rng)
 
201
    return SECSuccess;
 
202
}
 
203
    
 
204
 
 
205
/*
 
206
 * Update the global random number generator with more seeding
 
207
 * material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90
 
208
 * section 10.1.1.3
 
209
 *
 
210
 * If entropy is NULL, it is fetched from the noise generator.
 
211
 */
 
212
static
 
213
SECStatus
 
214
prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
 
215
        const PRUint8 *additional_input, unsigned int additional_input_len)
 
216
{
 
217
    PRUint8 noiseData[(sizeof rng->V_Data)+PRNG_SEEDLEN];
 
218
    PRUint8 *noise = &noiseData[0];
 
219
 
 
220
    /* if entropy wasn't supplied, fetch it. (normal operation case) */
 
221
    if (entropy == NULL) {
 
222
        entropy_len = (unsigned int) RNG_SystemRNG(
 
223
                        &noiseData[sizeof rng->V_Data], PRNG_SEEDLEN);
 
224
    } else {
 
225
        /* NOTE: this code is only available for testing, not to applications */
 
226
        /* if entropy was too big for the stack variable, get it from malloc */
 
227
        if (entropy_len > PRNG_SEEDLEN) {
 
228
            noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data));
 
229
            if (noise == NULL) {
 
230
                return SECFailure;
 
231
            }
 
232
        }
 
233
        PORT_Memcpy(&noise[sizeof rng->V_Data],entropy, entropy_len);
 
234
    }
 
235
 
 
236
    rng->V_type = prngReseedType;
 
237
    PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data);
 
238
    prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len,
 
239
                additional_input, additional_input_len);
 
240
    /* clear potential CSP */
 
241
    PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len); 
 
242
    rng->V_type = prngCGenerateType;
 
243
    prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0);
 
244
    PRNG_RESET_RESEED_COUNT(rng)
 
245
 
 
246
    if (noise != &noiseData[0]) {
 
247
        PORT_Free(noise);
 
248
    }
 
249
    return SECSuccess;
 
250
}
 
251
 
 
252
/*
 
253
 * build some fast inline functions for adding.
 
254
 */
 
255
#define PRNG_ADD_CARRY_ONLY(dest, start, cy) \
 
256
   carry = cy; \
 
257
   for (k1=start; carry && k1 >=0 ; k1--) { \
 
258
        carry = !(++dest[k1]); \
 
259
   } 
 
260
 
 
261
/*
 
262
 * NOTE: dest must be an array for the following to work.
 
263
 */
 
264
#define PRNG_ADD_BITS(dest, dest_len, add, len) \
 
265
    carry = 0; \
 
266
    for (k1=dest_len -1, k2=len-1; k2 >= 0; --k1, --k2) { \
 
267
        carry += dest[k1]+ add[k2]; \
 
268
        dest[k1] = (PRUint8) carry; \
 
269
        carry >>= 8; \
 
270
    }
 
271
 
 
272
#define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len) \
 
273
    PRNG_ADD_BITS(dest, dest_len, add, len) \
 
274
    PRNG_ADD_CARRY_ONLY(dest, k1, carry)
 
275
 
 
276
/*
 
277
 * This function expands the internal state of the prng to fulfill any number
 
278
 * of bytes we need for this request. We only use this call if we need more
 
279
 * than can be supplied by a single call to SHA256_HashBuf. 
 
280
 *
 
281
 * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen
 
282
 */
 
283
static void
 
284
prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes, 
 
285
             unsigned int no_of_returned_bytes)
 
286
{
 
287
    PRUint8 data[VSize(rng)];
 
288
 
 
289
    PORT_Memcpy(data, V(rng), VSize(rng));
 
290
    while (no_of_returned_bytes) {
 
291
        SHA256Context ctx;
 
292
        unsigned int len;
 
293
        unsigned int carry;
 
294
        int k1;
 
295
 
 
296
        SHA256_Begin(&ctx);
 
297
        SHA256_Update(&ctx, data, sizeof data);
 
298
        SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes);
 
299
        returned_bytes += len;
 
300
        no_of_returned_bytes -= len;
 
301
        /* The carry parameter is a bool (increment or not). 
 
302
         * This increments data if no_of_returned_bytes is not zero */
 
303
        PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, no_of_returned_bytes);
 
304
    }
 
305
    PORT_Memset(data, 0, sizeof data); 
 
306
}
 
307
 
 
308
/* 
 
309
 * Generates new random bytes and advances the internal prng state.     
 
310
 * additional bytes are only used in algorithm testing.
 
311
 * 
 
312
 * This function is specified in NIST SP 800-90 section 10.1.1.4
 
313
 */
 
314
static SECStatus
 
315
prng_generateNewBytes(RNGContext *rng, 
 
316
                PRUint8 *returned_bytes, unsigned int no_of_returned_bytes,
 
317
                const PRUint8 *additional_input,
 
318
                unsigned int additional_input_len)
 
319
{
 
320
    PRUint8 H[SHA256_LENGTH]; /* both H and w since they 
 
321
                               * aren't used concurrently */
 
322
    unsigned int carry;
 
323
    int k1, k2;
 
324
 
 
325
    if (!rng->isValid) {
 
326
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 
327
        return SECFailure;
 
328
    }
 
329
    /* This code only triggers during tests, normal
 
330
     * prng operation does not use additional_input */
 
331
    if (additional_input){
 
332
        SHA256Context ctx;
 
333
        /* NIST SP 800-90 defines two temporaries in their calculations,
 
334
         * w and H. These temporaries are the same lengths, and used
 
335
         * at different times, so we use the following macro to collapse
 
336
         * them to the same variable, but keeping their unique names for
 
337
         * easy comparison to the spec */
 
338
#define w H
 
339
        rng->V_type = prngAdditionalDataType;
 
340
        SHA256_Begin(&ctx);
 
341
        SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data);
 
342
        SHA256_Update(&ctx, additional_input, additional_input_len);
 
343
        SHA256_End(&ctx, w, NULL, sizeof w);
 
344
        PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w)
 
345
        PORT_Memset(w, 0, sizeof w);
 
346
#undef w 
 
347
    }
 
348
 
 
349
    if (no_of_returned_bytes == SHA256_LENGTH) {
 
350
        /* short_cut to hashbuf and save a copy and a clear */
 
351
        SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) );
 
352
    } else {
 
353
        prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
 
354
    }
 
355
    /* advance our internal state... */
 
356
    rng->V_type = prngGenerateByteType;
 
357
    SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
 
358
    PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H)
 
359
    PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C);
 
360
    PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter, 
 
361
                                        sizeof rng->reseed_counter)
 
362
    PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, 1);
 
363
 
 
364
    /* continuous rng check */
 
365
    if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) {
 
366
        rng->isValid = PR_FALSE;
 
367
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 
368
        return SECFailure;
 
369
    }
 
370
    PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV);
 
371
    return SECSuccess;
 
372
}
 
373
 
 
374
/* Use NSPR to prevent RNG_RNGInit from being called from separate
 
375
 * threads, creating a race condition.
 
376
 */
 
377
static const PRCallOnceType pristineCallOnce;
 
378
static PRCallOnceType coRNGInit;
 
379
static PRStatus rng_init(void)
 
380
{
 
381
    PRUint8 bytes[PRNG_SEEDLEN*2]; /* entropy + nonce */
 
382
    unsigned int numBytes;
 
383
    if (globalrng == NULL) {
 
384
        /* create a new global RNG context */
 
385
        globalrng = &theGlobalRng;
 
386
        PORT_Assert(NULL == globalrng->lock);
 
387
        /* create a lock for it */
 
388
        globalrng->lock = PZ_NewLock(nssILockOther);
 
389
        if (globalrng->lock == NULL) {
 
390
            globalrng = NULL;
 
391
            PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
 
392
            return PR_FAILURE;
 
393
        }
 
394
 
 
395
        /* Try to get some seed data for the RNG */
 
396
        numBytes = (unsigned int) RNG_SystemRNG(bytes, sizeof bytes);
 
397
        PORT_Assert(numBytes == 0 || numBytes == sizeof bytes);
 
398
        if (numBytes != 0) {
 
399
            /* if this is our first call,  instantiate, otherwise reseed 
 
400
             * prng_instantiate gets a new clean state, we want to mix
 
401
             * any previous entropy we may have collected */
 
402
            if (V(globalrng)[0] == 0) {
 
403
                prng_instantiate(globalrng, bytes, numBytes);
 
404
            } else {
 
405
                prng_reseed(globalrng, bytes, numBytes, NULL, 0);
 
406
            }
 
407
            memset(bytes, 0, numBytes);
 
408
        } else {
 
409
            PZ_DestroyLock(globalrng->lock);
 
410
            globalrng->lock = NULL;
 
411
            globalrng = NULL;
 
412
            return PR_FAILURE;
 
413
        }
 
414
        /* the RNG is in a valid state */
 
415
        globalrng->isValid = PR_TRUE;
 
416
 
 
417
        /* Fetch more entropy into the PRNG */
 
418
        RNG_SystemInfoForRNG();
 
419
    }
 
420
    return PR_SUCCESS;
 
421
}
 
422
 
 
423
/*
 
424
 * Clean up the global RNG context
 
425
 */
 
426
static void
 
427
prng_freeRNGContext(RNGContext *rng)
 
428
{
 
429
    PRUint8 inputhash[VSize(rng) + (sizeof rng->C)];
 
430
 
 
431
    /* destroy context lock */
 
432
    SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
 
433
 
 
434
    /* zero global RNG context except for C & V to preserve entropy */
 
435
    prng_Hash_df(inputhash, sizeof rng->C, rng->C, sizeof rng->C, NULL, 0); 
 
436
    prng_Hash_df(&inputhash[sizeof rng->C], VSize(rng), V(rng), VSize(rng), 
 
437
                                                                  NULL, 0); 
 
438
    memset(rng, 0, sizeof *rng);
 
439
    memcpy(rng->C, inputhash, sizeof rng->C); 
 
440
    memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng)); 
 
441
 
 
442
    memset(inputhash, 0, sizeof inputhash);
 
443
}
 
444
 
 
445
/*
 
446
 * Public functions
 
447
 */
 
448
 
 
449
/*
 
450
 * Initialize the global RNG context and give it some seed input taken
 
451
 * from the system.  This function is thread-safe and will only allow
 
452
 * the global context to be initialized once.  The seed input is likely
 
453
 * small, so it is imperative that RNG_RandomUpdate() be called with
 
454
 * additional seed data before the generator is used.  A good way to
 
455
 * provide the generator with additional entropy is to call
 
456
 * RNG_SystemInfoForRNG().  Note that C_Initialize() does exactly that.
 
457
 */
 
458
SECStatus 
 
459
RNG_RNGInit(void)
 
460
{
 
461
    /* Allow only one call to initialize the context */
 
462
    PR_CallOnce(&coRNGInit, rng_init);
 
463
    /* Make sure there is a context */
 
464
    return (globalrng != NULL) ? PR_SUCCESS : PR_FAILURE;
 
465
}
 
466
 
 
467
/*
 
468
** Update the global random number generator with more seeding
 
469
** material.
 
470
*/
 
471
SECStatus 
 
472
RNG_RandomUpdate(const void *data, size_t bytes)
 
473
{
 
474
    SECStatus rv;
 
475
 
 
476
    /* Make sure our assumption that size_t is unsigned is true */
 
477
    PR_STATIC_ASSERT(((size_t)-1) > (size_t)1);
 
478
 
 
479
#if defined(NS_PTR_GT_32) || (defined(NSS_USE_64) && !defined(NS_PTR_LE_32))
 
480
    /*
 
481
     * NIST 800-90 requires us to verify our inputs. This value can
 
482
     * come from the application, so we need to make sure it's within the
 
483
     * spec. The spec says it must be less than 2^32 bytes (2^35 bits).
 
484
     * This can only happen if size_t is greater than 32 bits (i.e. on
 
485
     * most 64 bit platforms). The 90% case (perhaps 100% case), size_t
 
486
     * is less than or equal to 32 bits if the platform is not 64 bits, and
 
487
     * greater than 32 bits if it is a 64 bit platform. The corner
 
488
     * cases are handled with explicit defines NS_PTR_GT_32 and NS_PTR_LE_32.
 
489
     *
 
490
     * In general, neither NS_PTR_GT_32 nor NS_PTR_LE_32 will need to be 
 
491
     * defined. If you trip over the next two size ASSERTS at compile time,
 
492
     * you will need to define them for your platform.
 
493
     *
 
494
     * if 'sizeof(size_t) > 4' is triggered it means that we were expecting
 
495
     *   sizeof(size_t) to be greater than 4, but it wasn't. Setting 
 
496
     *   NS_PTR_LE_32 will correct that mistake.
 
497
     *
 
498
     * if 'sizeof(size_t) <= 4' is triggered, it means that we were expecting
 
499
     *   sizeof(size_t) to be less than or equal to 4, but it wasn't. Setting 
 
500
     *   NS_PTR_GT_32 will correct that mistake.
 
501
     */
 
502
 
 
503
    PR_STATIC_ASSERT(sizeof(size_t) > 4);
 
504
 
 
505
    if (bytes > PRNG_MAX_ADDITIONAL_BYTES) {
 
506
        bytes = PRNG_MAX_ADDITIONAL_BYTES;
 
507
    }
 
508
#else
 
509
    PR_STATIC_ASSERT(sizeof(size_t) <= 4);
 
510
#endif
 
511
 
 
512
    PZ_Lock(globalrng->lock);
 
513
    /* if we're passed more than our additionalDataCache, simply
 
514
     * call reseed with that data */
 
515
    if (bytes > sizeof (globalrng->additionalDataCache)) {
 
516
        rv = prng_reseed(globalrng, NULL, 0, data, (unsigned int) bytes);
 
517
    /* if we aren't going to fill or overflow the buffer, just cache it */
 
518
    } else if (bytes < ((sizeof globalrng->additionalDataCache)
 
519
                                - globalrng->additionalAvail)) {
 
520
        PORT_Memcpy(globalrng->additionalDataCache+globalrng->additionalAvail,
 
521
                    data, bytes);
 
522
        globalrng->additionalAvail += (PRUint32) bytes;
 
523
        rv = SECSuccess;
 
524
    } else {
 
525
        /* we are going to fill or overflow the buffer. In this case we will
 
526
         * fill the entropy buffer, reseed with it, start a new buffer with the
 
527
         * remainder. We know the remainder will fit in the buffer because
 
528
         * we already handled the case where bytes > the size of the buffer.
 
529
         */
 
530
        size_t bufRemain = (sizeof globalrng->additionalDataCache) 
 
531
                                        - globalrng->additionalAvail;
 
532
        /* fill the rest of the buffer */
 
533
        if (bufRemain) {
 
534
            PORT_Memcpy(globalrng->additionalDataCache
 
535
                        +globalrng->additionalAvail, 
 
536
                        data, bufRemain);
 
537
            data = ((unsigned char *)data) + bufRemain;
 
538
            bytes -= bufRemain;
 
539
        }
 
540
        /* reseed from buffer */
 
541
        rv = prng_reseed(globalrng, NULL, 0, globalrng->additionalDataCache, 
 
542
                                        sizeof globalrng->additionalDataCache);
 
543
 
 
544
        /* copy the rest into the cache */
 
545
        PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
 
546
        globalrng->additionalAvail = (PRUint32) bytes;
 
547
    }
 
548
                
 
549
    PZ_Unlock(globalrng->lock);
 
550
    return rv;
 
551
}
 
552
 
 
553
/*
 
554
** Generate some random bytes, using the global random number generator
 
555
** object.
 
556
*/
 
557
static SECStatus 
 
558
prng_GenerateGlobalRandomBytes(RNGContext *rng,
 
559
                               void *dest, size_t len)
 
560
{
 
561
    SECStatus rv = SECSuccess;
 
562
    PRUint8 *output = dest;
 
563
    /* check for a valid global RNG context */
 
564
    PORT_Assert(rng != NULL);
 
565
    if (rng == NULL) {
 
566
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
567
        return SECFailure;
 
568
    }
 
569
    /* FIPS limits the amount of entropy available in a single request */
 
570
    if (len > PRNG_MAX_REQUEST_SIZE) {
 
571
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
 
572
        return SECFailure;
 
573
    }
 
574
    /* --- LOCKED --- */
 
575
    PZ_Lock(rng->lock);
 
576
    /* Check the amount of seed data in the generator.  If not enough,
 
577
     * don't produce any data.
 
578
     */
 
579
    if (rng->reseed_counter[0] >= RESEED_VALUE) {
 
580
        rv = prng_reseed(rng, NULL, 0, NULL, 0);
 
581
        PZ_Unlock(rng->lock);
 
582
        if (rv != SECSuccess) {
 
583
            return rv;
 
584
        }
 
585
        RNG_SystemInfoForRNG();
 
586
        PZ_Lock(rng->lock);
 
587
    }
 
588
    /*
 
589
     * see if we have enough bytes to fulfill the request.
 
590
     */
 
591
    if (len <= rng->dataAvail) {
 
592
        memcpy(output, rng->data + ((sizeof rng->data) - rng->dataAvail), len);
 
593
        memset(rng->data + ((sizeof rng->data) - rng->dataAvail), 0, len);
 
594
        rng->dataAvail -= len;
 
595
        rv = SECSuccess;
 
596
    /* if we are asking for a small number of bytes, cache the rest of 
 
597
     * the bytes */
 
598
    } else if (len < sizeof rng->data) {
 
599
        rv = prng_generateNewBytes(rng, rng->data, sizeof rng->data, 
 
600
                        rng->additionalAvail ? rng->additionalDataCache : NULL,
 
601
                        rng->additionalAvail);
 
602
        rng->additionalAvail = 0;
 
603
        if (rv == SECSuccess) {
 
604
            memcpy(output, rng->data, len);
 
605
            memset(rng->data, 0, len); 
 
606
            rng->dataAvail = (sizeof rng->data) - len;
 
607
        }
 
608
    /* we are asking for lots of bytes, just ask the generator to pass them */
 
609
    } else {
 
610
        rv = prng_generateNewBytes(rng, output, len,
 
611
                        rng->additionalAvail ? rng->additionalDataCache : NULL,
 
612
                        rng->additionalAvail);
 
613
        rng->additionalAvail = 0;
 
614
    }
 
615
    PZ_Unlock(rng->lock);
 
616
    /* --- UNLOCKED --- */
 
617
    return rv;
 
618
}
 
619
 
 
620
/*
 
621
** Generate some random bytes, using the global random number generator
 
622
** object.
 
623
*/
 
624
SECStatus 
 
625
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
 
626
{
 
627
    return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
 
628
}
 
629
 
 
630
void
 
631
RNG_RNGShutdown(void)
 
632
{
 
633
    /* check for a valid global RNG context */
 
634
    PORT_Assert(globalrng != NULL);
 
635
    if (globalrng == NULL) {
 
636
        /* Should set a "not initialized" error code. */
 
637
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 
638
        return;
 
639
    }
 
640
    /* clear */
 
641
    prng_freeRNGContext(globalrng);
 
642
    globalrng = NULL;
 
643
    /* reset the callonce struct to allow a new call to RNG_RNGInit() */
 
644
    coRNGInit = pristineCallOnce;
 
645
}
 
646
 
 
647
/*
 
648
 * Test case interface. used by fips testing and power on self test
 
649
 */
 
650
 /* make sure the test context is separate from the global context, This
 
651
  * allows us to test the internal random number generator without losing
 
652
  * entropy we may have previously collected. */
 
653
RNGContext testContext;
 
654
 
 
655
/*
 
656
 * Test vector API. Use NIST SP 800-90 general interface so one of the
 
657
 * other NIST SP 800-90 algorithms may be used in the future.
 
658
 */
 
659
SECStatus
 
660
PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len, 
 
661
                const PRUint8 *nonce, unsigned int nonce_len,
 
662
                const PRUint8 *personal_string, unsigned int ps_len)
 
663
{
 
664
   int bytes_len = entropy_len + nonce_len + ps_len;
 
665
   PRUint8 *bytes = PORT_Alloc(bytes_len);
 
666
 
 
667
   if (bytes == NULL) {
 
668
        return SECFailure;
 
669
   }
 
670
   /* concatenate the various inputs, internally NSS only instantiates with
 
671
    * a single long string */
 
672
   PORT_Memcpy(bytes, entropy, entropy_len);
 
673
   if (nonce) {
 
674
        PORT_Memcpy(&bytes[entropy_len], nonce, nonce_len);
 
675
   } else {
 
676
        PORT_Assert(nonce_len == 0);
 
677
   }
 
678
   if (personal_string) {
 
679
       PORT_Memcpy(&bytes[entropy_len+nonce_len], personal_string, ps_len);
 
680
   } else {
 
681
        PORT_Assert(ps_len == 0);
 
682
   }
 
683
   prng_instantiate(&testContext, bytes, bytes_len);
 
684
   testContext.isValid = PR_TRUE;
 
685
   PORT_ZFree(bytes, bytes_len);
 
686
   return SECSuccess;
 
687
}
 
688
 
 
689
SECStatus
 
690
PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len, 
 
691
                  const PRUint8 *additional, unsigned int additional_len)
 
692
{
 
693
    if (!testContext.isValid) {
 
694
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 
695
        return SECFailure;
 
696
    }
 
697
    return prng_reseed(&testContext, entropy, entropy_len, additional,
 
698
                        additional_len);
 
699
 
 
700
}
 
701
 
 
702
SECStatus
 
703
PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len, 
 
704
                  const PRUint8 *additional, unsigned int additional_len)
 
705
{
 
706
    if (!testContext.isValid) {
 
707
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 
708
        return SECFailure;
 
709
    }
 
710
    return prng_generateNewBytes(&testContext, bytes, bytes_len,
 
711
                        additional, additional_len);
 
712
 
 
713
}
 
714
 
 
715
SECStatus
 
716
PRNGTEST_Uninstantiate()
 
717
{
 
718
   PORT_Memset(&testContext, 0, sizeof testContext);
 
719
   return SECSuccess;
 
720
}
 
721
 
 
722