337 lines
12 KiB
C
337 lines
12 KiB
C
|
/* $NetBSD: rand.c,v 1.1.1.1 2001/01/27 08:08:39 itojun Exp $ */
|
|||
|
|
|||
|
/*
|
|||
|
* Cylink Corporation <EFBFBD> 1998
|
|||
|
*
|
|||
|
* This software is licensed by Cylink to the Internet Software Consortium to
|
|||
|
* promote implementation of royalty free public key cryptography within IETF
|
|||
|
* standards. Cylink wishes to expressly thank the contributions of Dr.
|
|||
|
* Martin Hellman, Whitfield Diffie, Ralph Merkle and Stanford University for
|
|||
|
* their contributions to Internet Security. In accordance with the terms of
|
|||
|
* this license, ISC is authorized to distribute and sublicense this software
|
|||
|
* for the practice of IETF standards.
|
|||
|
*
|
|||
|
* The software includes BigNum, written by Colin Plumb and licensed by Philip
|
|||
|
* R. Zimmermann for royalty free use and distribution with Cylink's
|
|||
|
* software. Use of BigNum as a stand alone product or component is
|
|||
|
* specifically prohibited.
|
|||
|
*
|
|||
|
* Disclaimer of All Warranties. THIS SOFTWARE IS BEING PROVIDED "AS IS",
|
|||
|
* WITHOUT ANY EXPRESSED OR IMPLIED WARRANTY OF ANY KIND WHATSOEVER. IN
|
|||
|
* PARTICULAR, WITHOUT LIMITATION ON THE GENERALITY OF THE FOREGOING, CYLINK
|
|||
|
* MAKES NO REPRESENTATION OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
|
|||
|
* PURPOSE.
|
|||
|
*
|
|||
|
* Cylink or its representatives shall not be liable for tort, indirect,
|
|||
|
* special or consequential damages such as loss of profits or loss of
|
|||
|
* goodwill from the use or inability to use the software for any purpose or
|
|||
|
* for any reason whatsoever.
|
|||
|
*
|
|||
|
* EXPORT LAW: Export of the Foundations Suite may be subject to compliance
|
|||
|
* with the rules and regulations promulgated from time to time by the Bureau
|
|||
|
* of Export Administration, United States Department of Commerce, which
|
|||
|
* restrict the export and re-export of certain products and technical data.
|
|||
|
* If the export of the Foundations Suite is controlled under such rules and
|
|||
|
* regulations, then the Foundations Suite shall not be exported or
|
|||
|
* re-exported, directly or indirectly, (a) without all export or re-export
|
|||
|
* licenses and governmental approvals required by any applicable laws, or (b)
|
|||
|
* in violation of any applicable prohibition against the export or re-export
|
|||
|
* of any part of the Foundations Suite. All export licenses for software
|
|||
|
* containing the Foundations Suite are the sole responsibility of the licensee.
|
|||
|
*/
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
* FILENAME: rand.c PRODUCT NAME: CRYPTOGRAPHIC TOOLKIT
|
|||
|
*
|
|||
|
* FILE STATUS:
|
|||
|
*
|
|||
|
* DESCRIPTION: Cryptographic Toolkit Functions File
|
|||
|
* Random Number Generation Files
|
|||
|
* PUBLIC FUNCTIONS:
|
|||
|
* int InitRand( u_int16_t SEED_bytes, uchar *SEED,
|
|||
|
* uchar *RVAL )
|
|||
|
* int GenRand( u_int16_t A_bytes, uchar *A,
|
|||
|
* uchar *RVAL )
|
|||
|
* int MyGenRand( u_int16_t A_bytes,
|
|||
|
* ord *A,
|
|||
|
* ord *RVAL )
|
|||
|
|
|||
|
* Copyright (c) Cylink Corporation 1994. All rights reserved.
|
|||
|
*
|
|||
|
* REVISION HISTORY:
|
|||
|
*
|
|||
|
* 24 Sep 94 KPZ Initial release
|
|||
|
* 10 Oct 94 KPZ Added Shamir Key Sharing functions
|
|||
|
* 10 Oct 94 KPZ Modified SHA functions for arbitrary message length
|
|||
|
* 12 Oct 94 KPZ Modified SHA functions (new standard)
|
|||
|
* 14 Oct 94 GKL Second version (big endian support)
|
|||
|
* 26 Oct 94 GKL (alignment for big endian support & ERR_ALLOC)
|
|||
|
*
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
* INCLUDE FILES
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
#include "port_before.h"
|
|||
|
|
|||
|
/* system files */
|
|||
|
#ifdef VXD
|
|||
|
#include <vtoolsc.h>
|
|||
|
#else
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#endif
|
|||
|
|
|||
|
/* program files */
|
|||
|
#ifdef VXD
|
|||
|
#include "tkvxd.h"
|
|||
|
#endif
|
|||
|
#include "cylink.h"
|
|||
|
#include "ctk_endian.h"
|
|||
|
#include "toolkit.h"
|
|||
|
#include "cencrint.h"
|
|||
|
#include "sha.h"
|
|||
|
#include "c_asm.h"
|
|||
|
|
|||
|
#include "port_after.h"
|
|||
|
extern u_int16_t DataOrder;
|
|||
|
/****************************************************************************
|
|||
|
* PUBLIC FUNCTIONS DEFINITIONS
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
* NAME: int InitRand( u_int16_t SEED_bytes,
|
|||
|
* uchar *SEED,
|
|||
|
* uchar *RVAL)
|
|||
|
*
|
|||
|
* DESCRIPTION: Initialize Random number Generator
|
|||
|
*
|
|||
|
* INPUTS:
|
|||
|
* PARAMETERS:
|
|||
|
* u_int16_t SEED_bytes Length of SEED
|
|||
|
* uchar *SEED Pointer to SEED value
|
|||
|
*
|
|||
|
* OUTPUT:
|
|||
|
* PARAMETERS:
|
|||
|
* uchar *RVAL Pointer to RVAL
|
|||
|
*
|
|||
|
* RETURN:
|
|||
|
* SUCCESS No errors
|
|||
|
* ERR_INPUT_LEN Invalid length for input data
|
|||
|
* ERR_DATA Generic data error
|
|||
|
* REVISION HISTORY:
|
|||
|
*
|
|||
|
* 24 Sep 94 KPZ Initial release
|
|||
|
*
|
|||
|
****************************************************************************/
|
|||
|
|
|||
|
int InitRand( u_int16_t SEED_bytes,
|
|||
|
uchar *SEED,
|
|||
|
uchar *RVAL )
|
|||
|
{
|
|||
|
int status = SUCCESS; /* function return status */
|
|||
|
if ( SEED_bytes == 0 )
|
|||
|
{
|
|||
|
status = ERR_INPUT_LEN;
|
|||
|
return status;
|
|||
|
}
|
|||
|
if ( SEED_bytes < SHA_LENGTH )
|
|||
|
{
|
|||
|
status = ERR_DATA;
|
|||
|
return status;
|
|||
|
}
|
|||
|
memcpy( RVAL, SEED, SHA_LENGTH);
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
* NAME: int GenRand( u_int16_t A_bytes,
|
|||
|
* uchar *A,
|
|||
|
* uchar *RVAL)
|
|||
|
*
|
|||
|
* DESCRIPTION: Generate random number.
|
|||
|
*
|
|||
|
* INPUTS:
|
|||
|
* PARAMETERS:
|
|||
|
* u_int16_t A_bytes Length of A
|
|||
|
* uchar *A Pointer to A value
|
|||
|
*
|
|||
|
* OUTPUT:
|
|||
|
* PARAMETERS:
|
|||
|
* uchar *RVAL Pointer to RVAL
|
|||
|
*
|
|||
|
* RETURN:
|
|||
|
* SUCCESS No errors
|
|||
|
* ERR_INPUT_LEN Invalid length for input data
|
|||
|
* ERR_DATA Generic data error
|
|||
|
* ERR_ALLOC Insufficient memory
|
|||
|
* REVISION HISTORY:
|
|||
|
*
|
|||
|
* 24 Sep 94 KPZ Initial release
|
|||
|
* 14 Oct 94 GKL Second version (big endian support)
|
|||
|
* 26 Oct 94 GKL (alignment for big endian support & ERR_ALLOC)
|
|||
|
*
|
|||
|
****************************************************************************/
|
|||
|
int GenRand( u_int16_t A_bytes,
|
|||
|
uchar *A,
|
|||
|
uchar *RVAL )
|
|||
|
{
|
|||
|
int status = SUCCESS; /* function return status */
|
|||
|
ord *RVAL_a;
|
|||
|
SHA_context hash_context; /* SHA context structure */
|
|||
|
uchar M[DSS_LENGTH_MIN]; /* message block */
|
|||
|
uchar hash_result[SHA_LENGTH];
|
|||
|
u_int16_t i;
|
|||
|
u_int16_t sha_block; /* number of sha blocks */
|
|||
|
u_int16_t sha_rem; /* size of last block */
|
|||
|
if ( A_bytes == 0 )
|
|||
|
{
|
|||
|
status = ERR_INPUT_LEN;
|
|||
|
return status;
|
|||
|
}
|
|||
|
sha_block = (u_int16_t) (A_bytes / SHA_LENGTH); /* number of sha blocks */
|
|||
|
sha_rem = (u_int16_t) (A_bytes % SHA_LENGTH); /* size of last block */
|
|||
|
if ( sha_rem == 0 ) /* last block = SHA_LENGTH */
|
|||
|
{
|
|||
|
sha_block--;
|
|||
|
}
|
|||
|
for ( i = 0; i <= sha_block; i++)
|
|||
|
{
|
|||
|
SHAInit ( &hash_context );
|
|||
|
memcpy( M, RVAL, SHA_LENGTH);
|
|||
|
memset( M + SHA_LENGTH, 0, DSS_LENGTH_MIN - SHA_LENGTH );
|
|||
|
if ( (status = SHAUpdate( &hash_context, M, DSS_LENGTH_MIN ))
|
|||
|
!= SUCCESS )
|
|||
|
{
|
|||
|
return status; /* error */
|
|||
|
}
|
|||
|
if ( (status=MySHAFinal (&hash_context, hash_result )) != SUCCESS )
|
|||
|
{
|
|||
|
return status; /* error */
|
|||
|
}
|
|||
|
|
|||
|
BigSwap(RVAL, SHA_LENGTH);
|
|||
|
ALIGN_CALLOC_COPY(RVAL, RVAL_a, SHA_LENGTH);
|
|||
|
if ( status != SUCCESS )
|
|||
|
{
|
|||
|
ALIGN_COPY_FREE(RVAL_a,RVAL,SHA_LENGTH);
|
|||
|
BigSwap(RVAL, SHA_LENGTH);
|
|||
|
return status; /* ERR_ALLOC insufficient memory */
|
|||
|
}
|
|||
|
Sum_Q( RVAL_a, 1, SHA_LENGTH / sizeof(ord) );
|
|||
|
Sum_big( RVAL_a, /* RVAL=RVAL+hash_result*/
|
|||
|
(ord *)hash_result,
|
|||
|
RVAL_a, SHA_LENGTH / sizeof(ord) );
|
|||
|
ALIGN_COPY_FREE(RVAL_a,RVAL,SHA_LENGTH);
|
|||
|
BigSwap(RVAL, SHA_LENGTH);
|
|||
|
#ifdef CTK_BIG_ENDIAN
|
|||
|
ByteSwap(hash_result,SHA_LENGTH);
|
|||
|
#endif
|
|||
|
BigSwap(hash_result, SHA_LENGTH);
|
|||
|
if ( i == sha_block && sha_rem != 0 ) /* last block < SHA_LENGTH*/
|
|||
|
{
|
|||
|
memcpy( A + i * SHA_LENGTH, hash_result,
|
|||
|
sha_rem * sizeof (uchar));
|
|||
|
}
|
|||
|
else /* last block = SHA_LENGTH*/
|
|||
|
{
|
|||
|
memcpy( A + i * SHA_LENGTH, hash_result,
|
|||
|
SHA_LENGTH * sizeof (uchar));
|
|||
|
}
|
|||
|
}
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/****************************************************************************
|
|||
|
* NAME: int MyGenRand( u_int16_t A_bytes,
|
|||
|
* ord *A,
|
|||
|
* ord *RVAL)
|
|||
|
*
|
|||
|
* DESCRIPTION: Generate random number.
|
|||
|
*
|
|||
|
* INPUTS:
|
|||
|
* PARAMETERS:
|
|||
|
* u_int16_t A_bytes Length of A
|
|||
|
* ord *A Pointer to A value
|
|||
|
*
|
|||
|
* OUTPUT:
|
|||
|
* PARAMETERS:
|
|||
|
* ord *RVAL Pointer to RVAL
|
|||
|
*
|
|||
|
* RETURN:
|
|||
|
* SUCCESS No errors
|
|||
|
* ERR_INPUT_LEN Invalid length for input data
|
|||
|
* ERR_DATA Generic data error
|
|||
|
* REVISION HISTORY:
|
|||
|
*
|
|||
|
* 24 Sep 94 KPZ Initial release
|
|||
|
* 14 Oct 94 GKL Second version (big endian support)
|
|||
|
*
|
|||
|
****************************************************************************/
|
|||
|
int MyGenRand( u_int16_t A_bytes,
|
|||
|
ord *A,
|
|||
|
ord *RVAL )
|
|||
|
{
|
|||
|
int status = SUCCESS; /* function return status */
|
|||
|
SHA_context hash_context; /* SHA context structure */
|
|||
|
uchar M[DSS_LENGTH_MIN]; /* message block */
|
|||
|
uchar hash_result[SHA_LENGTH];
|
|||
|
u_int16_t i;
|
|||
|
u_int16_t sha_block; /* number of sha blocks */
|
|||
|
u_int16_t sha_rem; /* size of last block */
|
|||
|
if ( A_bytes == 0 )
|
|||
|
{
|
|||
|
status = ERR_INPUT_LEN;
|
|||
|
return status;
|
|||
|
}
|
|||
|
sha_block = (u_int16_t) (A_bytes / SHA_LENGTH); /* number of sha blocks */
|
|||
|
sha_rem = (u_int16_t) (A_bytes % SHA_LENGTH); /* size of last block */
|
|||
|
if ( sha_rem == 0 ) /* last block = SHA_LENGTH */
|
|||
|
{
|
|||
|
sha_block--;
|
|||
|
}
|
|||
|
for ( i = 0; i <= sha_block; i++)
|
|||
|
{
|
|||
|
SHAInit ( &hash_context );
|
|||
|
memcpy( M, RVAL, SHA_LENGTH);
|
|||
|
memset( M + SHA_LENGTH, 0, DSS_LENGTH_MIN - SHA_LENGTH );
|
|||
|
if ( (status = SHAUpdate( &hash_context, M, DSS_LENGTH_MIN ))
|
|||
|
!= SUCCESS )
|
|||
|
{
|
|||
|
return status; /* error */
|
|||
|
}
|
|||
|
if ( (status=MySHAFinal (&hash_context, hash_result )) != SUCCESS )
|
|||
|
{
|
|||
|
return status; /* error */
|
|||
|
}
|
|||
|
#ifdef CTK_BIG_ENDIAN
|
|||
|
ByteSwap((uchar*)RVAL,SHA_LENGTH);
|
|||
|
#endif
|
|||
|
BigSwap((uchar*)RVAL, SHA_LENGTH);
|
|||
|
Sum_Q(RVAL, 1,SHA_LENGTH / sizeof(ord));
|
|||
|
Sum_big( RVAL, /* RVAL=RVAL+hash_result*/
|
|||
|
(ord*)hash_result,
|
|||
|
RVAL, SHA_LENGTH / sizeof(ord) );
|
|||
|
BigSwap((uchar*)RVAL, SHA_LENGTH);
|
|||
|
#ifdef CTK_BIG_ENDIAN
|
|||
|
ByteSwap((uchar*)RVAL,SHA_LENGTH);
|
|||
|
#endif
|
|||
|
if ( i == sha_block && sha_rem != 0 ) /* last block < SHA_LENGTH*/
|
|||
|
{
|
|||
|
memcpy( &A[ i*SHA_LENGTH / sizeof(ord)], hash_result,
|
|||
|
sha_rem * sizeof (uchar));
|
|||
|
}
|
|||
|
else /* last block = SHA_LENGTH*/
|
|||
|
{
|
|||
|
memcpy( &A[ i*SHA_LENGTH / sizeof(ord)], hash_result,
|
|||
|
SHA_LENGTH * sizeof (uchar));
|
|||
|
}
|
|||
|
}
|
|||
|
return status;
|
|||
|
}
|
|||
|
|