original files of m241
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
/* dot11RandLib.c - random number generator for wireless framework */
|
||||
|
||||
/*
|
||||
Modification History
|
||||
--------------------
|
||||
02a,02mar10,kr Initial version
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
This module contains functions for generating random numbers:
|
||||
- depends on openssl for the SHA256 and MD5 hashes;
|
||||
- code adapted from the CCI library (cci_DefaultRand.c).
|
||||
|
||||
\NOMANUAL
|
||||
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "drv/wlan/dot11Lib.h"
|
||||
#include "drv/wlan/dot11RsnLib.h"
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* *** Restricted Rights Legend ***
|
||||
*
|
||||
* The programs and information contained herein are licensed only
|
||||
* pursuant to a license agreement that contains use, reverse
|
||||
* engineering, disclosure, and other restrictions; accordingly, it
|
||||
* is "Unpublished--all rights reserved under the applicable
|
||||
* copyright laws".
|
||||
*
|
||||
* Use duplication, or disclosure by the Government is subject to
|
||||
* restrictions as set forth in subparagraph (c)(1)(ii) of the Rights
|
||||
* in Technical Data and Computer Licensed Programs clause of DFARS
|
||||
* 52.227 7013.
|
||||
*
|
||||
* Copyright 2000-2010 Wind River Systems, Inc.
|
||||
* Copyright 1997 Epilogue Technology Corporation.
|
||||
* Copyright 1998-1999 Integrated Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* *** Government Use ***
|
||||
*
|
||||
* The Licensed Programs and their documentation were developed at
|
||||
* private expense and no part of them is in the public domain.
|
||||
*
|
||||
* The Licensed Programs are "Restricted Computer Software" as that
|
||||
* term is defined in Clause 52.227-19 of the Federal Acquisition
|
||||
* Regulations (FAR) and are "Commercial Computer Software" as that
|
||||
* term is defined in Subpart 227.401 of the Department of Defense
|
||||
* Federal Acquisition Regulation Supplement (DFARS).
|
||||
*
|
||||
* (i) If the licensed Programs are supplied to the Department of
|
||||
* Defense (DoD), the Licensed Programs are classified as
|
||||
* "Commercial Computer Software" and the Government is acquiring
|
||||
* only "restricted rights" in the Licensed Programs and their
|
||||
* documentation as that term is defined in Clause 52.227
|
||||
* 7013(c)(1) of the DFARS, and
|
||||
*
|
||||
* (ii) If the Licensed Programs are supplied to any unit or agency
|
||||
* of the United States Government other than DoD, the
|
||||
* Government's rights in the Licensed Programs and their
|
||||
* documentation will be as defined in Clause 52.227-19(c)(2) of
|
||||
* the FAR.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* This file implements a cryptographically strong random number generator.
|
||||
* The algorithm is based on the ANSI X9.17 generator. Keyed MD5 is used
|
||||
* as the basic transform rather than TDES. The DT value is augmented with
|
||||
* a monotonically increasing counter. See [Stallings - Network and
|
||||
* Internetwork Security pp 102-103] or ANSI X9.17 Appendix C.
|
||||
*/
|
||||
|
||||
/*
|
||||
* these next 2 bits of magic are used to seed the generator with
|
||||
* less than 32 bytes of randomness. If the user hands in N < 32 bytes (call
|
||||
* them "B") we generate MD5 (MAGIC1 "+" B "+" MAGIC1), and
|
||||
* MD5 (MAGIC2 "+" B "+" MAGIC2), and combine them to get our needed 32 bytes.
|
||||
* The actual values here are *not* of any importance, although having a
|
||||
* reasonably "random" bit distribution is useful. These were generated by
|
||||
* running some real-time system statistics through MD5.
|
||||
*/
|
||||
|
||||
static UINT8 PRNG_MAGIC1 [] =
|
||||
{ 0xb4, 0x33, 0x4b, 0xf5, 0x9b, 0x7a, 0x24, 0x19,
|
||||
0x8c, 0x04, 0xa5, 0xd1, 0x1e, 0xab, 0xa2, 0xe9
|
||||
};
|
||||
|
||||
static UINT8 PRNG_MAGIC2 [] =
|
||||
{ 0xaa, 0x9b, 0x49, 0xd4, 0x0f, 0x4c, 0xa7, 0x1b,
|
||||
0x1d, 0x0e, 0x83, 0xd6, 0xe7, 0x9c, 0xab, 0xf8
|
||||
};
|
||||
|
||||
#define PRNG_SEEDBYTES_NEEDED 32
|
||||
|
||||
static MD5_CTX PRNG_CCI_MD5_CONTEXT;
|
||||
|
||||
static UINT8 PRNG_MD5_K[16]; /* MD5 keyed hash key */
|
||||
static UINT8 PRNG_SV[16]; /* current seed value */
|
||||
static UINT8 PRNG_R[16]; /* current random pool */
|
||||
static UINT32 PRNG_DT; /* "date+time" value */
|
||||
static UINT32 PRNG_CNT; /* counter; increments with each call */
|
||||
static UINT8 PRNG_N; /* number of "random" bytes currently available */
|
||||
static UINT8 PRNG_INJIDX; /* index of PRNG_SV where prng_inject_random8 will xor next random input into */
|
||||
|
||||
static SEM_ID defaultMtx;
|
||||
|
||||
/*
|
||||
** --- randomly get current time
|
||||
*/
|
||||
static UINT32 randomTime( void )
|
||||
{
|
||||
struct timespec tspec;
|
||||
clock_gettime( CLOCK_REALTIME, &tspec );
|
||||
return( (UINT32) tspec.tv_nsec );
|
||||
}
|
||||
|
||||
/*
|
||||
** --- Get a random number from the SHA256 algorithm that produces
|
||||
** a 32-byte digest --- which is equal to PRNG_SEEDBYTES_NEEDED(the value of the variable 'length').
|
||||
*/
|
||||
static unsigned glue_seed_prng( UINT8 *buffer, unsigned length )
|
||||
{
|
||||
SHA256_CTX context;
|
||||
UINT32 t = randomTime();
|
||||
|
||||
SHA256_Init( &context );
|
||||
SHA256_Update( &context, (void *) &t, sizeof(UINT32) );
|
||||
SHA256_Final( buffer, &context );
|
||||
return( length );
|
||||
}
|
||||
|
||||
/*
|
||||
* compute next seed value and state
|
||||
*/
|
||||
static void prng_iterate( void )
|
||||
{
|
||||
int i;
|
||||
UINT8 *p, *q;
|
||||
UINT8 digest[16];
|
||||
|
||||
/* step 1. R = MD5_K (MD5_K ((DT concat (++CNT)) XOR SV)) */
|
||||
|
||||
/* digest <-- MD5 ((DT concat (++CNT)) XOR SV */
|
||||
++PRNG_CNT;
|
||||
PRNG_DT = randomTime();
|
||||
MD5_Init( &PRNG_CCI_MD5_CONTEXT );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MD5_K, 16 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, (UINT8 *) &PRNG_DT, 4 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, (UINT8 *) &PRNG_CNT, 4 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MD5_K, 16 );
|
||||
MD5_Final( digest, &PRNG_CCI_MD5_CONTEXT );
|
||||
|
||||
/* PRNG_SV <-- (PRNG_SV XOR digest) */
|
||||
|
||||
/* leave digest alone as we'll need it again when we compute new SV */
|
||||
for( i = 0, p = PRNG_SV, q = digest; i < 16; i++ ) *p++ ^= *q++;
|
||||
|
||||
/* PRNG_R <-- MD5 (PRNG_SV) */
|
||||
MD5_Init( &PRNG_CCI_MD5_CONTEXT );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MD5_K, 16 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_SV, 16 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MD5_K, 16 );
|
||||
MD5_Final( PRNG_R, &PRNG_CCI_MD5_CONTEXT );
|
||||
|
||||
/*
|
||||
* step 2. SV = MD5_K (MD5_K ((DT concat (++CNT)) XOR R))
|
||||
*
|
||||
* digest is still MD5_K ((DT concat (++CNT)), so we dont need another
|
||||
* MD5 operation
|
||||
*/
|
||||
|
||||
/* PRNG_SV <-- (PRNG_SV XOR digest) */
|
||||
for( i = 0, p = PRNG_R, q = digest; i < 16; i++ ) *q++ ^= *p++;
|
||||
|
||||
MD5_Init( &PRNG_CCI_MD5_CONTEXT );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MD5_K, 16 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, (UINT8 *)digest, 16 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MD5_K, 16 );
|
||||
MD5_Final( PRNG_SV, &PRNG_CCI_MD5_CONTEXT );
|
||||
|
||||
/* now we have another 16 bytes of usable R */
|
||||
PRNG_N = 16;
|
||||
}
|
||||
|
||||
/*
|
||||
* seed the prng
|
||||
*/
|
||||
static void prng_seed( UINT32 seedSize, UINT8 *seedvalues )
|
||||
{
|
||||
if( seedSize <= PRNG_SEEDBYTES_NEEDED )
|
||||
{
|
||||
MD5_Init( &PRNG_CCI_MD5_CONTEXT );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MAGIC1, 16 );
|
||||
if( seedSize > 0 ) MD5_Update( &PRNG_CCI_MD5_CONTEXT, seedvalues, seedSize );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MAGIC1, 16 );
|
||||
MD5_Final( PRNG_MD5_K, &PRNG_CCI_MD5_CONTEXT );
|
||||
|
||||
MD5_Init( &PRNG_CCI_MD5_CONTEXT );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MAGIC2, 16 );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, seedvalues, seedSize );
|
||||
MD5_Update( &PRNG_CCI_MD5_CONTEXT, PRNG_MAGIC2, 16 );
|
||||
MD5_Final( PRNG_SV, &PRNG_CCI_MD5_CONTEXT );
|
||||
|
||||
memcpy( &PRNG_CNT, seedvalues, 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( PRNG_SV, seedvalues, 16 );
|
||||
memcpy( PRNG_MD5_K, seedvalues + 16, 16 );
|
||||
memcpy( &PRNG_CNT, seedvalues, 4 );
|
||||
}
|
||||
|
||||
PRNG_DT = randomTime();
|
||||
PRNG_N = PRNG_INJIDX = 0;
|
||||
prng_iterate(); /* kick start the PRNG */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the prng system. This involves calling out for seed bytes. 32
|
||||
* of them, in fact.
|
||||
*/
|
||||
static void prng_init( void )
|
||||
{
|
||||
UINT8 seedvalues[PRNG_SEEDBYTES_NEEDED];
|
||||
unsigned int seedSize;
|
||||
|
||||
memset( seedvalues, 0, PRNG_SEEDBYTES_NEEDED );
|
||||
seedSize = glue_seed_prng( seedvalues, PRNG_SEEDBYTES_NEEDED );
|
||||
prng_seed( seedSize, seedvalues );
|
||||
}
|
||||
|
||||
/*
|
||||
* hand back a "random" byte
|
||||
*/
|
||||
static UINT8 prng_random8( void )
|
||||
{
|
||||
if( !PRNG_N ) prng_iterate();
|
||||
|
||||
return PRNG_R[--PRNG_N];
|
||||
}
|
||||
|
||||
/*
|
||||
* fill up a buffer with "random" bytes
|
||||
*/
|
||||
static void prng_random( UINT8 *buf, UINT32 N )
|
||||
{
|
||||
while( N-- ) *buf++ = prng_random8();
|
||||
}
|
||||
|
||||
/*************************************************************************************************
|
||||
* Method Name: dot11RandNum
|
||||
* Description: Fill buffer with random numbers.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* < *buffer > -
|
||||
* < byteCount > -
|
||||
*
|
||||
* Returns: void - No value returned.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
void dot11RandNum(UINT8 *buffer, UINT32 byteCount)
|
||||
{
|
||||
semTake(defaultMtx, WAIT_FOREVER);
|
||||
prng_random( buffer, byteCount );
|
||||
semGive(defaultMtx);
|
||||
}
|
||||
|
||||
/*************************************************************************************************
|
||||
* Method Name: dot11RandNumInit
|
||||
* Description: Initialize the dot11RandLib
|
||||
*
|
||||
**************************************************************************************************/
|
||||
void dot11RandNumInit(void)
|
||||
{
|
||||
defaultMtx = semBCreate(SEM_Q_FIFO, SEM_FULL);
|
||||
|
||||
prng_init();
|
||||
}
|
||||
Reference in New Issue
Block a user