diff options
Diffstat (limited to 'lib/dns/sec/dnssafe/digrand.c')
-rw-r--r-- | lib/dns/sec/dnssafe/digrand.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/lib/dns/sec/dnssafe/digrand.c b/lib/dns/sec/dnssafe/digrand.c new file mode 100644 index 00000000..e6f9016e --- /dev/null +++ b/lib/dns/sec/dnssafe/digrand.c @@ -0,0 +1,88 @@ +/* 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 "global.h" +#include "algae.h" +#include "digrand.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; +} + |