summaryrefslogtreecommitdiff
path: root/lib/dns/sec/dnssafe/digrand.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/sec/dnssafe/digrand.c')
-rw-r--r--lib/dns/sec/dnssafe/digrand.c88
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;
+}
+