93 lines
2.8 KiB
C
93 lines
2.8 KiB
C
/* $NetBSD: digrand.c,v 1.1.1.1 2001/01/27 08:09:00 itojun Exp $ */
|
|
|
|
/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an
|
|
unpublished work protected as such under copyright law. This work
|
|
contains proprietary, confidential, and trade secret information of
|
|
RSA Data Security, Inc. Use, disclosure or reproduction without the
|
|
express written authorization of RSA Data Security, Inc. is
|
|
prohibited.
|
|
*/
|
|
|
|
#include "port_before.h"
|
|
#include "global.h"
|
|
#include "algae.h"
|
|
#include "digrand.h"
|
|
#include "port_after.h"
|
|
|
|
/* Calling routine must initialize the digest algorithm and set
|
|
digestRandom->vTable.
|
|
digestLen is the length of the output of the digest algorithm (i.e. 16).
|
|
state must point to an unsigned char * array of 3 * digestLen.
|
|
*/
|
|
void A_DigestRandomInit (digestRandom, digestLen, state)
|
|
A_DigestRandom *digestRandom;
|
|
unsigned int digestLen;
|
|
unsigned char *state;
|
|
{
|
|
digestRandom->_state = state;
|
|
digestRandom->_output = state + digestLen;
|
|
digestRandom->_digest = digestRandom->_output + digestLen;
|
|
|
|
digestRandom->_outputAvailable = 0;
|
|
digestRandom->_digestLen = digestLen;
|
|
|
|
T_memset ((POINTER)digestRandom->_state, 0, digestLen);
|
|
}
|
|
|
|
void A_DigestRandomUpdate (digestRandom, input, inputLen)
|
|
A_DigestRandom *digestRandom;
|
|
unsigned char *input;
|
|
unsigned int inputLen;
|
|
{
|
|
unsigned int i, j, x;
|
|
|
|
(*digestRandom->vTable->DigestUpdate) (digestRandom, input, inputLen);
|
|
(*digestRandom->vTable->DigestFinal) (digestRandom, digestRandom->_digest);
|
|
|
|
/* add digest to state */
|
|
x = 0;
|
|
for (i = 0; i < digestRandom->_digestLen; i++) {
|
|
j = digestRandom->_digestLen-1-i;
|
|
x += digestRandom->_state[j] + digestRandom->_digest[j];
|
|
digestRandom->_state[j] = (unsigned char)x;
|
|
x >>= 8;
|
|
}
|
|
}
|
|
|
|
void A_DigestRandomGenerateBytes (digestRandom, output, outputLen)
|
|
A_DigestRandom *digestRandom;
|
|
unsigned char *output;
|
|
unsigned int outputLen;
|
|
{
|
|
unsigned int available, i;
|
|
|
|
available = digestRandom->_outputAvailable;
|
|
|
|
while (outputLen > available) {
|
|
T_memcpy
|
|
((POINTER)output,
|
|
(POINTER)&digestRandom->_output[digestRandom->_digestLen-available],
|
|
available);
|
|
output += available;
|
|
outputLen -= available;
|
|
|
|
/* generate new output */
|
|
(*digestRandom->vTable->DigestUpdate)
|
|
(digestRandom, digestRandom->_state, digestRandom->_digestLen);
|
|
(*digestRandom->vTable->DigestFinal) (digestRandom, digestRandom->_output);
|
|
available = digestRandom->_digestLen;
|
|
|
|
/* increment state */
|
|
for (i = 0; i < digestRandom->_digestLen; i++)
|
|
if (digestRandom->_state[digestRandom->_digestLen-1-i]++)
|
|
break;
|
|
}
|
|
|
|
T_memcpy
|
|
((POINTER)output,
|
|
(POINTER)&digestRandom->_output[digestRandom->_digestLen-available],
|
|
outputLen);
|
|
digestRandom->_outputAvailable = available - outputLen;
|
|
}
|
|
|