]> andersk Git - moira.git/commitdiff
initial import of gdss from the Athena source tree
authordanw <danw>
Thu, 10 Jul 1997 23:55:56 +0000 (23:55 +0000)
committerdanw <danw>
Thu, 10 Jul 1997 23:55:56 +0000 (23:55 +0000)
57 files changed:
util/gdss/Imakefile [new file with mode: 0644]
util/gdss/gdss_test.c [new file with mode: 0644]
util/gdss/include/BigDyad.h [new file with mode: 0644]
util/gdss/include/BigNum.h [new file with mode: 0644]
util/gdss/include/BigRSA.h [new file with mode: 0644]
util/gdss/include/bigkeygen.h [new file with mode: 0644]
util/gdss/include/bigrsacode.h [new file with mode: 0644]
util/gdss/include/bigsignverify.h [new file with mode: 0644]
util/gdss/include/digital-copyright.h [new file with mode: 0644]
util/gdss/include/gdss.h [new file with mode: 0644]
util/gdss/include/hashes.h [new file with mode: 0644]
util/gdss/include/key_perm.h [new file with mode: 0644]
util/gdss/include/odd.h [new file with mode: 0644]
util/gdss/include/p_table.h [new file with mode: 0644]
util/gdss/include/pamrm.h [new file with mode: 0644]
util/gdss/include/random.h [new file with mode: 0644]
util/gdss/include/read_password.h [new file with mode: 0644]
util/gdss/lib/Imakefile [new file with mode: 0644]
util/gdss/lib/crypto/Imakefile [new file with mode: 0644]
util/gdss/lib/crypto/KeyFromPQ.c [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/DEScrypto.h [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/Imakefile [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/RSAcrypto.h [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/bigkeygen.c [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/bigrsacode.c [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/bigsignverify.c [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/gentables.c [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/hashes.h [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/random.c [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/random.h [new file with mode: 0644]
util/gdss/lib/crypto/algorithm/random_BigNum.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/Imakefile [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/KerN.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bn/bnCmp.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bn/bnDivide.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bn/bnInit.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bn/bnMult.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bz.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bzf.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/bztest.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/c/testKerN.c [new file with mode: 0644]
util/gdss/lib/crypto/bignum/h/BigNum.h [new file with mode: 0644]
util/gdss/lib/crypto/bignum/h/BigZ.h [new file with mode: 0644]
util/gdss/lib/crypto/bignum/h/BntoBnn.h [new file with mode: 0644]
util/gdss/lib/crypto/crypto_util.c [new file with mode: 0644]
util/gdss/lib/crypto/dumphex.c [new file with mode: 0644]
util/gdss/lib/crypto/endian.h [new file with mode: 0644]
util/gdss/lib/crypto/hashes.c [new file with mode: 0644]
util/gdss/lib/crypto/read_password.c [new file with mode: 0644]
util/gdss/lib/crypto/read_privkey.c [new file with mode: 0644]
util/gdss/lib/crypto/read_pubkey.c [new file with mode: 0644]
util/gdss/lib/crypto/testEncodeP.c [new file with mode: 0644]
util/gdss/lib/crypto/testsignverify.c [new file with mode: 0644]
util/gdss/lib/crypto/write [new file with mode: 0644]
util/gdss/lib/crypto/write_pubkey.c [new file with mode: 0644]
util/gdss/lib/gdss.c [new file with mode: 0644]
util/gdss/lib/rgdss.c [new file with mode: 0644]

diff --git a/util/gdss/Imakefile b/util/gdss/Imakefile
new file mode 100644 (file)
index 0000000..3ccf5e2
--- /dev/null
@@ -0,0 +1,13 @@
+/* $Header$ */
+
+#define have_subdirs
+SUBDIRS = lib
+
+all::
+
+gdss_test: lib/libgdss.a
+       $(CC) $(CFLAGS) -I./include -o $@ $@.c lib/libgdss.a $(LLIB) -lkrb -ldes -lhesiod $(OSLIBS)
+
+clean::
+       rm -f gdss_test
+
diff --git a/util/gdss/gdss_test.c b/util/gdss/gdss_test.c
new file mode 100644 (file)
index 0000000..a4d39c2
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Test program for GDSS.
+ *
+ */
+
+#include <krb.h>
+#include <gdss.h>
+
+char TestMessage[] = "This is a test message. This is only a test.";
+
+unsigned char OldSig[] = { 0x44, 0x6a, 0x69, 0x73, 0x20, 0x21, 0x20,
+0x21, 0x41, 0x54, 0x48, 0x45, 0x4e, 0x41, 0x2e, 0x4d, 0x49, 0x54,
+0x2e, 0x45, 0x44, 0x55, 0x20, 0x21, 0x2a, 0x13, 0x28, 0x97, 0x2b,
+0x47, 0xad, 0xcc, 0xb0, 0xe1, 0x11, 0x71, 0xc1, 0x48, 0xa5, 0xd1,
+0x1e, 0xa6, 0x20, 0x20, 0x97, 0x3d, 0xcb, 0x73, 0xf3, 0x63, 0x52,
+0x3b, 0x2c, 0x7f, 0x05, 0x30, 0xe0, 0x03, 0x75, 0x9e, 0x0c, 0xa7,
+0xdc, 0xf2, 0x41, 0x89, 0x95, 0xb1, 0x4e, 0xe1, 0x11, 0xba, 0x05,
+0x39, 0xd1, 0xf1, 0x74, 0x96, 0x7f, 0xa2, 0xaf, 0x40, 0xc3, 0x70,
+0x5a, 0x39, 0xa0, 0xce, 0x8a, 0xfd, 0x1c, 0xed, 0xcc, 0x00 };
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+  char Signature[1000];
+  int status;
+  SigInfo aSigInfo;
+
+  printf("Performing Test Signature....");
+  status = GDSS_Sign(TestMessage, strlen(TestMessage), Signature);
+  if (status != GDSS_SUCCESS) {
+    printf("FAILED\n");
+    if (status == GDSS_E_TIMEDOUT)
+      printf("Signature Server Request timed out (is it running?)!\n");
+    else printf("GDSS_Sign Error number: %d\n", status);
+    exit (1);
+  } else {
+    printf("SUCCESS\n");
+  }
+
+  memset(&aSigInfo, 0, sizeof(aSigInfo));
+
+  printf("Attempting to Verify signature...");
+  status = GDSS_Verify(TestMessage, strlen(TestMessage), Signature,
+                      &aSigInfo);
+  if (status != GDSS_SUCCESS) {
+    printf("FAILED\n");
+    printf("GDSS_Verify Error number: %d\n", status);
+    exit (1);
+  } else {
+    printf("SUCCESS\n");
+    printf("Signature by: %s.%s@%s at %s\n",
+          aSigInfo.pname, aSigInfo.pinst, aSigInfo.prealm,
+          ctime(&aSigInfo.timestamp));
+  }
+
+  printf("Purposely damaging data...test: ");
+
+  TestMessage[0] = 'S';
+
+  status = GDSS_Verify(TestMessage, strlen(TestMessage), Signature,
+                      &aSigInfo);
+  if (status == GDSS_SUCCESS) {
+    printf("FAILED\n");
+    printf("Signature succeeded when it should *not* have!\n");
+    exit (1);
+  } else if (status != GDSS_E_BADSIG) {
+    printf("FAILED\n");
+    printf("Signature failed, but returned error code %d\n", status);
+    exit (1);
+  } else {
+    printf("PASSED\n");
+  }
+
+  printf("Fixing data...\n");
+
+  TestMessage[0] = 'T';
+
+  printf("Attempting to Verify signature...");
+  status = GDSS_Verify(TestMessage, strlen(TestMessage), Signature,
+                      &aSigInfo);
+  if (status != GDSS_SUCCESS) {
+    printf("FAILED\n");
+    printf("GDSS_Verify Error number: %d\n", status);
+    exit (1);
+  } else {
+    printf("SUCCESS\n");
+    printf("Signature by: %s.%s@%s at %s\n",
+          aSigInfo.pname, aSigInfo.pinst, aSigInfo.prealm,
+          ctime(&aSigInfo.timestamp));
+  }
+
+  printf("Testing Builtin Signature...\n");
+
+  printf("Attempting to Verify signature...");
+
+  status = GDSS_Verify(TestMessage, strlen(TestMessage), OldSig,
+                      &aSigInfo);
+  if (status != GDSS_SUCCESS) {
+    printf("FAILED\n");
+    printf("GDSS_Verify Error number: %d\n", status);
+    exit (1);
+  } else {
+    printf("SUCCESS\n");
+    printf("Signature by: %s.%s@%s at %s\n",
+          aSigInfo.pname, aSigInfo.pinst, aSigInfo.prealm,
+          ctime(&aSigInfo.timestamp));
+  }
+
+  printf("All Test Passed.\n");
+  exit (0);
+}
+
+
+
+
+
+
diff --git a/util/gdss/include/BigDyad.h b/util/gdss/include/BigDyad.h
new file mode 100644 (file)
index 0000000..726bdc9
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#define assert(x) ((x)?0:dumpcore("x",__FILE__,__LINE__))
+
+#define PRINT_LEVEL1
+#define DigitLim    50
+
+extern unsigned BnnDyCanon();
+extern void BnnDyRaise();
+extern void BnnMPInit();
+extern void BnnModularProduct();
+
+extern BigNum muB();
+#define assert(x) ((x)?0:dumpcore("x",__FILE__,__LINE__))
+#define BnnCfMultiplyDigit(p,pl,m,ml,d) assert(BnnMultiplyDigit(p,pl,m,ml,d) == 0)
diff --git a/util/gdss/include/BigNum.h b/util/gdss/include/BigNum.h
new file mode 100644 (file)
index 0000000..98357fb
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/* BigN.h - Types and structures for clients of BigNum */
+
+
+
+               /******** representation of a bignum ******/
+/*
+**  <--------------------------- nl ---------------------------->
+**  |   Least                                           Most    |
+**  |Significant|           |           |           |Significant|
+**  |BigNumDigit|           |           |           |BigNumDigit|
+**  |___________|___________|___________|___________|___________|
+**        ^                                          (sometimes
+**        |                                            is zero)
+**       nn
+*/
+
+/* signals BigNum.h already included */
+#define BIGNUM
+
+               /*************** sizes ********************/
+
+#define BN_BYTE_SIZE                   8
+#define BN_WORD_SIZE                   (sizeof (int) * BN_BYTE_SIZE)
+#define BN_DIGIT_SIZE                  (sizeof (BigNumDigit) * BN_BYTE_SIZE)
+
+/* notes: */
+/* BN_BYTE_SIZE: number of bits in a byte */
+/* BN_WORD_SIZE: number of bits in an "int" in the target language */
+/* BN_DIGIT_SIZE: number of bits in a digit of a BigNum */
+
+
+               /****** results of compare functions ******/
+
+ /* Note: we don't use "enum" to interface with Modula2+, Lisp, ... */
+#define BN_LT                          -1
+#define BN_EQ                          0
+#define BN_GT                          1
+
+
+               /*************** boolean ******************/
+#ifndef TRUE
+#define        TRUE                    1
+#endif
+#ifndef FALSE
+#define        FALSE                   0
+#endif
+
+typedef short                          Boolean;
+
+
+               /* if DIGITon16BITS is defined, a single digit is on 16 bits */
+               /* otherwise (by default) a single digit is on 32 bits *****/
+
+#ifdef DIGITon16BITS
+typedef unsigned short                 BigNumDigit;
+#else
+typedef unsigned int                   BigNumDigit;
+#endif
+
+
+               /* bignum types: digits, big numbers, carries ... */
+
+typedef BigNumDigit *  BigNum;         /* A big number is a digit pointer */
+typedef unsigned short BigNumCarry;    /* Either 0 or 1 */
+typedef unsigned long  BigNumProduct;  /* The product of two digits */
+typedef unsigned long  BigNumLength;   /* The length of a bignum */
+typedef short          BigNumCmp;      /* result of comparison */
+
+/*\f*/
+
+
+               /************ functions of bn.c ***********/
+
+extern void             BnnInit                        ();
+extern void             BnnClose                       ();
+
+extern Boolean         BnnIsZero                       ();
+extern BigNumCarry     BnnMultiply                     ();
+extern void            BnnDivide                       ();
+extern BigNumCmp       BnnCompare                      ();
+
+
+               /*********** functions of KerN.c **********/
+
+extern void            BnnSetToZero                    ();
+extern void            BnnAssign                       ();
+extern void            BnnSetDigit                     ();
+extern BigNumDigit     BnnGetDigit                     ();
+extern BigNumLength    BnnNumDigits                    ();
+extern BigNumDigit     BnnNumLeadingZeroBitsInDigit    ();
+extern Boolean                 BnnDoesDigitFitInWord           ();
+extern Boolean         BnnIsDigitZero                  ();
+extern Boolean         BnnIsDigitNormalized            ();
+extern Boolean                 BnnIsDigitOdd                   ();
+extern BigNumCmp               BnnCompareDigits                ();
+extern void            BnnComplement                   ();
+extern void            BnnAndDigits                    ();
+extern void            BnnOrDigits                     ();
+extern void            BnnXorDigits                    ();
+extern BigNumDigit     BnnShiftLeft                    ();
+extern BigNumDigit     BnnShiftRight                   ();
+extern BigNumCarry     BnnAddCarry                     ();
+extern BigNumCarry     BnnAdd                          ();
+extern BigNumCarry     BnnSubtractBorrow               ();
+extern BigNumCarry     BnnSubtract                     ();
+extern BigNumCarry     BnnMultiplyDigit                ();
+extern BigNumDigit     BnnDivideDigit                  ();
+
+/*\f*/
+
+               /* some functions can be written with macro-procedures */
+
+
+#ifndef BNNMACROS_OFF
+/* the functions BnnIsZero and BnnCompareDigits are not macro procedures
+since they use parameters twice, and that can produce some bugs if
+you pass a parameter like x++, the increment will be executed twice ! */
+#define BnnSetToZero(nn,nl)             memset (nn, 0, (nl)*BN_DIGIT_SIZE/BN_BYTE_SIZE)
+#define BnnSetDigit(nn,d)              (*(nn) = (d))
+#define BnnGetDigit(nn)                        ((unsigned)(*(nn)))
+#define BnnDoesDigitFitInWord(d)       (BN_DIGIT_SIZE > BN_WORD_SIZE ? ((d) >= 1 << BN_WORD_SIZE ? FALSE : TRUE) : TRUE)
+#define BnnIsDigitZero(d)              ((d) == 0)
+#define BnnIsDigitNormalized(d)                ((d) & (1 << (BN_DIGIT_SIZE - 1)) ? TRUE : FALSE)
+#define BnnIsDigitOdd(d)               ((d) & 1 ? TRUE : FALSE)
+#define BnnAndDigits(nn, d)            (*(nn) &= (d))
+#define BnnOrDigits(nn, d)             (*(nn) |= (d))
+#define BnnXorDigits(nn, d)            (*(nn) ^= (d))
+
+#endif
+
+
diff --git a/util/gdss/include/BigRSA.h b/util/gdss/include/BigRSA.h
new file mode 100644 (file)
index 0000000..3823711
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_BIGRSA
+#define SPHINX_BIGRSA
+
+/* DigitLim is general buffer allocation size */
+
+#ifndef DigitLim
+#define DigitLim 50
+#endif
+
+#define PrimeSize 20
+#define MaxPrimeBits   PrimeSize*BN_DIGIT_SIZE-2
+#define MaxModulusBits 2*MaxPrimeBits-8
+
+typedef struct {
+       int nl,el,pl,ql,dpl,dql;
+
+       BigNumDigit     n[PrimeSize*2];
+       BigNumDigit     e[PrimeSize*2];
+       BigNumDigit     nINV[PrimeSize*2];
+       BigNumDigit     beta2n[PrimeSize*2];
+
+       BigNumDigit     p[PrimeSize];
+       BigNumDigit     q[PrimeSize];
+       BigNumDigit     dp[PrimeSize];
+       BigNumDigit     dq[PrimeSize];
+       BigNumDigit     cr[PrimeSize];
+       BigNumDigit     pINV[PrimeSize];
+       BigNumDigit     qINV[PrimeSize];
+       BigNumDigit     beta3p[PrimeSize];
+       BigNumDigit     beta3q[PrimeSize];
+       BigNumDigit     beta2p[PrimeSize];
+       }  RSAKeyStorage ;      
+
+typedef struct {
+       int nl,el,pl,ql,dpl,dql;
+
+       BigNumDigit     n[PrimeSize*2];
+       BigNumDigit     e[PrimeSize*2];
+       BigNumDigit     nINV[PrimeSize*2];
+       BigNumDigit     beta2n[PrimeSize*2];
+       }  RSAPublicKeyStorage ;        
+
+#define PRIVATE_KEY_SIZE sizeof(RSAKeyStorage)
+#define PUBLIC_KEY_SIZE sizeof(RSAPublicKeyStorage)
+
+#endif
+
diff --git a/util/gdss/include/bigkeygen.h b/util/gdss/include/bigkeygen.h
new file mode 100644 (file)
index 0000000..b54a5fb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_BIGKEYGEN
+#define SPHINX_BIGKEYGEN
+
+
+int newRSAKey ();
+int Finishkey ();               /* fills in key structure based on primes, etc. */
+int TestRSAKeys();
+int recover_private();          /* recover_private( deskey, input, len, rsakey) */
+int hide_private();             /* hide_private( deskey, **output, *len, rsakey) */
+int hide_privateP();            /* hide_privateP( deskey, **output, *len, rsakey) */
+int PrintTestKey();
+int PrintPubKey();
+#endif
+
diff --git a/util/gdss/include/bigrsacode.h b/util/gdss/include/bigrsacode.h
new file mode 100644 (file)
index 0000000..aade431
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_BIGRSACODE
+#define SPHINX_BIGRSACODE
+
+int NumEncodeLengthOctets (); 
+unsigned char *EncodeLength ();
+int NumEncodeValueOctets();
+unsigned char *EncodeBigIntegerValue ();
+unsigned char *EncodePublic();
+void FreePublic();
+unsigned char *EncodePrivate();
+unsigned char *EncodePrivateP();
+void FreePrivate();
+int DecodeValueLength ();
+int DecodeHeaderLength ();
+int DecodeTypeLength ();
+int DecodeTotalLength ();
+unsigned char *DecodeBigInteger ();
+unsigned char *DecodePublic ();
+unsigned char *DecodePrivate ();
+unsigned char *DecodePrivateP ();
+
+#endif
+
diff --git a/util/gdss/include/bigsignverify.h b/util/gdss/include/bigsignverify.h
new file mode 100644 (file)
index 0000000..21f948d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_BIGSIGNVERIFY
+#define SPHINX_BIGSIGNVERIFY
+
+#include "random.h"
+#include "BigZ.h"
+#include "BigRSA.h"
+
+int RSASign ();
+/*
+int RSASign (toBeSigned, datalen, key, signature, siglen)
+RSAKeyStorage *key;
+unsigned char *toBeSigned, *signature;
+int datalen, *siglen;
+*/
+
+int RSAVerify ();
+/*
+int RSAVerify (allegedSigned, datalen, key, signature, siglen)
+RSAKeyStorage *key;
+char *allegedSigned, *signature;
+int datalen, siglen;
+*/
+
+#define MAX_INIT_AUTH 2*DigitLim*sizeof(BigNumDigit)
+
+int InitAuthenticationKey ();
+int AcceptAuthenticationKey ();
+
+#endif
+
diff --git a/util/gdss/include/digital-copyright.h b/util/gdss/include/digital-copyright.h
new file mode 100644 (file)
index 0000000..bed3a20
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */ 
diff --git a/util/gdss/include/gdss.h b/util/gdss/include/gdss.h
new file mode 100644 (file)
index 0000000..b74afa0
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Include file for GDSS The Generic Digital Signature Service.
+ *
+ */
+#ifdef SOLARIS
+#include <string.h>
+#endif
+
+/* Structures Needed */
+
+typedef struct {
+       int     SigInfoVersion;
+       char    pname[ANAME_SZ];
+       char    pinst[INST_SZ];
+       char    prealm[REALM_SZ];
+       unsigned int    timestamp;
+       unsigned char *rawsig;  /* Raw Signature Bytes */
+} SigInfo;
+
+/* GDSS Errors */
+
+#define GDSS_SUCCESS   0       /* No error */
+#define GDSS_E_BADSIG  -1      /* Signature failed to verify */
+#define GDSS_E_NOPUBKEY -2     /* Couldn't find public key file */
+#define GDSS_E_KRBFAIL -3      /* Generic Kerberos error during sign */
+#define GDSS_E_NOSOCKET        -4      /* socket() call failed during sign */
+#define GDSS_E_NOCONNECT -5    /* connect() call failed during sign */
+#define GDSS_E_TIMEDOUT        -6      /* timed out contacting gdss sign server */
+#define GDSS_E_PADTOOMANY -7   /* Padding required to much space */
+#define GDSS_E_ALLOC   -8      /* malloc() failed to allocate memory */
+#define GDSS_E_BVERSION -9     /* Bad version ID in signature */
+#define GDSS_E_BADINPUT -10    /* Bad input value to Recompose */
+
+/* GDSS Constants */
+
+#define GDSS_PAD       10      /* Maximum number of nulls to pad */
+#define GDSS_ESCAPE    0x20    /* Escape character for padding */
+#define GDSS_NULL      0x21    /* Psuedo Null character */
diff --git a/util/gdss/include/hashes.h b/util/gdss/include/hashes.h
new file mode 100644 (file)
index 0000000..a9ac0c9
--- /dev/null
@@ -0,0 +1,60 @@
+/* hashes.h */
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+
+/*
+ * Externally Callable Routines. All arguments are character pointers
+ * or integer lengths.
+ */
+
+#ifndef SPHINX_HASHES
+#define SPHINX_HASHES
+
+void RSA_MD2();         /* RSA_MD2(input_buffer, length, hash_result) */
+void RSA_MD4();         /* RSA_MD4(input_buffer, length, hash_result) */
+void RSA_MAC();         /* RSA_MAC(input_buffer, length, mac, output_length) */
+void RSA_MD();          /* RSA_MD(input_buffer, length, hash_result) */
+
+int H1();               /* H1(username, password, hash_result) */
+int H2();               /* H2(username, password, hash_result) */
+
+/*
+ * Common data structures
+ */
+#define MAC_BLOCK_SIZE 8
+#define MD_BLOCK_SIZE  16
+
+
+#endif
+
diff --git a/util/gdss/include/key_perm.h b/util/gdss/include/key_perm.h
new file mode 100644 (file)
index 0000000..873e82b
--- /dev/null
@@ -0,0 +1,100 @@
+/* This file is automatically generated.  Do not edit it. */
+static int const key_perm[16][48] = {
+    /* ks permutation iteration =  1 */
+    14, 53, 38, 60, 55, 23, 39, 63, 
+    6, 15, 21, 46, 5, 37, 30, 31, 
+    44, 62, 61, 7, 36, 29, 22, 47, 
+    18, 28, 33, 50, 35, 4, 41, 26, 
+    3, 51, 17, 27, 59, 19, 34, 57, 
+    9, 20, 43, 10, 11, 58, 49, 25,     /* ks permutation iteration =  2 */
+    6, 45, 30, 52, 47, 15, 31, 55, 
+    61, 7, 13, 38, 60, 29, 22, 23, 
+    36, 54, 53, 62, 63, 21, 14, 39, 
+    10, 20, 25, 42, 27, 57, 33, 18, 
+    28, 43, 9, 19, 51, 11, 26, 49, 
+    1, 12, 35, 2, 3, 50, 41, 17,     /* ks permutation iteration =  3 */
+    53, 29, 14, 36, 31, 62, 15, 39, 
+    45, 54, 60, 22, 44, 13, 6, 7, 
+    55, 38, 37, 46, 47, 5, 61, 23, 
+    59, 4, 9, 26, 11, 41, 17, 2, 
+    12, 27, 58, 3, 35, 28, 10, 33, 
+    50, 57, 19, 51, 20, 34, 25, 1,     /* ks permutation iteration =  4 */
+    37, 13, 61, 55, 15, 46, 62, 23, 
+    29, 38, 44, 6, 63, 60, 53, 54, 
+    39, 22, 21, 30, 31, 52, 45, 7, 
+    43, 49, 58, 10, 28, 25, 1, 51, 
+    57, 11, 42, 20, 19, 12, 59, 17, 
+    34, 41, 3, 35, 4, 18, 9, 50,     /* ks permutation iteration =  5 */
+    21, 60, 45, 39, 62, 30, 46, 7, 
+    13, 22, 63, 53, 47, 44, 37, 38, 
+    23, 6, 5, 14, 15, 36, 29, 54, 
+    27, 33, 42, 59, 12, 9, 50, 35, 
+    41, 28, 26, 4, 3, 57, 43, 1, 
+    18, 25, 20, 19, 49, 2, 58, 34,     /* ks permutation iteration =  6 */
+    5, 44, 29, 23, 46, 14, 30, 54, 
+    60, 6, 47, 37, 31, 63, 21, 22, 
+    7, 53, 52, 61, 62, 55, 13, 38, 
+    11, 17, 26, 43, 57, 58, 34, 19, 
+    25, 12, 10, 49, 20, 41, 27, 50, 
+    2, 9, 4, 3, 33, 51, 42, 18,     /* ks permutation iteration =  7 */
+    52, 63, 13, 7, 30, 61, 14, 38, 
+    44, 53, 31, 21, 15, 47, 5, 6, 
+    54, 37, 36, 45, 46, 39, 60, 22, 
+    28, 1, 10, 27, 41, 42, 18, 3, 
+    9, 57, 59, 33, 4, 25, 11, 34, 
+    51, 58, 49, 20, 17, 35, 26, 2,     /* ks permutation iteration =  8 */
+    36, 47, 60, 54, 14, 45, 61, 22, 
+    63, 37, 15, 5, 62, 31, 52, 53, 
+    38, 21, 55, 29, 30, 23, 44, 6, 
+    12, 50, 59, 11, 25, 26, 2, 20, 
+    58, 41, 43, 17, 49, 9, 28, 18, 
+    35, 42, 33, 4, 1, 19, 10, 51,     /* ks permutation iteration =  9 */
+    63, 39, 52, 46, 6, 37, 53, 14, 
+    55, 29, 7, 60, 54, 23, 44, 45, 
+    30, 13, 47, 21, 22, 15, 36, 61, 
+    4, 42, 51, 3, 17, 18, 59, 12, 
+    50, 33, 35, 9, 41, 1, 20, 10, 
+    27, 34, 25, 57, 58, 11, 2, 43,     /* ks permutation iteration = 10 */
+    47, 23, 36, 30, 53, 21, 37, 61, 
+    39, 13, 54, 44, 38, 7, 63, 29, 
+    14, 60, 31, 5, 6, 62, 55, 45, 
+    49, 26, 35, 20, 1, 2, 43, 57, 
+    34, 17, 19, 58, 25, 50, 4, 59, 
+    11, 18, 9, 41, 42, 28, 51, 27,     /* ks permutation iteration = 11 */
+    31, 7, 55, 14, 37, 5, 21, 45, 
+    23, 60, 38, 63, 22, 54, 47, 13, 
+    61, 44, 15, 52, 53, 46, 39, 29, 
+    33, 10, 19, 4, 50, 51, 27, 41, 
+    18, 1, 3, 42, 9, 34, 49, 43, 
+    28, 2, 58, 25, 26, 12, 35, 11,     /* ks permutation iteration = 12 */
+    15, 54, 39, 61, 21, 52, 5, 29, 
+    7, 44, 22, 47, 6, 38, 31, 60, 
+    45, 63, 62, 36, 37, 30, 23, 13, 
+    17, 59, 3, 49, 34, 35, 11, 25, 
+    2, 50, 20, 26, 58, 18, 33, 27, 
+    12, 51, 42, 9, 10, 57, 19, 28,     /* ks permutation iteration = 13 */
+    62, 38, 23, 45, 5, 36, 52, 13, 
+    54, 63, 6, 31, 53, 22, 15, 44, 
+    29, 47, 46, 55, 21, 14, 7, 60, 
+    1, 43, 20, 33, 18, 19, 28, 9, 
+    51, 34, 4, 10, 42, 2, 17, 11, 
+    57, 35, 26, 58, 59, 41, 3, 12,     /* ks permutation iteration = 14 */
+    46, 22, 7, 29, 52, 55, 36, 60, 
+    38, 47, 53, 15, 37, 6, 62, 63, 
+    13, 31, 30, 39, 5, 61, 54, 44, 
+    50, 27, 4, 17, 2, 3, 12, 58, 
+    35, 18, 49, 59, 26, 51, 1, 28, 
+    41, 19, 10, 42, 43, 25, 20, 57,     /* ks permutation iteration = 15 */
+    30, 6, 54, 13, 36, 39, 55, 44, 
+    22, 31, 37, 62, 21, 53, 46, 47, 
+    60, 15, 14, 23, 52, 45, 38, 63, 
+    34, 11, 49, 1, 51, 20, 57, 42, 
+    19, 2, 33, 43, 10, 35, 50, 12, 
+    25, 3, 59, 26, 27, 9, 4, 41,     /* ks permutation iteration = 16 */
+    22, 61, 46, 5, 63, 31, 47, 36, 
+    14, 23, 29, 54, 13, 45, 38, 39, 
+    52, 7, 6, 15, 44, 37, 30, 55, 
+    26, 3, 41, 58, 43, 12, 49, 34, 
+    11, 59, 25, 35, 2, 27, 42, 4, 
+    17, 28, 51, 18, 19, 1, 57, 33
+};
diff --git a/util/gdss/include/odd.h b/util/gdss/include/odd.h
new file mode 100644 (file)
index 0000000..5dca557
--- /dev/null
@@ -0,0 +1,35 @@
+/* This file is automatically generated.  Do not edit it. */
+static unsigned char const odd_parity[256] = {
+  1, 
+  1,   2,   2,   4,   4,   7,   7,   8, 
+  8,  11,  11,  13,  13,  14,  14,  16, 
+ 16,  19,  19,  21,  21,  22,  22,  25, 
+ 25,  26,  26,  28,  28,  31,  31,  32, 
+ 32,  35,  35,  37,  37,  38,  38,  41, 
+ 41,  42,  42,  44,  44,  47,  47,  49, 
+ 49,  50,  50,  52,  52,  55,  55,  56, 
+ 56,  59,  59,  61,  61,  62,  62,  64, 
+ 64,  67,  67,  69,  69,  70,  70,  73, 
+ 73,  74,  74,  76,  76,  79,  79,  81, 
+ 81,  82,  82,  84,  84,  87,  87,  88, 
+ 88,  91,  91,  93,  93,  94,  94,  97, 
+ 97,  98,  98, 100, 100, 103, 103, 104, 
+104, 107, 107, 109, 109, 110, 110, 112, 
+112, 115, 115, 117, 117, 118, 118, 121, 
+121, 122, 122, 124, 124, 127, 127, 128, 
+128, 131, 131, 133, 133, 134, 134, 137, 
+137, 138, 138, 140, 140, 143, 143, 145, 
+145, 146, 146, 148, 148, 151, 151, 152, 
+152, 155, 155, 157, 157, 158, 158, 161, 
+161, 162, 162, 164, 164, 167, 167, 168, 
+168, 171, 171, 173, 173, 174, 174, 176, 
+176, 179, 179, 181, 181, 182, 182, 185, 
+185, 186, 186, 188, 188, 191, 191, 193, 
+193, 194, 194, 196, 196, 199, 199, 200, 
+200, 203, 203, 205, 205, 206, 206, 208, 
+208, 211, 211, 213, 213, 214, 214, 217, 
+217, 218, 218, 220, 220, 223, 223, 224, 
+224, 227, 227, 229, 229, 230, 230, 233, 
+233, 234, 234, 236, 236, 239, 239, 241, 
+241, 242, 242, 244, 244, 247, 247, 248, 
+248, 251, 251, 253, 253, 254, 254};
diff --git a/util/gdss/include/p_table.h b/util/gdss/include/p_table.h
new file mode 100644 (file)
index 0000000..72722eb
--- /dev/null
@@ -0,0 +1,265 @@
+/* This file is automatically generated.  Do not edit it. */
+
+       static unsigned long const P_prime[4][256] = {
+       
+
+0x00000000, 0x00000100, 0x00010000, 0x00010100, 
+0x00400000, 0x00400100, 0x00410000, 0x00410100, 
+0x40000000, 0x40000100, 0x40010000, 0x40010100, 
+0x40400000, 0x40400100, 0x40410000, 0x40410100, 
+0x00001000, 0x00001100, 0x00011000, 0x00011100, 
+0x00401000, 0x00401100, 0x00411000, 0x00411100, 
+0x40001000, 0x40001100, 0x40011000, 0x40011100, 
+0x40401000, 0x40401100, 0x40411000, 0x40411100, 
+0x08000000, 0x08000100, 0x08010000, 0x08010100, 
+0x08400000, 0x08400100, 0x08410000, 0x08410100, 
+0x48000000, 0x48000100, 0x48010000, 0x48010100, 
+0x48400000, 0x48400100, 0x48410000, 0x48410100, 
+0x08001000, 0x08001100, 0x08011000, 0x08011100, 
+0x08401000, 0x08401100, 0x08411000, 0x08411100, 
+0x48001000, 0x48001100, 0x48011000, 0x48011100, 
+0x48401000, 0x48401100, 0x48411000, 0x48411100, 
+0x00000002, 0x00000102, 0x00010002, 0x00010102, 
+0x00400002, 0x00400102, 0x00410002, 0x00410102, 
+0x40000002, 0x40000102, 0x40010002, 0x40010102, 
+0x40400002, 0x40400102, 0x40410002, 0x40410102, 
+0x00001002, 0x00001102, 0x00011002, 0x00011102, 
+0x00401002, 0x00401102, 0x00411002, 0x00411102, 
+0x40001002, 0x40001102, 0x40011002, 0x40011102, 
+0x40401002, 0x40401102, 0x40411002, 0x40411102, 
+0x08000002, 0x08000102, 0x08010002, 0x08010102, 
+0x08400002, 0x08400102, 0x08410002, 0x08410102, 
+0x48000002, 0x48000102, 0x48010002, 0x48010102, 
+0x48400002, 0x48400102, 0x48410002, 0x48410102, 
+0x08001002, 0x08001102, 0x08011002, 0x08011102, 
+0x08401002, 0x08401102, 0x08411002, 0x08411102, 
+0x48001002, 0x48001102, 0x48011002, 0x48011102, 
+0x48401002, 0x48401102, 0x48411002, 0x48411102, 
+0x00020000, 0x00020100, 0x00030000, 0x00030100, 
+0x00420000, 0x00420100, 0x00430000, 0x00430100, 
+0x40020000, 0x40020100, 0x40030000, 0x40030100, 
+0x40420000, 0x40420100, 0x40430000, 0x40430100, 
+0x00021000, 0x00021100, 0x00031000, 0x00031100, 
+0x00421000, 0x00421100, 0x00431000, 0x00431100, 
+0x40021000, 0x40021100, 0x40031000, 0x40031100, 
+0x40421000, 0x40421100, 0x40431000, 0x40431100, 
+0x08020000, 0x08020100, 0x08030000, 0x08030100, 
+0x08420000, 0x08420100, 0x08430000, 0x08430100, 
+0x48020000, 0x48020100, 0x48030000, 0x48030100, 
+0x48420000, 0x48420100, 0x48430000, 0x48430100, 
+0x08021000, 0x08021100, 0x08031000, 0x08031100, 
+0x08421000, 0x08421100, 0x08431000, 0x08431100, 
+0x48021000, 0x48021100, 0x48031000, 0x48031100, 
+0x48421000, 0x48421100, 0x48431000, 0x48431100, 
+0x00020002, 0x00020102, 0x00030002, 0x00030102, 
+0x00420002, 0x00420102, 0x00430002, 0x00430102, 
+0x40020002, 0x40020102, 0x40030002, 0x40030102, 
+0x40420002, 0x40420102, 0x40430002, 0x40430102, 
+0x00021002, 0x00021102, 0x00031002, 0x00031102, 
+0x00421002, 0x00421102, 0x00431002, 0x00431102, 
+0x40021002, 0x40021102, 0x40031002, 0x40031102, 
+0x40421002, 0x40421102, 0x40431002, 0x40431102, 
+0x08020002, 0x08020102, 0x08030002, 0x08030102, 
+0x08420002, 0x08420102, 0x08430002, 0x08430102, 
+0x48020002, 0x48020102, 0x48030002, 0x48030102, 
+0x48420002, 0x48420102, 0x48430002, 0x48430102, 
+0x08021002, 0x08021102, 0x08031002, 0x08031102, 
+0x08421002, 0x08421102, 0x08431002, 0x08431102, 
+0x48021002, 0x48021102, 0x48031002, 0x48031102, 
+0x48421002, 0x48421102, 0x48431002, 0x48431102, 
+
+0x00000000, 0x00800000, 0x00008000, 0x00808000, 
+0x20000000, 0x20800000, 0x20008000, 0x20808000, 
+0x00000020, 0x00800020, 0x00008020, 0x00808020, 
+0x20000020, 0x20800020, 0x20008020, 0x20808020, 
+0x02000000, 0x02800000, 0x02008000, 0x02808000, 
+0x22000000, 0x22800000, 0x22008000, 0x22808000, 
+0x02000020, 0x02800020, 0x02008020, 0x02808020, 
+0x22000020, 0x22800020, 0x22008020, 0x22808020, 
+0x00080000, 0x00880000, 0x00088000, 0x00888000, 
+0x20080000, 0x20880000, 0x20088000, 0x20888000, 
+0x00080020, 0x00880020, 0x00088020, 0x00888020, 
+0x20080020, 0x20880020, 0x20088020, 0x20888020, 
+0x02080000, 0x02880000, 0x02088000, 0x02888000, 
+0x22080000, 0x22880000, 0x22088000, 0x22888000, 
+0x02080020, 0x02880020, 0x02088020, 0x02888020, 
+0x22080020, 0x22880020, 0x22088020, 0x22888020, 
+0x00000200, 0x00800200, 0x00008200, 0x00808200, 
+0x20000200, 0x20800200, 0x20008200, 0x20808200, 
+0x00000220, 0x00800220, 0x00008220, 0x00808220, 
+0x20000220, 0x20800220, 0x20008220, 0x20808220, 
+0x02000200, 0x02800200, 0x02008200, 0x02808200, 
+0x22000200, 0x22800200, 0x22008200, 0x22808200, 
+0x02000220, 0x02800220, 0x02008220, 0x02808220, 
+0x22000220, 0x22800220, 0x22008220, 0x22808220, 
+0x00080200, 0x00880200, 0x00088200, 0x00888200, 
+0x20080200, 0x20880200, 0x20088200, 0x20888200, 
+0x00080220, 0x00880220, 0x00088220, 0x00888220, 
+0x20080220, 0x20880220, 0x20088220, 0x20888220, 
+0x02080200, 0x02880200, 0x02088200, 0x02888200, 
+0x22080200, 0x22880200, 0x22088200, 0x22888200, 
+0x02080220, 0x02880220, 0x02088220, 0x02888220, 
+0x22080220, 0x22880220, 0x22088220, 0x22888220, 
+0x00000001, 0x00800001, 0x00008001, 0x00808001, 
+0x20000001, 0x20800001, 0x20008001, 0x20808001, 
+0x00000021, 0x00800021, 0x00008021, 0x00808021, 
+0x20000021, 0x20800021, 0x20008021, 0x20808021, 
+0x02000001, 0x02800001, 0x02008001, 0x02808001, 
+0x22000001, 0x22800001, 0x22008001, 0x22808001, 
+0x02000021, 0x02800021, 0x02008021, 0x02808021, 
+0x22000021, 0x22800021, 0x22008021, 0x22808021, 
+0x00080001, 0x00880001, 0x00088001, 0x00888001, 
+0x20080001, 0x20880001, 0x20088001, 0x20888001, 
+0x00080021, 0x00880021, 0x00088021, 0x00888021, 
+0x20080021, 0x20880021, 0x20088021, 0x20888021, 
+0x02080001, 0x02880001, 0x02088001, 0x02888001, 
+0x22080001, 0x22880001, 0x22088001, 0x22888001, 
+0x02080021, 0x02880021, 0x02088021, 0x02888021, 
+0x22080021, 0x22880021, 0x22088021, 0x22888021, 
+0x00000201, 0x00800201, 0x00008201, 0x00808201, 
+0x20000201, 0x20800201, 0x20008201, 0x20808201, 
+0x00000221, 0x00800221, 0x00008221, 0x00808221, 
+0x20000221, 0x20800221, 0x20008221, 0x20808221, 
+0x02000201, 0x02800201, 0x02008201, 0x02808201, 
+0x22000201, 0x22800201, 0x22008201, 0x22808201, 
+0x02000221, 0x02800221, 0x02008221, 0x02808221, 
+0x22000221, 0x22800221, 0x22008221, 0x22808221, 
+0x00080201, 0x00880201, 0x00088201, 0x00888201, 
+0x20080201, 0x20880201, 0x20088201, 0x20888201, 
+0x00080221, 0x00880221, 0x00088221, 0x00888221, 
+0x20080221, 0x20880221, 0x20088221, 0x20888221, 
+0x02080201, 0x02880201, 0x02088201, 0x02888201, 
+0x22080201, 0x22880201, 0x22088201, 0x22888201, 
+0x02080221, 0x02880221, 0x02088221, 0x02888221, 
+0x22080221, 0x22880221, 0x22088221, 0x22888221, 
+
+0x00000000, 0x00000080, 0x00002000, 0x00002080, 
+0x01000000, 0x01000080, 0x01002000, 0x01002080, 
+0x00000004, 0x00000084, 0x00002004, 0x00002084, 
+0x01000004, 0x01000084, 0x01002004, 0x01002084, 
+0x00000008, 0x00000088, 0x00002008, 0x00002088, 
+0x01000008, 0x01000088, 0x01002008, 0x01002088, 
+0x0000000C, 0x0000008C, 0x0000200C, 0x0000208C, 
+0x0100000C, 0x0100008C, 0x0100200C, 0x0100208C, 
+0x10000000, 0x10000080, 0x10002000, 0x10002080, 
+0x11000000, 0x11000080, 0x11002000, 0x11002080, 
+0x10000004, 0x10000084, 0x10002004, 0x10002084, 
+0x11000004, 0x11000084, 0x11002004, 0x11002084, 
+0x10000008, 0x10000088, 0x10002008, 0x10002088, 
+0x11000008, 0x11000088, 0x11002008, 0x11002088, 
+0x1000000C, 0x1000008C, 0x1000200C, 0x1000208C, 
+0x1100000C, 0x1100008C, 0x1100200C, 0x1100208C, 
+0x00000400, 0x00000480, 0x00002400, 0x00002480, 
+0x01000400, 0x01000480, 0x01002400, 0x01002480, 
+0x00000404, 0x00000484, 0x00002404, 0x00002484, 
+0x01000404, 0x01000484, 0x01002404, 0x01002484, 
+0x00000408, 0x00000488, 0x00002408, 0x00002488, 
+0x01000408, 0x01000488, 0x01002408, 0x01002488, 
+0x0000040C, 0x0000048C, 0x0000240C, 0x0000248C, 
+0x0100040C, 0x0100048C, 0x0100240C, 0x0100248C, 
+0x10000400, 0x10000480, 0x10002400, 0x10002480, 
+0x11000400, 0x11000480, 0x11002400, 0x11002480, 
+0x10000404, 0x10000484, 0x10002404, 0x10002484, 
+0x11000404, 0x11000484, 0x11002404, 0x11002484, 
+0x10000408, 0x10000488, 0x10002408, 0x10002488, 
+0x11000408, 0x11000488, 0x11002408, 0x11002488, 
+0x1000040C, 0x1000048C, 0x1000240C, 0x1000248C, 
+0x1100040C, 0x1100048C, 0x1100240C, 0x1100248C, 
+0x00040000, 0x00040080, 0x00042000, 0x00042080, 
+0x01040000, 0x01040080, 0x01042000, 0x01042080, 
+0x00040004, 0x00040084, 0x00042004, 0x00042084, 
+0x01040004, 0x01040084, 0x01042004, 0x01042084, 
+0x00040008, 0x00040088, 0x00042008, 0x00042088, 
+0x01040008, 0x01040088, 0x01042008, 0x01042088, 
+0x0004000C, 0x0004008C, 0x0004200C, 0x0004208C, 
+0x0104000C, 0x0104008C, 0x0104200C, 0x0104208C, 
+0x10040000, 0x10040080, 0x10042000, 0x10042080, 
+0x11040000, 0x11040080, 0x11042000, 0x11042080, 
+0x10040004, 0x10040084, 0x10042004, 0x10042084, 
+0x11040004, 0x11040084, 0x11042004, 0x11042084, 
+0x10040008, 0x10040088, 0x10042008, 0x10042088, 
+0x11040008, 0x11040088, 0x11042008, 0x11042088, 
+0x1004000C, 0x1004008C, 0x1004200C, 0x1004208C, 
+0x1104000C, 0x1104008C, 0x1104200C, 0x1104208C, 
+0x00040400, 0x00040480, 0x00042400, 0x00042480, 
+0x01040400, 0x01040480, 0x01042400, 0x01042480, 
+0x00040404, 0x00040484, 0x00042404, 0x00042484, 
+0x01040404, 0x01040484, 0x01042404, 0x01042484, 
+0x00040408, 0x00040488, 0x00042408, 0x00042488, 
+0x01040408, 0x01040488, 0x01042408, 0x01042488, 
+0x0004040C, 0x0004048C, 0x0004240C, 0x0004248C, 
+0x0104040C, 0x0104048C, 0x0104240C, 0x0104248C, 
+0x10040400, 0x10040480, 0x10042400, 0x10042480, 
+0x11040400, 0x11040480, 0x11042400, 0x11042480, 
+0x10040404, 0x10040484, 0x10042404, 0x10042484, 
+0x11040404, 0x11040484, 0x11042404, 0x11042484, 
+0x10040408, 0x10040488, 0x10042408, 0x10042488, 
+0x11040408, 0x11040488, 0x11042408, 0x11042488, 
+0x1004040C, 0x1004048C, 0x1004240C, 0x1004248C, 
+0x1104040C, 0x1104048C, 0x1104240C, 0x1104248C, 
+
+0x00000000, 0x80000000, 0x00000800, 0x80000800, 
+0x00200000, 0x80200000, 0x00200800, 0x80200800, 
+0x00000040, 0x80000040, 0x00000840, 0x80000840, 
+0x00200040, 0x80200040, 0x00200840, 0x80200840, 
+0x00000010, 0x80000010, 0x00000810, 0x80000810, 
+0x00200010, 0x80200010, 0x00200810, 0x80200810, 
+0x00000050, 0x80000050, 0x00000850, 0x80000850, 
+0x00200050, 0x80200050, 0x00200850, 0x80200850, 
+0x04000000, 0x84000000, 0x04000800, 0x84000800, 
+0x04200000, 0x84200000, 0x04200800, 0x84200800, 
+0x04000040, 0x84000040, 0x04000840, 0x84000840, 
+0x04200040, 0x84200040, 0x04200840, 0x84200840, 
+0x04000010, 0x84000010, 0x04000810, 0x84000810, 
+0x04200010, 0x84200010, 0x04200810, 0x84200810, 
+0x04000050, 0x84000050, 0x04000850, 0x84000850, 
+0x04200050, 0x84200050, 0x04200850, 0x84200850, 
+0x00004000, 0x80004000, 0x00004800, 0x80004800, 
+0x00204000, 0x80204000, 0x00204800, 0x80204800, 
+0x00004040, 0x80004040, 0x00004840, 0x80004840, 
+0x00204040, 0x80204040, 0x00204840, 0x80204840, 
+0x00004010, 0x80004010, 0x00004810, 0x80004810, 
+0x00204010, 0x80204010, 0x00204810, 0x80204810, 
+0x00004050, 0x80004050, 0x00004850, 0x80004850, 
+0x00204050, 0x80204050, 0x00204850, 0x80204850, 
+0x04004000, 0x84004000, 0x04004800, 0x84004800, 
+0x04204000, 0x84204000, 0x04204800, 0x84204800, 
+0x04004040, 0x84004040, 0x04004840, 0x84004840, 
+0x04204040, 0x84204040, 0x04204840, 0x84204840, 
+0x04004010, 0x84004010, 0x04004810, 0x84004810, 
+0x04204010, 0x84204010, 0x04204810, 0x84204810, 
+0x04004050, 0x84004050, 0x04004850, 0x84004850, 
+0x04204050, 0x84204050, 0x04204850, 0x84204850, 
+0x00100000, 0x80100000, 0x00100800, 0x80100800, 
+0x00300000, 0x80300000, 0x00300800, 0x80300800, 
+0x00100040, 0x80100040, 0x00100840, 0x80100840, 
+0x00300040, 0x80300040, 0x00300840, 0x80300840, 
+0x00100010, 0x80100010, 0x00100810, 0x80100810, 
+0x00300010, 0x80300010, 0x00300810, 0x80300810, 
+0x00100050, 0x80100050, 0x00100850, 0x80100850, 
+0x00300050, 0x80300050, 0x00300850, 0x80300850, 
+0x04100000, 0x84100000, 0x04100800, 0x84100800, 
+0x04300000, 0x84300000, 0x04300800, 0x84300800, 
+0x04100040, 0x84100040, 0x04100840, 0x84100840, 
+0x04300040, 0x84300040, 0x04300840, 0x84300840, 
+0x04100010, 0x84100010, 0x04100810, 0x84100810, 
+0x04300010, 0x84300010, 0x04300810, 0x84300810, 
+0x04100050, 0x84100050, 0x04100850, 0x84100850, 
+0x04300050, 0x84300050, 0x04300850, 0x84300850, 
+0x00104000, 0x80104000, 0x00104800, 0x80104800, 
+0x00304000, 0x80304000, 0x00304800, 0x80304800, 
+0x00104040, 0x80104040, 0x00104840, 0x80104840, 
+0x00304040, 0x80304040, 0x00304840, 0x80304840, 
+0x00104010, 0x80104010, 0x00104810, 0x80104810, 
+0x00304010, 0x80304010, 0x00304810, 0x80304810, 
+0x00104050, 0x80104050, 0x00104850, 0x80104850, 
+0x00304050, 0x80304050, 0x00304850, 0x80304850, 
+0x04104000, 0x84104000, 0x04104800, 0x84104800, 
+0x04304000, 0x84304000, 0x04304800, 0x84304800, 
+0x04104040, 0x84104040, 0x04104840, 0x84104840, 
+0x04304040, 0x84304040, 0x04304840, 0x84304840, 
+0x04104010, 0x84104010, 0x04104810, 0x84104810, 
+0x04304010, 0x84304010, 0x04304810, 0x84304810, 
+0x04104050, 0x84104050, 0x04104850, 0x84104850, 
+0x04304050, 0x84304050, 0x04304850, 0x84304850
+};
diff --git a/util/gdss/include/pamrm.h b/util/gdss/include/pamrm.h
new file mode 100644 (file)
index 0000000..794cf2a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#define rword(num,i) (8*num+i)
+#define R_m 31
+#define R_mINV 30
+#define R_mbeta 29
+
+#define R_0 16
+#define R_sq 17
+#define R_j 18
+#define R_a 19
+#define R_x 20
+#define R_q 21
+#define R_s0 22
+#define R_s1 23
+
+/* multiply read at odd halfword address */
+/* charge write at odd halfword address */
+#define charge(ra,rs0,rp1) (1 | ra << 1 | rs0 << 6 | rp1 << 11)
+#define mult(rb,rs1,rp0)   (1 | rb << 1 | rs1 << 6 | rp0 << 11)
diff --git a/util/gdss/include/random.h b/util/gdss/include/random.h
new file mode 100644 (file)
index 0000000..d6f960d
--- /dev/null
@@ -0,0 +1,62 @@
+/* random.h */
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_RANDOM
+#define SPHINX_RANDOM
+
+typedef unsigned long  INT32;          /* 32-bit unsigned integer */
+
+typedef union 
+{                                      /* data type for the DES blocks */
+    unsigned char      bytes[8];       /* for access as bytes */
+    INT32              longwords[2];   /* for access as longwords */
+} DESblock;
+
+#define DES_BLOCK_SIZE sizeof(DESblock)
+
+typedef struct {
+        int count ;
+        DESblock seed , key , current;
+        }  RNGState ;
+
+#define RNG_STATE_SIZE sizeof(RNGState) 
+void read_rng_state ();
+void restore_rng_state ();
+void initialize_rng_state ();
+void random_bytes ();
+void DES_X9_MAC();      /* DES_X9_MAC(key,input_buffer, length, hash_result) */
+
+#endif
+
diff --git a/util/gdss/include/read_password.h b/util/gdss/include/read_password.h
new file mode 100644 (file)
index 0000000..3ce8ac1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_READ_PASSWORD
+#define SPHINX_READ_PASSWORD
+
+#include "hashes.h"
+
+int DES_read_password();
+int DES_read_password_hash();
+
+#endif
diff --git a/util/gdss/lib/Imakefile b/util/gdss/lib/Imakefile
new file mode 100644 (file)
index 0000000..7e0b649
--- /dev/null
@@ -0,0 +1,21 @@
+/* $Header$ */
+
+SUBDIRS = crypto
+
+OBJS = gdss.o rgdss.o
+COBJS = crypto/hashes.o crypto/read_password.o crypto/crypto_util.o \
+       crypto/dumphex.o crypto/read_privkey.o crypto/read_pubkey.o \
+       crypto/write_pubkey.o crypto/KeyFromPQ.o
+BOBJS = crypto/bignum/o/KerN.o crypto/bignum/o/bnCmp.o \
+       crypto/bignum/o/bnDivide.o crypto/bignum/o/bnInit.o \
+       crypto/bignum/o/bnMult.o crypto/bignum/o/bz.o crypto/bignum/o/bzf.o 
+AOBJS = crypto/algorithm/random.o crypto/algorithm/random_BigNum.o \
+       crypto/algorithm/bigrsacode.o crypto/algorithm/bigkeygen.o \
+       crypto/algorithm/bigsignverify.o
+
+DEFINES = -I. -I../include -I./crypto/bignum/h -I./crypto/algorithm
+
+do_subdirs($(SUBDIRS))
+
+library_obj_rule()
+install_library_target(gdss,$(OBJS) $(COBJS) $(BOBJS) $(AOBJS),)
diff --git a/util/gdss/lib/crypto/Imakefile b/util/gdss/lib/crypto/Imakefile
new file mode 100644 (file)
index 0000000..628d5c1
--- /dev/null
@@ -0,0 +1,17 @@
+/* $Header$ */
+
+#define have_subdirs
+SUBDIRS = algorithm bignum
+
+OBJS =  hashes.o \
+       read_password.o \
+       crypto_util.o \
+       dumphex.o \
+       read_privkey.o \
+       read_pubkey.o \
+       write_pubkey.o \
+       KeyFromPQ.o
+
+DEFINES = -I. -I../../include -Ibignum/h
+
+all:: $(OBJS)
diff --git a/util/gdss/lib/crypto/KeyFromPQ.c b/util/gdss/lib/crypto/KeyFromPQ.c
new file mode 100644 (file)
index 0000000..866735e
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "BigNum.h"
+#include "BigRSA.h"
+#include "bigrsacode.h"
+#include "bigkeygen.h"
+
+/* 
+#ifdef DEBUG
+#undef DEBUG
+#endif
+*/
+
+/* given two primes in msb-lsg order, initialize the key structure */
+
+int KeyFromPQ ( P, PL, Q, QL, keys )
+char *P, *Q;
+int PL, QL;
+RSAKeyStorage *keys ;
+{
+    BigNum  p = keys->p, q = keys->q ;
+    int i;
+    char *x, *y;
+    unsigned pl, ql;
+
+    memset(keys,0,sizeof(RSAKeyStorage));
+    BnnInit();
+
+    DecodeBigInteger(P, p, PL);
+    DecodeBigInteger(Q, q, QL);
+    pl = BnnNumDigits(p, (PL+sizeof(BigNumDigit))/sizeof(BigNumDigit));
+    ql = BnnNumDigits(q, (QL+sizeof(BigNumDigit))/sizeof(BigNumDigit));
+
+    if (BnnCompare(p, pl, q, ql) == -1) {
+        unsigned tpl = pl;
+        BigNumDigit tp[DigitLim];
+        BnnSetToZero(tp,DigitLim);
+        BnnAssign(tp,p,pl);
+        BnnSetToZero(p,pl);
+        BnnAssign(p,q,ql);
+        BnnAssign(q,tp,pl);
+        pl = ql;
+        ql = tpl;
+    }
+
+    keys->pl = pl;
+    keys->ql = ql;
+
+    BnnSetDigit(keys->e, (BigNumDigit) ((1<<16)+1));
+    keys->el = 1;
+
+    BnnMultiply(keys->n, pl+ql, p, pl, q, ql),
+    keys->nl = pl+ql;
+
+#ifdef DEBUG
+PrintTestKey(keys);
+#endif
+
+    if (FinishKey(keys)==0) return (0);
+
+    if (TestRSAKeys(keys)!=1) {
+#ifdef DEBUG
+printf("\nFailed.\n");
+#endif
+        return(0);
+    }  
+
+    BnnClose();
+    return(1);
+}
+
+
diff --git a/util/gdss/lib/crypto/algorithm/DEScrypto.h b/util/gdss/lib/crypto/algorithm/DEScrypto.h
new file mode 100644 (file)
index 0000000..0e31249
--- /dev/null
@@ -0,0 +1,517 @@
+/* DEScrypto.h */
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/* In-line include file for DES routines */
+
+#ifndef SPHINX_DESCRYPTO
+#define SPHINX_DESCRYPTO
+
+/*
+ *********************************************************************
+ *********************************************************************
+ **                                                                 **
+ **                       W A R N I N G                             **
+ **                                                                 **
+ **  This software is subject to export restrictions under the      **
+ **  U.S. Department of State's International Traffic in Arms       **
+ **  Regulations (ITAR).  This software must not be transmitted     **
+ **  in source form outside the United States or to a foreign       **
+ **  national in the United States without a valid U.S. State       **
+ **  Department export license.                                     **
+ **                                                                 **
+ *********************************************************************
+ *********************************************************************
+*/
+
+#ifndef SPHINX_ITAR
+#define SPHINX_ITAR
+static char copyright[] = "\n Copyright, 1989, 1990, Digital Equipment Corporation \n";
+static char warning[]= "\n  This software is subject to export restrictions under \
+\n  the U.S. Department of State's International Traffic in Arms \
+\n  Regulations (ITAR).  This software must not be transmitted \
+\n  in source form outside the United States or to a foreign \
+\n  national in the United States without a valid U.S. State \
+\n  Department export license. ";
+#endif
+
+#include "endian.h"
+#include "hashes.h"
+#include "random.h"
+#include "tables.h"
+
+static DESdecrypt_local();
+static DESencrypt_local();
+static void DES_load_key_local();
+static int DES_CBC_encrypt_local ();
+static int DES_CBC_decrypt_local ();
+
+typedef struct 
+{                                      /* DES key schedule */
+    unsigned char      subkey[16][8];  /* 8 6-bit subkeys per round */
+} KEYschedule;
+
+/*
+ * The following macros perform the initial and final permutations on a
+ * DES block. The output is accessed as 32-bit units and the input as 8-bit
+ * units.
+ *
+ * Note: These macros reference 2 permutation arrays (iperm and fperm) which
+ *      are machine generated and must be included with any program using
+ *      these macros.
+ */
+
+#define INITIAL(out, in) \
+    out[0] = iperma[in[0]] \
+            | (iperma[in[1]] << 1) \
+            | (iperma[in[2]] << 2) \
+            | (iperma[in[3]] << 3) \
+            | (iperma[in[4]] << 4) \
+            | (iperma[in[5]] << 5) \
+            | (iperma[in[6]] << 6) \
+            | (iperma[in[7]] << 7); \
+    out[1] = ipermb[in[0]] \
+            | (ipermb[in[1]] << 1) \
+            | (ipermb[in[2]] << 2) \
+            | (ipermb[in[3]] << 3) \
+            | (ipermb[in[4]] << 4) \
+            | (ipermb[in[5]] << 5) \
+            | (ipermb[in[6]] << 6) \
+            | (ipermb[in[7]] << 7)
+
+#if SPHINX_ENDIAN
+#define FINAL(out, in) \
+    out[0] = fperma[in[0]] \
+            | (fperma[in[4]] << 1) \
+            | (fperma[in[1]] << 2) \
+            | (fperma[in[5]] << 3) \
+            | (fperma[in[2]] << 4) \
+            | (fperma[in[6]] << 5) \
+            | (fperma[in[3]] << 6) \
+            | (fperma[in[7]] << 7); \
+    out[1] = fpermb[in[0]] \
+            | (fpermb[in[4]] << 1) \
+            | (fpermb[in[1]] << 2) \
+            | (fpermb[in[5]] << 3) \
+            | (fpermb[in[2]] << 4) \
+            | (fpermb[in[6]] << 5) \
+            | (fpermb[in[3]] << 6) \
+            | (fpermb[in[7]] << 7);
+#else
+#define FINAL(out, in) \
+    out[0] = fperma[in[3]] \
+            | (fperma[in[7]] << 1) \
+            | (fperma[in[2]] << 2) \
+            | (fperma[in[6]] << 3) \
+            | (fperma[in[1]] << 4) \
+            | (fperma[in[5]] << 5) \
+            | (fperma[in[0]] << 6) \
+            | (fperma[in[4]] << 7); \
+    out[1] = fpermb[in[3]] \
+            | (fpermb[in[7]] << 1) \
+            | (fpermb[in[2]] << 2) \
+            | (fpermb[in[6]] << 3) \
+            | (fpermb[in[1]] << 4) \
+            | (fpermb[in[5]] << 5) \
+            | (fpermb[in[0]] << 6) \
+            | (fpermb[in[4]] << 7);
+
+#endif /* SPHINX_ENDIAN */
+
+/*
+ * The following tables are taken directly from FIPS PUB 46 (Specifications
+ * for the Data Encryption Standard).
+ */
+
+/*
+ * Number of left rotations of pc1
+ */
+static char totrot[] = {
+       1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
+};
+
+/*
+ * Permuted choice key (table)
+ */
+static char pc2[] = {
+       14, 17, 11, 24,  1,  5,
+        3, 28, 15,  6, 21, 10,
+       23, 19, 12,  4, 26,  8,
+       16,  7, 27, 20, 13,  2,
+       41, 52, 31, 37, 47, 55,
+       30, 40, 51, 45, 33, 48,
+       44, 49, 39, 56, 34, 53,
+       46, 42, 50, 36, 29, 32
+};
+
+/*
+ * Note that the Standard is written in Big Endian terms so bit 1 is the
+ * high bit of the byte.
+ */
+static int bytebit[] = {
+    0200, 0100, 040, 020, 010, 04, 02, 01
+};
+
+/*
+ * Declare external and forward routines.
+ */
+
+\f
+/*
+ *
+ * Functional Description:
+ *
+ *     Perform a DES decryption of a single 8-byte block producing
+ *     another 8-byte block.
+ *
+ * Inputs:
+ *
+ *     indata  - Pointer to the input data
+ *
+ * Outputs:
+ *
+ *     outdata - Pointer to the output data
+ *
+ * Return Value:
+ *
+ *     None
+ *
+ */
+static DESdecrypt_local( indata,outdata,key_schedule )
+KEYschedule *key_schedule ;
+DESblock *indata,*outdata;
+{
+    register int i;
+    register INT32 er,out;
+    register unsigned char *subkey;
+    INT32 index;
+    DESblock temp;
+    
+    /*
+     * Perform the initial transformation.
+     */
+    INITIAL(temp.longwords, indata->bytes);
+
+    /*
+     * Now swap halves of the working block.
+     */
+    out = temp.longwords[0];
+    temp.longwords[0] = temp.longwords[1];
+    temp.longwords[1] = out;
+    
+    /*
+     * Perform the decryption operation.
+     */
+    for (i = 15; i >= 0; i--)
+    {
+       /*
+        * Select the subkey for this round.
+        */
+       subkey = key_schedule->subkey[i];
+
+       /*
+        * Compute the index value to be used for the first 7 subkeys.
+        */
+       index = temp.longwords[1 - (i & 1)];
+       er = (index >> 1) | ((index & 1) ? 0x80000000 : 0);
+       
+       /*
+        * Perform one round of E(input) ^ K through the combined S and
+        * P boxes.
+        */
+       out  = sp[0][((er >> 26) & 0x3F) ^ *subkey++];
+       out |= sp[1][((er >> 22) & 0x3F) ^ *subkey++];
+       out |= sp[2][((er >> 18) & 0x3F) ^ *subkey++];
+       out |= sp[3][((er >> 14) & 0x3F) ^ *subkey++];
+       out |= sp[4][((er >> 10) & 0x3F) ^ *subkey++];
+       out |= sp[5][((er >> 6) & 0x3F) ^ *subkey++];
+       out |= sp[6][((er >> 2) & 0x3F) ^ *subkey++];
+       er = (index << 1) | ((index & 0x80000000) ? 1 : 0);
+       out |= sp[7][(er & 0x3F) ^ *subkey];
+
+       temp.longwords[i & 1] ^= out;
+    }
+    
+    /*
+     * Perform the final transformation.
+     */
+    FINAL(outdata->longwords, temp.bytes);
+}
+
+\f
+/*
+ *
+ * Functional Description:
+ *
+ *     Perform a DES encryption of a single 8-byte block producing
+ *     another 8-byte block.
+ *
+ * Inputs:
+ *
+ *     indata  - Pointer to the input data
+ *
+ * Outputs:
+ *
+ *     outdata - Pointer to the output data
+ *
+ * Return Value:
+ *
+ *     None
+ *
+ */
+static DESencrypt_local( indata,outdata,key_schedule )
+DESblock *indata,*outdata;
+KEYschedule *key_schedule ;
+{
+    register int i;
+    register INT32 er,out;
+    register unsigned char *subkey;
+    INT32 index;
+    DESblock temp;
+    
+    /*
+     * Perform the initial transformation.
+     */
+    INITIAL(temp.longwords, indata->bytes);
+    
+    /*
+     * Perform the encryption operation.
+     */
+    for (i = 0; i < 16; i++)
+    {
+       /*
+        * Select the subkey for this round.
+        */
+       subkey = key_schedule->subkey[i];
+
+       /*
+        * Compute the index value to be used for the first 7 subkeys.
+        */
+       index = temp.longwords[1 - (i & 1)];
+       er = (index >> 1) | ((index & 1) ? 0x80000000 : 0);
+       
+       /*
+        * Perform one round of E(input) ^ K through the combined S and
+        * P boxes.
+        */
+       out  = sp[0][((er >> 26) & 0x3F) ^ *subkey++];
+       out |= sp[1][((er >> 22) & 0x3F) ^ *subkey++];
+       out |= sp[2][((er >> 18) & 0x3F) ^ *subkey++];
+       out |= sp[3][((er >> 14) & 0x3F) ^ *subkey++];
+       out |= sp[4][((er >> 10) & 0x3F) ^ *subkey++];
+       out |= sp[5][((er >> 6) & 0x3F) ^ *subkey++];
+       out |= sp[6][((er >> 2) & 0x3F) ^ *subkey++];
+       er = (index << 1) | ((index & 0x80000000) ? 1 : 0);
+       out |= sp[7][(er & 0x3F) ^ *subkey];
+
+       temp.longwords[i & 1] ^= out;
+    }
+    
+    /*
+     * Now swap halves of the working block.
+     */
+    out = temp.longwords[0];
+    temp.longwords[0] = temp.longwords[1];
+    temp.longwords[1] = out;
+
+    /*
+     * Perform the final transformation.
+     */
+    FINAL(outdata->longwords, temp.bytes);
+}
+\f
+/*
+ *
+ * Functional Description:
+ *
+ *     Expand a DES key from an 8-byte array into a key schedule. This
+ *     expansion allows the later encryption routines to operate faster.
+ *
+ * Inputs:
+ *
+ *     inkey   - Pointer to an 8-byte input key
+ *
+ * Outputs:
+ *
+ * Return Value:
+ *
+ *     None
+ *
+ */
+static void DES_load_key_local( key, key_schedule )
+register unsigned char *key;
+KEYschedule *key_schedule ;
+{
+    register int i,j,k;
+    unsigned char k1[56],k2[56];
+
+    /*
+     * Clear out the key schedule, in case it isn't already
+     */
+    memset(key_schedule, 0, sizeof(KEYschedule));
+    
+    /*
+     * Compute the key for the first round as an array of 56 bits (k1).
+     */
+    for (i = 0; i < 56; i++)
+       k1[i] = (key[pc1byte[i]] & pc1bit[i]) ? 1 : 0;
+
+    /*
+     * Build the subkeys by rotating and selecting the bits from each
+     * iteration.
+     */
+    for (i = 0; i < 16; i++)
+    {
+       /*
+        * Rotate the initial key permutation the correct amount for
+        * this subkey, rotating each half independently.
+        */
+       for (j = 0; j < 56; j++)
+           k2[j] = k1[(k = j + totrot[i]) < (j < 28 ? 28 : 56) ? k : k - 28];
+
+       /*
+        * Select the final values for each subkey.
+        */
+       for (j = 0; j < 48; j++)
+           if (k2[pc2[j] - 1] != 0)
+               key_schedule->subkey[i][j/6] |= bytebit[j % 6] >> 2;
+    }
+}
+
+
+\f
+/*
+ *
+ *                     D E S _ C B C _ e n c r y p t
+ *
+ *     Encrypt a buffer using DES in Cipher Block Chaining mode.
+ *
+ * Inputs:
+ *     iv      - Pointer to initialization vector or zero
+ *     inbuf   - Pointer to the input buffer
+ *     isize   - Size of the input buffer
+ *     outbuf  - Pointer to the output buffer (can be same as input)
+ *
+ * Outputs:
+ *     outbuf  - contains encrypted data
+ *
+ * Return Value:
+ *     0       - Buffer is not a multiple of 8 bytes
+ *     1       - Success
+ */
+static int DES_CBC_encrypt_local (iv , inbuf, isize, outbuf,key_schedule)
+unsigned char * iv, * inbuf, * outbuf ;
+int isize;
+KEYschedule *key_schedule ;
+{
+       unsigned long temp1[2] ;
+       unsigned long * inptr = (unsigned long *) inbuf;
+       unsigned long * outptr = (unsigned long *) outbuf;
+    
+       /*
+        * Check that we have a good buffer size.
+        */
+       if ((isize & 0x7) != 0) return (0);
+
+       if (iv!=0) memcpy(temp1,iv,sizeof(temp1)); /* copy over initialization vector */
+       else    memset(temp1,0,sizeof(temp1));
+
+       while (isize > 0) {
+
+               temp1[0] ^= * inptr ++ ; /* XOR previous ciphertext with next data */
+               temp1[1] ^= * inptr ++ ;
+               
+               DESencrypt_local(temp1,temp1,key_schedule); /* encrypt */
+               
+               * outptr ++ = temp1 [0]; /* copy out data */
+               * outptr ++ = temp1 [1];
+
+               isize -= 8;
+       }
+       return(1);
+}
+\f
+/*
+ *
+ *                     D E S _ C B C _ d e c r y p t
+ *
+ *     Decrypt a buffer using DES in Cipher Block Chaining mode.
+ *
+ * Inputs:
+ *     iv      - Pointer to initialization vector or zero
+ *     inbuf   - Pointer to the input buffer
+ *     isize   - Size of the input buffer
+ *     outbuf  - Pointer to the output buffer  (can be same as input)
+ *
+ * Outputs:
+ *     outbuf  - contains encrypted data
+ *
+ * Return Value:
+ *     0       - Buffer is not a multiple of 8 bytes
+ *     1       - Success
+ */
+static int DES_CBC_decrypt_local (iv , inbuf, isize, outbuf,key_schedule)
+char * iv, * inbuf, * outbuf ;
+int isize;
+KEYschedule *key_schedule ;
+{
+       unsigned long temp1[2], temp2[2];
+       unsigned long * inptr = (unsigned long *) inbuf;
+       unsigned long * outptr = (unsigned long *) outbuf;
+    
+       /*
+        * Check that we have a good buffer size.
+        */
+       if ((isize & 0x7) != 0) return (0);
+
+       if (iv!=0) memcpy(temp1,iv,sizeof(temp1)); /* copy over initialization vector */
+       else    memset(temp1,0,sizeof(temp1));
+
+       while (isize > 0) {
+               DESdecrypt_local(inptr,temp2,key_schedule); /* decrypt to temporary */
+
+               temp2[0] ^= temp1 [0]; /* XOR previous ciphertext with data */
+               temp2[1] ^= temp1 [1];
+               
+               temp1[0] = * inptr ++ ; /* copy in ciphertext for next block XOR */
+               temp1[1] = * inptr ++ ;
+
+               * outptr ++ = temp2 [0]; /* copy out data */
+               * outptr ++ = temp2 [1];
+
+               isize -= 8;
+       }
+       return(1);
+}
+
+#endif
diff --git a/util/gdss/lib/crypto/algorithm/Imakefile b/util/gdss/lib/crypto/algorithm/Imakefile
new file mode 100644 (file)
index 0000000..1604cb8
--- /dev/null
@@ -0,0 +1,22 @@
+/* $Header$ */
+
+OBJS =         random.o \
+       random_BigNum.o \
+       bigrsacode.o \
+       bigkeygen.o \
+       bigsignverify.o
+
+DEFINES = -I. -I../../../include -I../bignum/h
+
+
+depend:: tables.h
+
+all:: tables.h $(OBJS)
+
+genutil(gentables,gentables.o,,)
+
+endian.h tables.h: gentables
+       ./gentables
+
+clean::
+       $(RM) tables.h endian.h
diff --git a/util/gdss/lib/crypto/algorithm/RSAcrypto.h b/util/gdss/lib/crypto/algorithm/RSAcrypto.h
new file mode 100644 (file)
index 0000000..cfc0366
--- /dev/null
@@ -0,0 +1,294 @@
+/* RSAcrypto.h */
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/* This code was derived in large part from Mark Shand's PRL Montgomery code. */
+
+/* In-line code for basic RSA routines */
+
+static void rsaencrypt_1();
+static void rsadecrypt_1();
+static void BnnModularProduct_1();
+static void BnnDyRaise_1 ();
+static unsigned BnnDyCanon_1 ();
+/*
+ *********************************************************************
+ *********************************************************************
+ **                                                                 **
+ **                       W A R N I N G                             **
+ **                                                                 **
+ **  This software is subject to export restrictions under the      **
+ **  U.S. Department of State's International Traffic in Arms       **
+ **  Regulations (ITAR).  This software must not be transmitted     **
+ **  IN SOURCE FORM outside the United States or to a foreign       **
+ **  national in the United States without a valid U.S. State       **
+ **  Department export license.                                     **
+ **                                                                 **
+ *********************************************************************
+ *********************************************************************
+*/
+
+#ifndef SPHINX_RSACRYPTO
+#define SPHINX_RSACRYPTO
+
+#ifndef SPHINX_ITAR
+#define SPHINX_ITAR
+static char copyright[] = "\n Copyright, 1989, 1990, Digital Equipment Corporation ";
+static char warning[]= "\n  This software is subject to export restrictions under \
+\n  the U.S. Department of State's International Traffic in Arms \
+\n  Regulations (ITAR).  This software must not be transmitted \
+\n  in source form outside the United States or to a foreign \
+\n  national in the United States without a valid U.S. State \
+\n  Department export license. ";
+#endif
+
+#define assert(x) ((x)?0:dumpcore("x",__FILE__,__LINE__))
+#define TopBitInWord ((BigNumDigit)(1<<(BN_DIGIT_SIZE-1)))
+
+static BigNumDigit one[2*2*DigitLim] = { 1 };
+
+static int dumpcore(s,f,n)
+char *s,*f;
+int n;
+{
+    fflush(stdout);
+    fclose(stdout);
+    fprintf(stderr, "\nassertion failed file %s line %d: %s\n",  f, n, s);
+    fclose(stderr);
+    abort();
+} 
+
+static void rsaencrypt_1(inblk,outblk,keys)
+BigNum  inblk, outblk;
+RSAKeyStorage * keys;
+{
+    static BigNumDigit x[1] ;
+    char *charp;
+    register int shift = 0;
+    BigNum n = keys->n, e = keys->e;
+    int nl = keys->nl, el = keys->el;
+    int nTop = BnnNumDigits(n,nl) ;
+    int BLOCKLEN = nTop*BN_DIGIT_SIZE -        BnnNumLeadingZeroBitsInDigit(n[nTop-1]) - 1;
+    int BLOCKBYTES = BLOCKLEN/8;
+    int BLOCKWDS = BLOCKLEN/BN_DIGIT_SIZE + 1;
+    BnnInit();
+    x[0] = 0;
+    charp = (char *) x;
+    *charp = 1;
+    if (x[0] != (BigNumDigit) 1 && BLOCKBYTES % sizeof(BigNumDigit) != 0) 
+    {
+        /* This machine is big-endian */
+        shift = ((sizeof(BigNumDigit) * BLOCKWDS) - BLOCKBYTES) * 8;
+    }
+    *charp = 0;
+    
+    inblk[nl-1] >>= shift;
+    BnnDyRaise_1 (outblk, inblk, e, el, n, keys->beta2n, keys->nINV, nl);
+    BnnClose();
+}
+
+static void rsadecrypt_1(inblk, outblk,keys)
+BigNum inblk, outblk;
+RSAKeyStorage * keys ;
+{
+    static BigNumDigit x[3*DigitLim], xp[2*DigitLim], xq[2*DigitLim] ;
+    char *charp;
+    register int shift = 0;
+    BigNum n = keys->n, p = keys->p, q = keys->q , 
+          pINV = keys->pINV, qINV = keys->qINV;
+    int nl = keys->nl, pl = keys->pl, ql = keys->ql ;
+    int nTop = BnnNumDigits(n,nl) ;
+    int BLOCKLEN = nTop*BN_DIGIT_SIZE -        BnnNumLeadingZeroBitsInDigit(n[nTop-1]) - 1;
+    int BLOCKBYTES = BLOCKLEN/8;
+    int BLOCKWDS = BLOCKLEN/BN_DIGIT_SIZE + 1;
+
+    BnnInit();
+    x[nl]=0;
+    charp = (char *) (x+nl);
+    *charp = 1;
+    if (x[nl] != (BigNumDigit) 1)
+    {
+        /* This machine is big-endian */
+        shift = ((sizeof(BigNumDigit) * BLOCKWDS) - BLOCKBYTES) * 8;
+    }
+    {
+       /* xp <- inblk/B^PL [p] */
+       BnnSetToZero(xp, 2*pl);
+       BnnAssign(xp+pl, inblk+pl, nl-pl);
+       BnnModularProduct_1 (xp, pl+pl, inblk, pl, one, pl, p, pl, pINV);
+       /* xq <- inblk/B^QL [q] */
+       BnnSetToZero(xq, 2*ql);
+       BnnAssign(xq+ql, inblk+ql, nl-ql);
+       BnnModularProduct_1 (xq, ql+ql, inblk, ql, one, ql, q, ql, qINV);
+        /* pass beta3[pq] coeff. to compensate for prediv by B^[PQ]L */
+        BnnDyRaise_1 (xp, xp+pl, keys->dp, keys->dpl, p, keys->beta3p, pINV, pl);
+        BnnDyRaise_1 (xq, xq+ql, keys->dq, keys->dql, q, keys->beta3q, qINV, ql);
+       BnnSetToZero(xp+pl, nl-pl);
+       BnnSetToZero(xq+ql, nl-ql);
+       BnnSubtract(xp,pl,xq,ql,1);
+       while((BnnGetDigit(xp+(pl-1))&TopBitInWord)!=0) BnnAdd(xp,pl,p,pl,0);
+       BnnSetToZero(x,3*pl);
+       BnnModularProduct_1 (x+pl,pl+pl,xp,pl,keys->cr,pl,p,pl,pINV);
+       BnnModularProduct_1 (x,pl+pl,keys->beta2p,pl,x+pl+pl,pl,p,pl,pINV);
+       BnnDyCanon_1 (x+pl, p, pl);
+       BnnMultiply(xq, nl, x+pl, pl, q , ql);
+       xq[2*pl-1] <<= shift;
+    }
+    BnnClose();
+    BnnAssign(outblk, xq, nl);
+}
+
+
+static void BnnModularProduct_1 (p,pl,a,al,b,bl,m,ml,mu)
+BigNum p,b,a,m,mu;
+unsigned pl,al,bl,ml;
+{
+    /* p is length pl */
+    /* a has length al, b has length bl, m has length ml, mu has length >= 2 */
+    /* mu is -m[0..1..] mod BN_DIGIT_SIZE*2 */
+    /* after computation
+        p[0..bl-1] = 0
+        (p[bl..pl-1] * beta^bl) mod m = p+(a*b) mod m
+    */
+    BigNumDigit qt[2*DigitLim];
+    assert(pl <= 2*DigitLim);
+    
+    BnnMultiply(p, pl, a, al, b, bl);
+    BnnSetToZero(qt, pl);
+    BnnMultiply(qt, pl, p, pl-ml, mu, ml);
+    BnnMultiply(p, pl, m, ml, qt, pl-ml);
+}
+
+static unsigned BnnDyCanon_1 (x, m, ml)
+BigNum x, m;
+unsigned ml;
+{
+    int redcount = 0;
+    while (BnnCompare(x, ml, m, ml) > 0)
+    {
+        BnnSubtract(x, ml, m, ml, 1);
+        redcount++;
+    }
+    return redcount;
+}
+
+#define MAX_LN2PWR 4
+#define MAXPWR (1<<MAX_LN2PWR)
+
+static void BnnDyRaise_1 (x, a, e, el, m, beta2ml, mu, ml)
+BigNum x, a, e, m, beta2ml;
+BigNum mu;
+unsigned ml, el;
+{
+    static BigNumDigit sBUF[DigitLim];
+    static BigNumDigit tBUF[DigitLim*10];
+    register BigNum s = sBUF, t = tBUF;
+    static BigNum aCache[MAXPWR];
+    BigNumDigit ed;
+    BigNumDigit mask;
+    int eindex, eoffset, nibble, i;
+    static BigNumDigit aCacheBUF[MAXPWR*2*DigitLim];
+    int pwr,ln2pwr;
+
+    /* Exponentiate: x = a^e mod m */
+    if (BnnNumDigits(e, el) > 1)
+       ln2pwr = MAX_LN2PWR;
+    else
+       ln2pwr = 1;
+    pwr = (1<<ln2pwr);
+    /* We work high to low in the exponent and make a special case 
+        of the topmost bit in e */ 
+    /* check that m is within range */
+    assert((m[ml-1] & (3<<(BN_DIGIT_SIZE-2))) == 0);
+
+    /* prime the aCache */
+    t = aCacheBUF+2*DigitLim-ml;
+    aCache[1] = s = aCacheBUF+2*DigitLim;
+    BnnSetToZero(t, 2*ml);
+    BnnModularProduct_1 (t, ml+ml, a, ml, beta2ml, ml, m, ml, mu);
+    for (i = 2; i < pwr; i++)
+    {
+        t += 2*DigitLim;
+        BnnSetToZero(t, 2*ml);
+        BnnModularProduct_1 (t, ml+ml, s, ml, aCache[1], ml, m, ml, mu);
+        aCache[i] = (s += 2*DigitLim);
+    }
+
+    eindex = BnnNumDigits(e, el)-1;
+    ed = e[eindex];
+    eoffset = ((BN_DIGIT_SIZE-BnnNumLeadingZeroBitsInDigit(ed)-1) & ~(ln2pwr-1));
+    mask = (pwr-1) << eoffset;
+    nibble = (ed&mask)>>eoffset;
+    mask >>= ln2pwr;
+    eoffset -= ln2pwr;
+    s = aCache[nibble];
+
+    while (eindex >= 0)
+    {
+        ed = e[eindex--];
+        while (mask)
+        {
+            /* Square ln2pwr times */
+            t = tBUF;
+            BnnSetToZero(t, 2*(ln2pwr+1)*ml);
+            for (i = 0; i < ln2pwr; i++)
+            {
+                BnnModularProduct_1 (t, ml+ml, s, ml, s, ml, m, ml, mu);
+                s = t+ml; t += 2*ml;
+            }
+            nibble = (ed&mask)>>eoffset;
+            if (nibble)
+            {
+                /* Multiply */
+                BnnModularProduct_1 (t, ml+ml, s, ml, aCache[nibble], ml, m, ml, mu);
+                BnnAssign(sBUF, t+ml, ml);
+            }
+            else
+                BnnAssign(sBUF, s, ml);
+            mask >>= ln2pwr;
+            eoffset -= ln2pwr;
+            s = sBUF;
+        }
+        eoffset = BN_DIGIT_SIZE-ln2pwr;
+        mask = (pwr-1) << eoffset;
+    }
+    /* restore representation */
+    
+    t = tBUF;
+    BnnSetToZero(t, 2*ml);
+    BnnModularProduct_1 (t, ml+ml, s, ml, one, ml, m, ml, mu);
+    BnnAssign(x, t+ml, ml);
+}
+
+#endif
diff --git a/util/gdss/lib/crypto/algorithm/bigkeygen.c b/util/gdss/lib/crypto/algorithm/bigkeygen.c
new file mode 100644 (file)
index 0000000..eba3789
--- /dev/null
@@ -0,0 +1,892 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/* This code was derived from Mark Shand's PRL Montgomery code. */
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#ifndef SYSV
+#include <sys/timeb.h>
+#endif
+
+#include "BigZ.h"
+#include "BigRSA.h"
+#include "bigrsacode.h"
+#include "bigkeygen.h"
+
+#ifdef mips
+#undef BnnSetToZero
+#endif
+
+#define KEY_LINE 64
+#define KEY_RADIX 16
+
+/* 
+#define DEBUG_1
+*/
+
+/* Global storage indicating whether to print prime progress reports */
+
+int bigkeygenPrintStatistics = 0;
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+/*
+ * One-half the difference between the lengths of p and q, in bits
+ */
+#define PRIME_BIT_DIFF 3
+
+/*
+ * Local modular product routines
+ */
+
+/* put in-line RSA routines here */
+
+#include "RSAcrypto.h"
+
+static void BnnGCD_1();
+static void modpwr2_1();
+static BigNum muB_1();
+static int bigprime();
+
+/*
+ * newRSAKey generates a new RSA key instance.
+ *
+ *      bitlen  length of primes, in bits.  Modulus will be
+ *              approximately 2*bitlen
+ *      keys    RSAKeyStorage structure for new key
+ */
+int newRSAKey ( bitlen , keys )
+int bitlen ;
+RSAKeyStorage *keys ;
+{
+    BigNum  p = keys->p, q = keys->q ;
+    unsigned lowbits = 1, confidence = 20, pl, ql;
+#ifdef DEBUG
+    clock_t mark, tenths;
+    struct timeb start_time , end_time ; 
+#endif
+
+    if ((bitlen<128)||(bitlen>MaxPrimeBits)) return (0);
+
+    memset(keys,0,sizeof(RSAKeyStorage));
+    BnnInit();
+
+#ifdef DEBUG
+    mark = clock();
+    ftime (&start_time);
+#endif
+
+    bigprime(p, &pl, bitlen+PRIME_BIT_DIFF, lowbits, confidence, 0);
+    do {
+       bigprime(q, &ql, bitlen-PRIME_BIT_DIFF, lowbits, confidence, 0);
+    } while (BnnCompare(p, pl, q, ql) == 0);
+
+#ifdef DEBUG
+    mark = clock() - mark ;
+    ftime (&end_time);
+
+#ifdef ultrix
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC  1000000
+#endif
+    tenths = (100*(mark%CLOCKS_PER_SEC))/CLOCKS_PER_SEC ;
+    mark /= CLOCKS_PER_SEC ;
+#else
+    tenths = (100*(mark%CLK_TCK))/CLK_TCK ;
+    mark /= CLK_TCK ;
+#endif
+
+    printf ("\n/* Primes found in %d.%02d seconds of process time*/\n", mark, tenths );
+    mark = end_time.time - start_time.time ;
+    { long xt = (unsigned long) end_time.millitm - (unsigned long) start_time.millitm ;
+      if (xt<0) { mark--; xt = 1000 - xt;}
+      printf ("\n/* Primes found in %d.%03d elapsed seconds */\n",
+                end_time.time-start_time.time, xt );
+    }
+#endif
+    if (BnnCompare(p, pl, q, ql) == -1) {
+        unsigned tpl = pl;
+        BigNumDigit tp[DigitLim];
+        BnnSetToZero(tp,DigitLim);
+        BnnAssign(tp,p,pl);
+        BnnSetToZero(p,pl);
+        BnnAssign(p,q,ql);
+        BnnAssign(q,tp,pl);
+        pl = ql;
+        ql = tpl;
+    }
+
+    keys->pl = pl;
+    keys->ql = ql;
+
+    /*
+     * Set exponent to F16 and compute modulus.
+     */
+    BnnSetDigit(keys->e, (BigNumDigit) ((1<<16)+1));
+    keys->el = 1;
+
+    BnnMultiply(keys->n, pl+ql, p, pl, q, ql),
+    keys->nl = pl+ql;
+
+    if (FinishKey(keys)==0) return (0);
+
+    if (TestRSAKeys(keys)!=1) {
+#ifdef DEBUG
+printf("\nFailed.\n");
+#endif
+        return(0);
+    }  
+
+    BnnClose();
+    return(1);
+}
+
+
+/* 
+ * Prime-finding routines 
+ */
+
+
+static BigNumDigit smallprime[]=
+{3,5,7,11,13,17,19,23,29,31,37,41,43,53,59,
+61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,
+163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,
+257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,
+359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,
+461,463,467,479,487,491,499 };
+
+
+/*
+ * Test for primality.
+ */
+
+static int IsPrime(n,nl,confidence)
+BigNum n;
+int nl;
+{
+        int i;
+        static BigNumDigit x[DigitLim], 
+                           y[2*DigitLim], 
+                           beta2n[2*DigitLim+1],
+                           nINV [2*DigitLim] ;
+
+        for(i=0;i<=(sizeof(smallprime)/sizeof(BigNumDigit));i++) 
+          if(BnnDivideDigit(y,n,nl+1,smallprime[i])==0) goto exit ;
+
+        muB_1(nINV, n, nl*BN_DIGIT_SIZE);
+        modpwr2_1(beta2n, 2, n, nl);
+        BnnSetToZero (x, nl);
+
+        for(i=0;i<=confidence;i++) {
+                x[0]+= smallprime[i] ;
+                BnnDyRaise_1(y, x, n, nl, n, beta2n, nINV, nl);
+                BnnDyCanon_1(y, n, nl);
+                if (BnnCompare(y, nl, x, nl)) goto exit;
+                }
+        return(1);
+
+exit:
+        return(0);
+}
+
+/*
+ * Generate a big prime.
+ */
+static bigprime (n,nlen,bitlen,lowbits,confidence,stats)
+BigNum n;        
+unsigned *nlen;
+int bitlen;
+BigNumDigit lowbits;
+int confidence;
+unsigned *stats;
+{ 
+  char * z ;
+  static char sieve [1000];
+  int i,j;
+  BigNumDigit r, s, q[DigitLim] ;
+  unsigned nl =(bitlen+(BN_DIGIT_SIZE-1))/BN_DIGIT_SIZE ;
+  unsigned ntop = nl;
+
+  if((((bitlen-1)%BN_DIGIT_SIZE)+1)>=(BN_DIGIT_SIZE-1)) nl++;
+  *nlen = nl;
+  BnnSetToZero(n,nl+1);
+  while(1) {
+    random_BigNum(n,ntop);
+    n[nl-1]&=(1<<((BN_DIGIT_SIZE)-(nl*(BN_DIGIT_SIZE)-bitlen))) -1 ;
+    n[(bitlen-1)/BN_DIGIT_SIZE] |= 1<<((bitlen-1)%BN_DIGIT_SIZE);
+    n[(bitlen-2)/BN_DIGIT_SIZE] |= 1<<((bitlen-2)%BN_DIGIT_SIZE);
+    n[0]&=~1;
+
+    if(bigkeygenPrintStatistics) 
+        printf("\nCandidate Random Number: %s\n",BzToString(BzFromBigNum(n,nl),16));
+
+    z = &sieve[0] ;
+    for (i=0;i<1000;i=i+2){*z++=1;*z++=0;};
+    r = BnnDivideDigit(q,n,nl+1,(BigNumDigit)3);
+    if (r==0) r = (BigNumDigit) 3;
+    r--;
+    z = &sieve[3-r] ;
+    for (j=3-r;j<1000;j+=3) {*z=1;z+=3;}
+
+    for (s=3;s<10000;s+=2) {
+      for (j=0; j<5; j++)if ((s>smallprime[j])&&(0==(s%smallprime[j]))) goto nexts;
+      r = BnnDivideDigit(q,n,nl+1,s);
+      if (r==0) r = s;
+      z = &sieve[s-r] ;
+      for (j=s-r;j<1000;j+=s) {*z=1;z+=s;}
+    nexts: ;
+    }
+    for(i=0;i<1000;i++) {
+      if (!sieve[i]) {
+
+    if(bigkeygenPrintStatistics) printf("|"),fflush(stdout);
+
+         if (IsPrime(n,nl,5)) goto exit;
+      }
+      BnnAddCarry(n,nl,1);  /* try next one */
+    } 
+  }
+exit:
+
+if(bigkeygenPrintStatistics) printf(""), fflush(stdout);
+
+}
+
+
+/*
+ * This routine expects modulus n and exponent e to be initialized
+ * in the RSAKeyStorage structure supplied.  It computes the rest of
+ * the key components based on what is provided.  If p and q are there
+ * it also makes sure a complete private key is initialized.
+ */
+int FinishKey (keys)
+RSAKeyStorage *keys;
+{
+    static BigNumDigit g[4*DigitLim], wgcd[12*DigitLim], 
+       r[4*DigitLim], pq[4*DigitLim], d[4*DigitLim], z[4*DigitLim];
+
+    BigNum n = keys->n, dp = keys->dp, dq = keys->dq, cr = keys->cr,
+          e = keys->e, p = keys->p, q = keys->q ;
+
+    unsigned nl=keys->nl, pl=keys->pl, ql=keys->ql, tmp,
+             dpl = keys->dpl, dql = keys->dql ;
+
+    /*
+     * If primes are supplied, generate dp, dq, and cr if needed.
+     * Assume cr there if dp and dq are.
+     */
+
+    if (pl && ql && ((dpl == 0)||(dql ==0)) ) {
+        BnnAssign(pq, n, nl);
+        BnnSubtract(pq, nl, p, pl, 1);
+        BnnSubtract(pq, nl, q, ql, 1);
+        BnnAddCarry(pq, nl, 1);
+        BnnGCD_1(g, d, r, e, pq, wgcd, nl);
+        if (BnnCompare(g,nl,one,nl)!=0) {
+#ifdef DEBUG
+printf("GCD failed to generate private key exponent.\n");
+#endif
+               return(0);
+        }
+        BnnAssign(z, d, nl);
+        z[nl] = 0;
+        BnnAssign(pq, p, pl);
+        BnnSubtractBorrow(pq, pl, 0);
+        BnnDivide(z, nl+1, pq, tmp=BnnNumDigits(pq, pl));
+        BnnSetToZero(z+tmp, nl+1-tmp);
+        BnnAssign(dp, z, (keys->dpl)=BnnNumDigits(z,nl));
+
+        BnnAssign(z, d, nl);
+        z[nl] = 0;
+        BnnAssign(pq, q, ql);
+        BnnSubtractBorrow(pq, ql, 0);
+        BnnDivide(z, nl+1, pq, tmp=BnnNumDigits(pq, ql));
+        BnnSetToZero(z+tmp, nl+1-tmp);
+        BnnAssign(dq, z, (keys->dql)=BnnNumDigits(z,nl));
+    
+        BnnGCD_1(g,r,cr,p,q,wgcd,pl);
+        if ((BnnGetDigit(cr+(pl-1))&TopBitInWord)!=0) BnnAdd(cr,pl,p,pl,0);
+    }
+
+    modpwr2_1(z, 2, n, nl);
+    BnnAssign(keys->beta2n, z, nl);
+    muB_1(keys->nINV, n, nl*BN_DIGIT_SIZE);
+
+    if (pl&&ql)  {
+        modpwr2_1(z, 3, p, pl);
+        BnnAssign(keys->beta3p, z, pl);
+        modpwr2_1(z, 2, p, pl);
+        BnnAssign(keys->beta2p, z, pl);
+        modpwr2_1(z, 3, q, ql);
+        BnnAssign(keys->beta3q, z, ql);
+        muB_1(keys->pINV, p, pl*BN_DIGIT_SIZE);
+        muB_1(keys->qINV, q, ql*BN_DIGIT_SIZE);
+    }
+
+#ifdef DEBUG_1
+    printf("\n");
+    printf("p = %s\n", BzToString(BzFromBigNum(p, pl), 16));
+    printf("q = %s\n", BzToString(BzFromBigNum(q, ql), 16));
+    printf("n = %s\n", BzToString(BzFromBigNum(n, nl), 16));
+    printf("e = %s\n", BzToString(BzFromBigNum(e, nl), 16));
+    printf("d = %s\n", BzToString(BzFromBigNum(d, nl), 16));
+    printf("dp = %s\n", BzToString(BzFromBigNum(dp, dpl), 16));
+    printf("dq = %s\n", BzToString(BzFromBigNum(dq, dql), 16));
+    printf("cr = %s\n", BzToString(BzFromBigNum(cr, pl), 16));
+    fflush(stdout);
+#endif
+
+
+    return(1);
+}
+
+
+static BigNum muB_1(res, zz, bits)
+BigNum res, zz;
+int bits;
+{
+    /* Compute -z^-1 mod 2^bits */
+#define muBLIM 40
+    BigNumDigit n[muBLIM];
+    BigNumDigit msk[muBLIM], z[muBLIM];
+    unsigned nl = (bits+BN_DIGIT_SIZE-1)/BN_DIGIT_SIZE;
+    int i;
+    
+    if (nl > muBLIM)
+    {
+        fprintf(stderr, "Limit check in %s:muB_1 line %d\n", __FILE__, __LINE__);
+        abort();
+    }
+    
+    BnnSetToZero(n, nl);
+    BnnComplement(n,nl);
+    BnnSetToZero(res, nl);
+    BnnSetToZero(msk, nl);
+    BnnSetDigit(msk, 1);
+    BnnAssign(z, zz, nl);
+    BnnShiftRight(z,nl,1);
+    while (bits--)
+    {
+        if (BnnIsDigitOdd(*n))
+        {
+            for (i = 0; i < nl; i++)
+                BnnOrDigits(res+i, msk[i]);
+            BnnShiftRight(n,nl,1);
+            BnnSubtract(n, nl, z, nl, 1);
+        }
+        else
+           BnnShiftRight(n,nl,1);
+        BnnShiftLeft(msk,nl,1);
+    }
+    return res;
+}
+
+static void modpwr2_1(result, pwr, m, ml)
+BigNum result, m;
+unsigned pwr, ml;
+{      unsigned tmp;
+       BnnSetToZero(result, pwr*ml);
+       BnnSetDigit(result+pwr*ml, (BigNumDigit) 1);
+       BnnDivide(result, pwr*ml+1, m, tmp=BnnNumDigits(m, ml));
+       BnnSetToZero(result+tmp, pwr*ml+1-tmp);
+}
+
+
+static void BnnGCD_1(gcd, A, B, U, V, work, len)
+BigNum gcd, A, B, U, V, work;
+int len;
+{
+    /* Extended binary GCD
+       code based on Knuth Vol.2 Second Edition
+       section 4.5.2 Answers to Exercises page 599
+    */
+    /* Note: len must be large enough to hold 2*U or 2*V */
+    /* "work" is a BigNum of length 3*len */
+    BigNumDigit k;
+    BigNum u1,u2,u3, v1,v2,v3;
+    BigNum t1,t2,t3;
+    u1 = A; u2 = B; u3 = gcd;
+    v1 = work; v2 = work + len; v3 = work + 2*len;
+
+    k = 0;
+    while (!BnnIsDigitOdd(*U) && !BnnIsDigitOdd(*V))
+    {
+        BnnShiftRight(U, len, 1);
+        BnnShiftRight(V, len, 1);
+        k++;
+    }
+    BnnSetToZero(u1, len); BnnSetDigit(u1, (BigNumDigit) 1);
+    BnnSetToZero(u2, len);
+    BnnAssign(u3, U, len);
+    if (BnnIsDigitOdd(*U))
+    {
+        t1 = v1; t2 = v2; t3 = v3;
+        BnnSetToZero(v1, len);
+        BnnSetToZero(v2, len); BnnComplement(v2, len);
+        BnnSetToZero(v3, len); BnnSubtract(v3, len, V, len, 1);
+    }
+    else
+    {
+        t1 = u1; t2 = u2; t3 = u3;
+        BnnAssign(v1, V, len);
+        BnnSetToZero(v2, len); BnnSetDigit(v2, (BigNumDigit) 1);
+            BnnSubtract(v2, len, U, len, 1);
+        BnnAssign(v3, V, len);
+    }
+#ifdef PRINT_LEVEL2
+    printf("#[%d %d %d ] [ %d %d %d ]\n", *u1,*u2,*u3, *v1,*v2,*v3);
+#endif
+    while (!BnnIsZero(t3, len))
+    {
+        while (!BnnIsDigitOdd(*t3))
+        {
+            BigNumDigit sign;
+            if (!BnnIsDigitOdd(*t1) && !BnnIsDigitOdd(*t2))
+            {
+                sign = BnnGetDigit(t1+(len-1)) & TopBitInWord;
+                BnnShiftRight(t1, len, 1);
+                BnnOrDigits(t1+(len-1), sign);
+                sign = BnnGetDigit(t2+(len-1)) & TopBitInWord;
+                BnnShiftRight(t2, len, 1);
+                BnnOrDigits(t2+(len-1), sign);
+            }
+            else
+            {
+                BnnAdd(t1, len, V, len, 0);
+                sign = BnnGetDigit(t1+(len-1)) & TopBitInWord;
+                BnnShiftRight(t1, len, 1);
+                BnnOrDigits(t1+(len-1), sign);
+                BnnSubtract(t2, len, U, len, 1);
+                sign = BnnGetDigit(t2+(len-1)) & TopBitInWord;
+                BnnShiftRight(t2, len, 1);
+                BnnOrDigits(t2+(len-1), sign);
+            }
+            sign = BnnGetDigit(t3+(len-1)) & TopBitInWord;
+            BnnShiftRight(t3, len, 1);
+            BnnOrDigits(t3+(len-1), sign);
+        }
+        if (t1 == v1) /* a cheap way to recall what state we are in */ 
+        {
+            BnnComplement(v1, len);
+            BnnAdd(v1, len, V, len, 1);
+            BnnComplement(v2, len);
+            BnnAddCarry(v2, len, 1);
+            BnnSubtract(v2, len, U, len, 1);
+            BnnComplement(v3, len);
+            BnnAddCarry(v3, len, 1);
+        }
+        if (BnnCompare(u3, len, v3, len) > 0)
+        {
+            BnnSubtract(u1, len, v1, len, 1);
+            BnnSubtract(u2, len, v2, len, 1);
+            BnnSubtract(u3, len, v3, len, 1);
+            t1 = u1; t2 = u2; t3 = u3;
+        }
+        else
+        {
+            BnnComplement(v1, len);
+            BnnAdd(v1, len, u1, len, 1);
+            BnnComplement(v2, len);
+            BnnAdd(v2, len, u2, len, 1);
+            BnnComplement(v3, len);
+            BnnAdd(v3, len, u3, len, 1);
+            t1 = v1; t2 = v2; t3 = v3;
+        }
+
+        if (BnnGetDigit(t1+(len-1)) & TopBitInWord)
+        {
+            BnnAdd(t1, len, V, len, 0);
+            BnnSubtract(t2, len, U, len, 1);
+        }
+#ifdef PRINT_LEVEL2
+    printf(">[%d %d %d ] [ %d %d %d ]\n", *u1,*u2,*u3, *v1,*v2,*v3);
+#endif
+    }
+    while (k-- > 0)
+        BnnShiftLeft(u3, len, 1);
+}
+
+
+/**********************************************************************/
+
+static char *TestData = "Now is the time for all good men to come to the aid of their" ;
+static BigNumDigit test_in [2*DigitLim], test1 [2*DigitLim], test2 [2*DigitLim] ;
+
+int TestRSAKeys(key)
+RSAKeyStorage *key ; 
+{
+        int nl=key->nl;
+        int ll = BnnNumDigits(key->n,nl);
+
+        memset(test_in,0,sizeof(test_in));
+        memset(test1,0,sizeof(test1));
+        memset(test2,0,sizeof(test2));
+        strcpy((char *)test_in,TestData);
+        BnnSetToZero(test_in+ll-2,(nl-ll)+3);
+#ifdef DEBUG
+printf("\nPrivate Key Encrypt/Decrypt Test.");
+printf("\nInput(hex): %s", BzToString(BzFromBigNum(test_in, nl), 16));
+printf("\nInput(string): %s", test_in);
+#endif
+        rsaencrypt_1(test_in,test1,key);
+#ifdef DEBUG
+printf("\nEncrypted: %s", BzToString(BzFromBigNum(test1, nl), 16));
+#endif
+        rsadecrypt_1(test1,test2,key);
+#ifdef DEBUG
+printf("\nDecrypted: %s", BzToString(BzFromBigNum(test2, nl), 16));
+printf("\n");
+#endif
+        if (BnnCompare(test_in,nl,test2,nl) != 0) { 
+#ifdef DEBUG
+printf("\nKey Test Failed.\n");
+#endif
+                return(0);
+        }
+#ifdef DEBUG
+printf("\nKey Test Passed.\n");
+#endif
+        return(1);
+}  
+
+static int Test2RSAPrivate_1(key)
+RSAKeyStorage *key ; 
+{
+        int nl=key->nl;
+        int ll = BnnNumDigits(key->n,nl);
+
+        memset(test_in,0,sizeof(test_in));
+        memset(test1,0,sizeof(test1));
+        memset(test2,0,sizeof(test2));
+        strcpy((char *)test_in,TestData);
+        BnnSetToZero(test_in+ll-2,(nl-ll)+3);
+#ifdef DEBUG
+        printf("\nPrivate Key Decrypt/Encrypt Test.");
+        printf("\nInput(hex): %s", BzToString(BzFromBigNum(test_in, nl), 16));
+        printf("\nInput(string): %s", test_in);
+#endif
+        rsadecrypt_1(test_in,test1,key);
+#ifdef DEBUG
+printf("\nSigned: %s", BzToString(BzFromBigNum(test1, nl), 16));
+#endif
+        rsaencrypt_1(test1,test2,key);
+#ifdef DEBUG
+printf("\nVerified: %s", BzToString(BzFromBigNum(test2, nl), 16));
+printf("\n");
+#endif
+        if (BnnCompare(test_in,nl,test2,nl) != 0) { 
+#ifdef DEBUG
+printf("\nKey Test Failed.\n");
+#endif
+                return(0);
+        }
+        return(1);
+}  
+
+
+PrintBigNum(n,nl,radix)
+BigNum n;
+int radix, nl;
+{  
+     static char oneline [KEY_LINE+1];
+     char *p = BzToString(BzFromBigNum(n,nl), radix);
+
+     oneline[KEY_LINE]='\0';
+     while(*p != '\0'){
+        strncpy(oneline,p,KEY_LINE); 
+        printf("\n     %s",oneline);
+        p+=((strlen(p)>KEY_LINE)?KEY_LINE:strlen(p));
+     }
+}
+
+int PrintTestKey (Keys)
+RSAKeyStorage *Keys;
+{
+    int i;
+  
+    printf("\ne: (%d BigNumDigit", Keys->el);
+    if(Keys->el > 1) printf("s) "); else printf(")");
+    PrintBigNum(Keys->e,Keys->el,KEY_RADIX);
+    printf("\nn: (%d BigNumDigits) ", Keys->nl);
+    PrintBigNum(Keys->n,Keys->nl,KEY_RADIX);
+
+    if (Keys->pl) { printf("\np: (%d BigNumDigits) ", Keys->pl);
+              PrintBigNum(Keys->p,Keys->pl,KEY_RADIX);
+              printf("\nq: (%d BigNumDigits) ", Keys->ql);
+              PrintBigNum(Keys->q,Keys->ql,KEY_RADIX);
+              printf("\ndp: (%d BigNumDigits) ", Keys->dpl);
+              PrintBigNum(Keys->dp, Keys->dpl,KEY_RADIX);
+              printf("\ndq: (%d BigNumDigits) ", Keys->dql);
+              PrintBigNum(Keys->dq, Keys->dql,KEY_RADIX);
+              printf("\ncr: ");
+              PrintBigNum(Keys->cr, Keys->pl,KEY_RADIX);
+    }
+    
+    i=BnnNumDigits(Keys->nINV,sizeof(*Keys->nINV)*sizeof(int));
+    printf("\nnINV: (%d BigNumDigits) ", i);
+    PrintBigNum(Keys->nINV, i, KEY_RADIX);
+
+    i=BnnNumDigits(Keys->beta2n,sizeof(*Keys->beta2n)*sizeof(int));
+    printf("\nbeta2n: (%d BigNumDigits) ", i);
+    PrintBigNum(Keys->beta2n, i,KEY_RADIX);
+
+    if(Keys->pl) {
+        i=BnnNumDigits(Keys->pINV,sizeof(*Keys->pINV)*sizeof(int));
+        printf("\npINV: (%d BigNumDigits) ", i);
+        PrintBigNum(Keys->pINV, i,KEY_RADIX);
+
+        i=BnnNumDigits(Keys->qINV,sizeof(*Keys->qINV)*sizeof(int));
+        printf("\nqINV: (%d BigNumDigits) ", i);
+        PrintBigNum(Keys->qINV, i,KEY_RADIX);
+
+
+        i=BnnNumDigits(Keys->beta2p,sizeof(*Keys->beta2p)*sizeof(int));
+        printf("\nbeta2p: (%d BigNumDigits) ", i);
+        PrintBigNum(Keys->beta2p, i,KEY_RADIX);
+
+        i=BnnNumDigits(Keys->beta3p,sizeof(*Keys->beta3p)*sizeof(int));
+        printf("\nbeta3p: (%d BigNumDigits) ", i);
+        PrintBigNum(Keys->beta3p, i,KEY_RADIX);
+
+        i=BnnNumDigits(Keys->beta3q,sizeof(*Keys->beta3q)*sizeof(int));
+        printf("\nbeta3q: (%d BigNumDigits) ", i);
+        PrintBigNum(Keys->beta3q, i,KEY_RADIX);
+    }
+    
+    printf("\n");
+    fflush(stdout);
+}
+
+
+int PrintPubKey (Keys)
+RSAKeyStorage *Keys;
+{
+    int i=BnnNumDigits(Keys->n,Keys->nl);
+    i = i*BN_DIGIT_SIZE - BnnNumLeadingZeroBitsInDigit(Keys->n[i-1]);
+  
+    printf("\ne: (%d BigNumDigit", Keys->el);
+    if(Keys->el > 1) printf("s) "); else printf(")");
+    PrintBigNum(Keys->e,Keys->el,KEY_RADIX);
+    printf("\nn: (%d BigNumDigits, %d bits) ", Keys->nl, i);
+    PrintBigNum(Keys->n,Keys->nl,KEY_RADIX);
+
+    printf("\n");
+    fflush(stdout);
+}
+
+int PrintPrivKey (Keys)
+RSAKeyStorage *Keys;
+{
+    int i=BnnNumDigits(Keys->n,Keys->nl);
+    i = i*BN_DIGIT_SIZE - BnnNumLeadingZeroBitsInDigit(Keys->n[i-1]);
+  
+    printf("\ne: (%d BigNumDigit", Keys->el);
+    if(Keys->el > 1) printf("s) "); else printf(")");
+    PrintBigNum(Keys->e,Keys->el,KEY_RADIX);
+    printf("\nn: (%d BigNumDigits, %d bits) ", Keys->nl, i);
+    PrintBigNum(Keys->n,Keys->nl,KEY_RADIX);
+
+    if (Keys->pl) { printf("\np: (%d BigNumDigits) ", Keys->pl);
+              PrintBigNum(Keys->p,Keys->pl,KEY_RADIX);
+              printf("\nq: (%d BigNumDigits) ", Keys->ql);
+              PrintBigNum(Keys->q,Keys->ql,KEY_RADIX);
+              printf("\ndp: (%d BigNumDigits) ", Keys->dpl);
+              PrintBigNum(Keys->dp, Keys->dpl,KEY_RADIX);
+              printf("\ndq: (%d BigNumDigits) ", Keys->dql);
+              PrintBigNum(Keys->dq, Keys->dql,KEY_RADIX);
+              printf("\ncr: ");
+              PrintBigNum(Keys->cr, Keys->pl,KEY_RADIX);
+    }
+    else printf("\n no private key parameters.");
+
+    printf("\n");
+    fflush(stdout);
+    }
+    
+
+/*********************************************************************/
+
+/* In-line DES routines here. */
+
+#include "DEScrypto.h"
+
+static KEYschedule local_key_schedule;
+static RSAKeyStorage tempkey;
+
+/*
+ * Decrypts an RSA private key.
+ */
+int recover_private(deskey, encrypted_key, encrypted_key_len, key)
+DESblock *deskey;               /* derived from password */
+char *encrypted_key;            /* input to be decrypted */
+unsigned encrypted_key_len;     /* must be multiple of 8 bytes */
+RSAKeyStorage *key;             /* output with new key in it */
+{
+   unsigned char *outbuf;
+   int rt=0;
+
+   if((outbuf=(unsigned char *)calloc(encrypted_key_len,1))==0)return(0);
+
+   DES_load_key_local( deskey, &local_key_schedule);
+   if (DES_CBC_decrypt_local(0, encrypted_key, encrypted_key_len, 
+                                outbuf, &local_key_schedule)==0) 
+                                                        goto clean;
+   memset(&tempkey,0,sizeof(tempkey));
+   if (key->nl) tempkey.nl=key->nl, BnnAssign(tempkey.n,key->n,key->nl);
+#ifdef DEBUG
+printf("\nDecrypted private key:\n");
+dumphex(outbuf,encrypted_key_len-sizeof(long));
+#endif
+   if (DecodePrivate(outbuf, &tempkey) != NULL) {
+#ifdef DEBUG
+printf("\nRecovered Key:\n");
+PrintTestKey(&tempkey);
+#endif
+        if (rt=TestRSAKeys(&tempkey)) memcpy(key,&tempkey,sizeof(RSAKeyStorage));
+   }
+#ifdef DEBUG
+   else printf("\nDecode Failed.\n");
+#endif
+
+   memset(outbuf,0,encrypted_key_len);
+   memset(&tempkey,0,sizeof(tempkey));
+clean:
+   free(outbuf);
+   return(rt);
+}
+
+/*
+ * Decrypts an RSA private key.
+ */
+int recover_privateP(deskey, encrypted_key, encrypted_key_len, key)
+DESblock *deskey;               /* derived from password */
+char *encrypted_key;            /* input to be decrypted */
+unsigned encrypted_key_len;     /* must be multiple of 8 bytes */
+RSAKeyStorage *key;             /* output with new key in it */
+{
+   unsigned char *outbuf;
+   int rt=0;
+
+   if((outbuf=(unsigned char *)calloc(encrypted_key_len,1))==0)return(0);
+
+   DES_load_key_local( deskey, &local_key_schedule);
+   if (DES_CBC_decrypt_local(0, encrypted_key, encrypted_key_len, 
+                                outbuf, &local_key_schedule)==0) 
+                                                        goto clean;
+   memset(&tempkey,0,sizeof(tempkey));
+   if (key->nl) tempkey.nl=key->nl, BnnAssign(tempkey.n,key->n,key->nl);
+#ifdef DEBUG
+printf("\nDecrypted private key:\n");
+dumphex(outbuf,encrypted_key_len-sizeof(long));
+#endif
+   /*  make sure that we decode the private key with only the prime p  */
+   if (DecodePrivateP(outbuf, &tempkey) != NULL) {
+#ifdef DEBUG
+printf("\nRecovered Key:\n");
+PrintTestKey(&tempkey);
+#endif
+        if (rt=TestRSAKeys(&tempkey)) memcpy(key,&tempkey,sizeof(RSAKeyStorage));
+   }
+#ifdef DEBUG
+   else printf("\nDecode Failed.\n");
+#endif
+
+   memset(outbuf,0,encrypted_key_len);
+   memset(&tempkey,0,sizeof(tempkey));
+clean:
+   free(outbuf);
+   return(rt);
+}
+
+/*
+ * Encrypts an RSA private key.
+ *
+ * NOTE: Contains components to foil use as a general encrypt/decrypt
+ *       facility.
+ *
+ */
+int hide_private(deskey, encrypted_key, encrypted_key_len, key)
+DESblock *deskey;               /* derived from password */
+char **encrypted_key;           /* storage will be allocated */
+unsigned *encrypted_key_len;    /* will be written */
+RSAKeyStorage *key;             /* input must be a valid private key */
+{
+   unsigned char *outbuf, *encoded_key;
+   int len, klen;
+
+   if (TestRSAKeys(key)!=1) return(0); 
+   if ((encoded_key=EncodePrivate(key))==0) return(0) ;
+   len = (((klen=DecodeTotalLength(encoded_key))+7)/8)*8; /* pad */
+   if ((outbuf = (unsigned char *)calloc(len,1)) ==0) 
+                        {FreePrivate(encoded_key); return(0);};
+   memcpy(outbuf,encoded_key,klen);
+   FreePrivate(encoded_key);
+   DES_load_key_local(deskey, &local_key_schedule);
+   DES_CBC_encrypt_local (0, outbuf, len, outbuf, &local_key_schedule);
+   *encrypted_key = (char *)outbuf;
+   *encrypted_key_len = len;
+   return(1);
+}
+
+
+/*
+ * Same as above, but only encrypts prime P
+ */
+int hide_privateP(deskey, encrypted_key, encrypted_key_len, key)
+DESblock *deskey;               /* derived from password */
+char **encrypted_key;           /* storage will be allocated */
+unsigned *encrypted_key_len;    /* will be written */
+RSAKeyStorage *key;             /* input must be a valid private key */
+{
+   unsigned char *outbuf, *encoded_key;
+   int len, klen;
+
+   if (TestRSAKeys(key)!=1) return(0); 
+   if ((encoded_key=EncodePrivateP(key))==0) return(0) ;
+   len = (((klen=DecodeTotalLength(encoded_key))+7)/8)*8;
+   if ((outbuf = (unsigned char *)calloc(len,1)) ==0) 
+                        {FreePrivate(encoded_key); return(0);};
+   memcpy(outbuf,encoded_key,klen);
+   FreePrivate(encoded_key);
+   DES_load_key_local(deskey, &local_key_schedule);
+   DES_CBC_encrypt_local (0, outbuf, len, outbuf, &local_key_schedule);
+   *encrypted_key = (char *)outbuf;
+   *encrypted_key_len = len;
+   return(1);
+}
diff --git a/util/gdss/lib/crypto/algorithm/bigrsacode.c b/util/gdss/lib/crypto/algorithm/bigrsacode.c
new file mode 100644 (file)
index 0000000..ac04b87
--- /dev/null
@@ -0,0 +1,638 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "BigNum.h"
+#include "BigRSA.h"
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+/*
+ * These routines convert ASN.1 to RSAKeyStorage and vice-versa.
+ */
+
+#define INTEGER_TAG    2
+#define BITSTRING_TAG   3
+#define SEQUENCE_TAG   48
+#define CONTEXT_0_TAG  160
+#define CONTEXT_1_TAG  161
+#define CONTEXT_2_TAG  162
+#define CONTEXT_3_TAG  163
+#define CONTEXT_4_TAG  164
+#define CONTEXT_5_TAG  165
+
+/*
+ * Routines for encoding keys.
+ */
+/* 
+ * Compute total size of length field assuming minimal (X.509) encoding.
+ */
+
+int NumEncodeLengthOctets (size) 
+int size;
+{
+        int i = 2;
+        if (size<128) i=1; else if (size>256) i=3 ;
+        return(i);
+}
+
+/*
+ *  Write out length, advance pointer to next thing to be written.
+ */
+unsigned char *EncodeLength (input, size)
+unsigned char *input;
+int size;
+{
+        int i = NumEncodeLengthOctets(size);
+
+        if (i==1) (*input++)=(unsigned char)size ;
+        else {  i--;
+                (*input++)= i+0x80;
+                for (i--;i>=0;i--) (*input++)=(size>>(i*8));
+        }
+        return(input);
+}
+
+/* 
+ * Compute the value of the INTEGER encoded length field for a BigNum 
+ * of length nl.
+ */
+int NumEncodeValueOctets(n,nl)
+int nl;
+BigNum n;
+{
+        int i,j;
+        
+        if (n==0) return (0);
+        
+        i = BnnNumDigits(n,nl);
+        j = BnnNumLeadingZeroBitsInDigit(BnnGetDigit(n+i-1));
+
+        i=i*sizeof(int)-j/8;
+        if ((j%8)==0)i++;
+        return(i);
+}
+
+/* 
+ * Write out BigNum as encoded INTEGER, most to least significant octet, and
+ * return pointer to next octet in stream.  Expects to be supplied with
+ * a sufficiently large buffer.  Always expects the BigNum to be positive.
+ */
+unsigned char *EncodeBigIntegerValue (stream, input, size)
+unsigned char *stream;
+BigNum input;
+unsigned size; 
+{
+        int nl = BnnNumDigits(input, size);
+        BigNumDigit d = BnnGetDigit(input+nl-1);
+        int i = BnnNumLeadingZeroBitsInDigit(d);
+
+        if ((i%8)==0) *stream++ = 0;      /* want positive number, after all */
+        for(i=sizeof(int)-(i/8)-1;i>=0;i--) *stream++ = (unsigned char) (d>>(i*8))&0xff;
+        for(nl--;nl>0;nl--){
+                  d = BnnGetDigit(input+nl-1);
+                  for(i=sizeof(int)-1;i>=0;i--) *stream++ = (d>>(i*8))&0xff;
+        }
+        return(stream);
+}
+
+/*
+ * Make an encoded public key from RSAKeyStorage.  This includes allocating
+ * the stream storage.
+ *
+ * A public key is defined as SEQUENCE { INTEGER, INTEGER }
+ */
+unsigned char *EncodePublic(keys)
+RSAKeyStorage *keys;
+{
+        int mod_len,exp_len,sequence_len,public_key_len ;
+        unsigned char *buffer, *start;
+
+        if ((keys->nl)==0) return(0);
+        
+        mod_len = NumEncodeValueOctets(keys->n,keys->nl);
+        exp_len = NumEncodeValueOctets(keys->e,keys->el);
+        sequence_len = exp_len + mod_len + NumEncodeLengthOctets(exp_len)+
+               NumEncodeLengthOctets(mod_len)+2;
+        public_key_len = NumEncodeLengthOctets(sequence_len)+sequence_len+1;
+
+        if (start = buffer = (unsigned char *) calloc(public_key_len,1)) {
+               *buffer++ = SEQUENCE_TAG;
+               buffer = EncodeLength (buffer,sequence_len);
+               *buffer++= INTEGER_TAG; 
+               buffer=EncodeLength (buffer,mod_len);
+               buffer=EncodeBigIntegerValue(buffer,keys->n,keys->nl);
+               *buffer++= INTEGER_TAG; 
+               buffer=EncodeLength (buffer,exp_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->e,keys->el);
+        }
+        return(start);
+}
+
+void FreePublic(buffer)
+{       free(buffer);
+}
+
+/*
+ * Make an encoded private key from RSAKeyStorage.  This includes allocating
+ * the stream storage.
+ *
+ * A private key is defined as 
+ *   SEQUENCE { 
+ *              primep     INTEGER,           -- always there
+ *              primeq [0] INTEGER OPTIONAL,
+ *              mod    [1] INTEGER OPTIONAL,  -- never there
+ *              exp    [2] INTEGER OPTIONAL,
+ *              dp     [3] INTEGER OPTIONAL,
+ *              dq     [4] INTEGER OPTIONAL,
+ *              cr     [5] INTEGER OPTIONAL }
+ */ 
+unsigned char *EncodePrivate(keys)
+RSAKeyStorage *keys;
+{
+        int p_len, q_len, exp_len, dp_len, dq_len, cr_len, sequence_len ;
+        unsigned char *buffer, *start;
+
+        /* must have two primes to be a private key */
+        if ((keys->pl ==0)||(keys->ql ==0)) return(0);
+
+        sequence_len = 6 +
+                (p_len = NumEncodeValueOctets(keys->p,keys->pl)) +
+                NumEncodeLengthOctets(p_len) +
+                (q_len = NumEncodeValueOctets(keys->q,keys->ql)) +
+                NumEncodeLengthOctets(q_len) +
+                (exp_len = NumEncodeValueOctets(keys->e,keys->el)) +
+                NumEncodeLengthOctets(exp_len) + 
+                (dp_len = NumEncodeValueOctets(keys->dp,keys->dpl)) +
+                NumEncodeLengthOctets(dp_len) +
+                (dq_len = NumEncodeValueOctets(keys->dq,keys->dql)) +
+                NumEncodeLengthOctets(dq_len) + 
+                (cr_len = NumEncodeValueOctets(keys->cr,keys->pl)) +
+                NumEncodeLengthOctets(cr_len);            
+
+        if (start=buffer= 
+         (unsigned char *)calloc(1+NumEncodeLengthOctets(sequence_len)+sequence_len,1)) {
+               *buffer++ = SEQUENCE_TAG;
+               buffer=EncodeLength (buffer,sequence_len);
+               *buffer++= INTEGER_TAG; 
+               buffer=EncodeLength (buffer,p_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->p,keys->pl);
+               *buffer++= CONTEXT_0_TAG;       
+               buffer=EncodeLength (buffer,q_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->q,keys->ql);
+                /*
+                 * No optional modulus.
+                 */
+               *buffer++= CONTEXT_2_TAG;
+               buffer=EncodeLength (buffer,exp_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->e,keys->el);
+               *buffer++= CONTEXT_3_TAG;
+               buffer=EncodeLength (buffer,dp_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->dp,keys->dpl);
+               *buffer++= CONTEXT_4_TAG;
+               buffer=EncodeLength (buffer,dq_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->dq,keys->dql);
+               *buffer++= CONTEXT_5_TAG;
+               buffer=EncodeLength (buffer,cr_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->cr,keys->pl);
+        }
+        return(start);
+}
+
+/* 
+ * The following routine is similar to the above but just puts prime p in 
+ * the encoded private key.
+ */
+unsigned char *EncodePrivateP(keys)
+RSAKeyStorage *keys;
+{
+        int p_len = NumEncodeValueOctets(keys->p,keys->pl);
+        int sequence_len = p_len + 1 + NumEncodeLengthOctets(p_len) ;
+        unsigned char *start, *buffer ;
+
+        if (start=buffer= (unsigned char *)
+             calloc(1+NumEncodeLengthOctets(sequence_len)+sequence_len, 1)) {
+               *buffer++ = SEQUENCE_TAG;
+               buffer=EncodeLength (buffer,sequence_len);
+               *buffer++= INTEGER_TAG; 
+               buffer=EncodeLength (buffer,p_len);
+               buffer=EncodeBigIntegerValue (buffer,keys->p,keys->pl);
+        }
+        return(start);
+}
+
+void FreePrivate(buffer)
+{       free(buffer);
+}
+
+
+/*
+ * Decoding routines.
+ */
+/*
+ * Input is an encoded value field, tells how many octets in the value.
+ * Does not handle indefinite length forms.
+ */
+int DecodeValueLength (input) /* handles non-minimal size case */
+unsigned char *input ;
+{
+        int len , i ;
+
+        if ((*input&0x80)==0) return(*input);
+        if (*input==0x80) return(0);
+        for (i=(*input++ & 0x7f),len=0;i>0;i--) len=(len << 8)+(unsigned int)*input++;
+
+        return(len);
+}
+
+/*
+ * Input is undecoded string.  Returns offset to start of value field.
+ */
+int DecodeHeaderLength (input)
+unsigned char *input ;
+{
+        int tlen = DecodeTypeLength(input);
+        input+=tlen;
+        tlen++;
+        if (*input&0x80) tlen += (*input&0x7f);
+        return(tlen);
+}
+
+/*
+ * Compute number of type bytes.
+ */
+int DecodeTypeLength (input)
+unsigned char *input;
+{       int temp=1;
+        if ((*input&31)==31) do {input++;temp++;} while (*input&0x80) ;
+        return(temp);
+}
+
+/*
+ * Compute offset to next element to decode.
+ * Assumes definite length encoding.
+ */
+int DecodeTotalLength (input)
+unsigned char *input ;
+{
+ return (DecodeHeaderLength(input)+DecodeValueLength(input+DecodeTypeLength(input)));
+}
+
+/* 
+ *  DecodeBigInteger Returns pointer to one byte beyond end of encoded value.
+ *  Reads in least to most significant.
+ */
+unsigned char *DecodeBigInteger (stream, value, size)
+unsigned char *stream;
+BigNum value ;
+int size;
+{
+        int nl = (size+sizeof(int)-1)/sizeof(int);
+        BigNumDigit d;
+        int i,j,k=size-1;
+
+        for(i=0;i<(nl-1);i++){
+            d = 0;
+            for(j=0;j<sizeof(int);j++)
+              d |= (BigNumDigit)(stream[k-j]&0xff)<<(j*8);
+            BnnSetDigit(value+i,d);
+            k-=sizeof(int);
+          }
+/* assert: i = nl-1 */
+        d=0;
+        BnnSetToZero(value+i,1);
+        nl=(size+sizeof(int)-1)%sizeof(int);
+        for(j=0;j<=nl;j++)
+              d |= (BigNumDigit)(stream[k-j]&0xff)<<(j*8);
+        BnnSetDigit(value+i,d);
+
+        return(stream+size);
+}
+
+/* 
+ * DecodePublic.  Initializes RSAKeyStorage. 
+ * Returns pointer to next element if no syntax problems, else zero.
+ */
+unsigned char *DecodePublic (input, keys)
+unsigned char *input;
+RSAKeyStorage *keys;
+{
+        register len;
+        unsigned char *next=input;
+
+        memset(keys,0,sizeof(RSAKeyStorage));
+
+        if ((*input != SEQUENCE_TAG)|| /* must be definite form */
+            (DecodeValueLength(input+1)<=0))  goto syntax_error;
+        input += DecodeHeaderLength(input);
+
+        if (*input != INTEGER_TAG) goto syntax_error;
+        len = DecodeValueLength(input+1);
+        if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+        input+= DecodeHeaderLength(input);
+        input = DecodeBigInteger (input, keys->n, len);
+        keys->nl = 1 + BnnNumDigits(keys->n, (len+sizeof(int)-1)/sizeof(int));
+
+        if (*input != INTEGER_TAG) goto syntax_error;
+        len = DecodeValueLength(input+1);
+        if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+        input+= DecodeHeaderLength(input);
+        input = DecodeBigInteger (input, keys->e, len);
+        keys->el = BnnNumDigits(keys->e, (len+sizeof(int)-1)/sizeof(int));
+
+        /* 
+         * should be at the end of the encoded substring
+         */
+        if (input != next+DecodeTotalLength(next)) goto syntax_error ;
+        
+        FinishKey(keys);
+
+        return(input);
+
+syntax_error:
+#ifdef DEBUG
+printf("\nDecodePublic: Syntax Error.\n");
+#endif
+        return(0);
+}
+
+/* 
+ * DecodePrivate.  Returns pointer to next element if good, else zero.
+ *
+ * Fills in RSAKeyStorage with key parameters if succesful, 
+ * assuming there is enough to go on.  The modulus can be supplied in the structure
+ * already, but other values are assumed cleared as necessary.  The idea
+ * in this case is to call with the same structure as the public key is in to
+ * make it into a private key structure based on decoding the prime p.
+ */
+unsigned char *DecodePrivate (input, keys)
+unsigned char *input;
+RSAKeyStorage *keys;
+{
+        int len, crl ;
+        unsigned char *next=input;
+        BigNum x;
+        
+        if ((*input != SEQUENCE_TAG)|| /* must be definite form */
+            (DecodeValueLength(input+1)<=0))  goto syntax_error;
+        input += DecodeHeaderLength(input);
+
+        if (*input == INTEGER_TAG) { /* must have a p */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(BigNumDigit)*PrimeSize)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->p, len);
+                len = keys->pl = BnnNumDigits(x=keys->p, (len+sizeof(int)-1)/sizeof(int));
+                if ((x[len-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
+                        if (len<PrimeSize) keys->pl = len+1;
+                        else goto syntax_error ;
+        } else goto syntax_error ;
+
+        if (*input == CONTEXT_0_TAG) {  /* may have a q */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(BigNumDigit)*PrimeSize)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->q, len);
+                len= keys->ql = BnnNumDigits(x=keys->q, (len+sizeof(int)-1)/sizeof(int));
+                if ((x[len-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
+                        if (len<PrimeSize) keys->ql = len+1;
+                        else goto syntax_error ;
+        }
+        else keys->ql=0;
+               
+        if (*input == CONTEXT_1_TAG) { /* may have a modulus */
+                memset(keys->n,0,sizeof(*keys->n));
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->n, len);
+                keys->nl = 1 + BnnNumDigits(keys->n, (len+sizeof(int)-1)/sizeof(int));
+        }
+        
+        memset(keys->e,0,sizeof(*keys->e));
+        if (*input == CONTEXT_2_TAG) { /* may have an exponent */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->e, len);
+        } 
+        else  /* use default exponent */
+                BnnSetDigit(keys->e, (BigNumDigit) ((1<<16)+1) );  /* 32 bits */
+        keys->el = BnnNumDigits(keys->e, (len+sizeof(int)-1)/sizeof(int));
+
+        memset(keys->dp,0,sizeof(*keys->dp));
+        if (*input == CONTEXT_3_TAG) { /* may have a dp */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->dp, len);
+                keys->dpl = BnnNumDigits(keys->dp, (len+sizeof(int)-1)/sizeof(int));
+        }
+        else    keys->dpl=0;
+
+        memset(keys->dq,0,sizeof(*keys->dq));
+        if (*input == CONTEXT_4_TAG) { /* may have a dq */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->dq, len);
+                keys->dql = BnnNumDigits(keys->dq, (len+sizeof(int)-1)/sizeof(int));
+        }
+        else    keys->dql=0;
+        
+        memset(keys->cr,0,sizeof(*keys->cr));
+        if (*input == CONTEXT_5_TAG) { /* may have a cr */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(int)*2*DigitLim)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->cr, len);
+                crl = 1;
+        }
+        else    crl=0;
+        
+        /* 
+         * should be at the end of the encoded substring
+         */
+        if (input != next+DecodeTotalLength(next)) goto syntax_error ;
+        
+        if (keys->ql == 0)              /* need to regenerate q */
+                if (keys->nl == 0) goto syntax_error; /* must know n */
+                else {
+                        BigNumDigit xx[4*DigitLim];
+                        int ql, pl, nl, i;
+                        
+                        memset(xx,0,sizeof(xx));
+                        BnnAssign(xx,keys->n,nl=keys->nl);
+                        BnnDivide(xx,nl,keys->p,pl=keys->pl);
+                        /* check that p evenly divided n */
+                        for(i=0;i<pl;i++) if(xx[i]) goto syntax_error;
+                        ql = keys->ql = BnnNumDigits(xx,nl) - pl;
+                        BnnAssign(keys->q,xx+pl,ql);
+                        if ((x[ql-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
+                                if (ql<PrimeSize) keys->ql = ql+1;
+                                else goto syntax_error ;
+                }
+
+        if (keys->nl == 0){      /* need to regenerate n */
+                 int nl = keys->pl + keys->ql;
+                 memset(keys->n,0,sizeof(*keys->n));
+                 BnnMultiply(keys->n,nl,keys->p,keys->pl,keys->q,keys->ql);
+                 keys->nl=nl;
+        }
+
+        if(FinishKey(keys) == 0) goto syntax_error ;
+
+        return(input);
+syntax_error:
+#ifdef DEBUG
+printf("\nDecodePrivate: Syntax Error.\n");
+#endif
+#ifndef DEBUG
+        memset(keys->p,0,sizeof(*keys->p));
+        memset(keys->q,0,sizeof(*keys->q));
+        memset(keys->dp,0,sizeof(*keys->dp));
+        memset(keys->dq,0,sizeof(*keys->dq));
+        memset(keys->cr,0,sizeof(*keys->cr));
+        keys->pl=keys->ql=keys->dpl=keys->dql=0;
+#endif
+        return(0);
+}
+
+/* 
+ * DecodePrivateP.  Returns pointer to next element if good, else zero.
+ *
+ * Fills in RSAKeyStorage with key parameters if succesful, 
+ * assuming there is enough to go on.  The modulus can be supplied in the structure
+ * already, but other values are assumed cleared as necessary.  The idea
+ * in this case is to call with the same structure as the public key is in to
+ * make it into a private key structure based on decoding the prime p.
+ * Only the prime p must be passed in.
+ */
+unsigned char *DecodePrivateP (input, keys)
+unsigned char *input;
+RSAKeyStorage *keys;
+{
+        int len, crl ;
+        unsigned char *next=input;
+        BigNum x;
+        
+        if ((*input != SEQUENCE_TAG)|| /* must be definite form */
+            (DecodeValueLength(input+1)<=0))  goto syntax_error;
+        input += DecodeHeaderLength(input);
+
+        if (*input == INTEGER_TAG) { /* must have a p */
+                len = DecodeValueLength(input+1);
+                if ((len<=0)||(len >= sizeof(BigNumDigit)*PrimeSize)) goto syntax_error;
+                input+= DecodeHeaderLength(input);
+                input = DecodeBigInteger (input, keys->p, len);
+                len = keys->pl = BnnNumDigits(x=keys->p, (len+sizeof(int)-1)/sizeof(int));
+                if ((x[len-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
+                        if (len<PrimeSize) keys->pl = len+1;
+                        else goto syntax_error ;
+        } else goto syntax_error ;
+
+        if (*input == CONTEXT_0_TAG) goto syntax_error ;
+        else keys->ql=0;
+               
+        if (*input == CONTEXT_1_TAG) goto syntax_error ;
+        
+        memset(keys->e,0,sizeof(*keys->e));
+        if (*input == CONTEXT_2_TAG) goto syntax_error ;
+        else  /* use default exponent */
+                BnnSetDigit(keys->e, (BigNumDigit) ((1<<16)+1) );  /* 32 bits */
+        keys->el = BnnNumDigits(keys->e, (len+sizeof(int)-1)/sizeof(int));
+
+        memset(keys->dp,0,sizeof(*keys->dp));
+        if (*input == CONTEXT_3_TAG) goto syntax_error ;
+        else    keys->dpl=0;
+
+        memset(keys->dq,0,sizeof(*keys->dq));
+        if (*input == CONTEXT_4_TAG) goto syntax_error ;
+        else    keys->dql=0;
+        
+        memset(keys->cr,0,sizeof(*keys->cr));
+        if (*input == CONTEXT_5_TAG) goto syntax_error ;
+        else    crl=0;
+        
+        /* 
+         * should be at the end of the encoded substring
+         */
+        if (input != next+DecodeTotalLength(next)) goto syntax_error ;
+        
+        if (keys->ql == 0)              /* need to regenerate q */
+                if (keys->nl == 0) goto syntax_error; /* must know n */
+                else {
+                        BigNumDigit xx[4*DigitLim];
+                        int ql, pl, nl, i;
+                        
+                        memset(xx,0,sizeof(xx));
+                        BnnAssign(xx,keys->n,nl=keys->nl);
+                        BnnDivide(xx,nl,keys->p,pl=keys->pl);
+                        /* check that p evenly divided n */
+                        for(i=0;i<pl;i++) if(xx[i]) goto syntax_error;
+                        ql = keys->ql = BnnNumDigits(xx,nl) - pl;
+                        BnnAssign(keys->q,xx+pl,ql);
+                        if ((x[ql-1]&(3<<BN_DIGIT_SIZE-2))!=0) 
+                                if (ql<PrimeSize) keys->ql = ql+1;
+                                else goto syntax_error ;
+                }
+
+        if (keys->nl == 0){      /* need to regenerate n */
+                 int nl = keys->pl + keys->ql;
+                 memset(keys->n,0,sizeof(*keys->n));
+                 BnnMultiply(keys->n,nl,keys->p,keys->pl,keys->q,keys->ql);
+                 keys->nl=nl;
+        }
+
+        if(FinishKey(keys) == 0) goto syntax_error ;
+
+        return(input);
+syntax_error:
+#ifdef DEBUG
+printf("\nDecodePrivateP: Syntax Error.\n");
+#endif
+#ifndef DEBUG
+        memset(keys->p,0,sizeof(*keys->p));
+        memset(keys->q,0,sizeof(*keys->q));
+        memset(keys->dp,0,sizeof(*keys->dp));
+        memset(keys->dq,0,sizeof(*keys->dq));
+        memset(keys->cr,0,sizeof(*keys->cr));
+        keys->pl=keys->ql=keys->dpl=keys->dql=0;
+#endif
+        return(0);
+}
diff --git a/util/gdss/lib/crypto/algorithm/bigsignverify.c b/util/gdss/lib/crypto/algorithm/bigsignverify.c
new file mode 100644 (file)
index 0000000..3185728
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <syslog.h>
+#include "bigsignverify.h"
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+/* in-line crypto routines here */
+
+#include "RSAcrypto.h"
+#include "DEScrypto.h"
+
+#define CLOCK_SKEW  5*60
+
+#ifdef mips
+#undef BnnSetToZero
+#endif
+
+/*
+ * Global
+ */
+static BigNumDigit buffer1[2*DigitLim], buffer2[2*DigitLim];
+
+/*
+ * RSASign takes a key in local format and a counted character string and
+ * writes a signature in "BER INTEGER" encoded format into the supplied buffer.
+ * The length in bytes is also written.
+ *
+ */
+
+int RSASign (toBeSigned, datalen, key, signature, siglen)
+RSAKeyStorage *key;
+unsigned char *toBeSigned;
+unsigned char *signature;       /* output assumed large enough to hold modulus */
+int datalen, *siglen;           /* in bytes */
+{
+        char *temp = (char *)buffer2;
+        int i, nl=key->nl, pl=key->pl, ql=key->ql;
+        BigNum signed_digest = buffer1, p = key->p, q = key->q;
+
+        if ((pl==0)||(ql==0)) return(0);        /* not a private key */
+        RSA_MD2(toBeSigned, datalen, temp);     /* hash to temp */
+        BnnSetToZero(signed_digest,nl);
+        for (i=0;i<16;i++)                      /* copy in right order */
+          signed_digest[i/sizeof(BigNumDigit)]|=
+                ((0x0ff&temp[15-i])<<((i%sizeof(BigNumDigit))*8));
+       signed_digest[4] |= 0x00000410;
+        rsadecrypt_1(signed_digest, signed_digest, key);
+        *siglen = NumEncodeValueOctets(signed_digest, nl);
+        if(EncodeBigIntegerValue(signature, signed_digest, nl)) return(TRUE);
+        else return(FALSE);
+}
+
+/*
+ * RSAVerify takes an encoded signature, allegedly signed data and key
+ * and yields a boolean (TRUE/FALSE).
+ */
+
+int RSAVerify (allegedSigned, datalen, key, signature, siglen)
+RSAKeyStorage *key;
+char *allegedSigned, *signature;
+int datalen, siglen;
+{
+        char *temp=(char *)buffer2;
+        BigNum md = buffer1, buffer = buffer2, n = key->n;
+        int i, bl, nl=key->nl;
+
+        if ((bl=(siglen+sizeof(BigNumDigit)-1)/sizeof(BigNumDigit)) > nl) {
+#ifdef DEBUG        
+printf("\nRSAVerify: signature has more BigNumDigits than the modulus\n");
+#endif
+                return(FALSE);
+        }
+
+        BnnSetToZero(md,nl);
+        RSA_MD2(allegedSigned, datalen, temp);
+        for (i=0;i<16;i++)                      /* copy in right order */
+          md[i/sizeof(BigNumDigit)]|=((0x0ff&temp[15-i])<<((i%sizeof(BigNumDigit))*8));
+
+        BnnSetToZero(buffer,nl);
+        DecodeBigInteger(signature, buffer, siglen);
+        if (BnnCompare(n, nl, buffer, bl)!=1) {
+#ifdef DEBUG
+printf("\nRSAVerify: signature is larger BigNum value than modulus\n");
+#endif
+                return(FALSE);
+        }
+
+        rsaencrypt_1(buffer, buffer, key);
+#ifdef DEBUG
+printf("RSAVerify: computed md:\n");
+dumphex(md,nl*8);
+printf("RSAVerify: recovered md:\n");
+dumphex(buffer,nl*8);
+#endif
+       buffer[4] &= 0xffff0000;
+        if (BnnCompare(md,nl,buffer,nl)==0)  return (TRUE);
+#ifdef DEBUG
+printf("\nRSAVerify: signature verification failed.\n");
+#endif
+        return(FALSE);
+
+}
+
+\f
+/*
+ * The initialization routine generates a DES key and encrypts it under
+ * the public key of the intended verifier principal.
+ *
+ * A word about byte ordering.  The "least significant byte" of a BigNum
+ * is the byte that has the least significant bit in it.  The "most
+ * significant byte" has the most significant bit in it.
+ *
+ */
+#include "endian.h"
+#define RandomOffset (sizeof(DESblock)+2*sizeof(time_t))
+#define BYTE_IN_BIGNUM(x) (SPHINX_ENDIAN?(sizeof(BigNumDigit)-(x%sizeof(BigNumDigit)-1)):x)
+
+int InitAuthenticationKey (verifier, delegation, new_key, encrypted_key, 
+                                encrypted_key_len, when_expires)
+RSAKeyStorage *verifier, *delegation;
+DESblock *new_key;
+unsigned char *encrypted_key;
+int *encrypted_key_len;
+time_t when_expires;
+{
+        time_t when_signed;
+        BigNum vn=verifier->n, p = buffer1, temp = buffer1;
+        int i, leading_zero_bytes, vnl=verifier->nl, tl;
+        RNGState rng;
+        
+        /*
+         * This is all we need the delegation key for.
+         */
+        read_rng_state(&rng);
+        if(((rng.count)==0)&&delegation) initialize_rng_state(delegation->p,16);
+
+        /*
+         * Fill temporary storage with a random number.
+         */
+        BnnSetToZero(temp,vnl+1);
+        tl = BnnNumDigits(vn,vnl);
+        random_BigNum(temp,tl);
+
+        /* 
+         * There must always be one more significant byte in the modulus than 
+         * the one that has the "64" in the encrypted key.
+         */
+#ifdef DEBUG
+printf("\nleading zero bits: %d, vn[tl-1]=%08x\n",
+                BnnNumLeadingZeroBitsInDigit(vn[tl-1]), vn[tl-1]);
+#endif
+        leading_zero_bytes=BnnNumLeadingZeroBitsInDigit(BnnGetDigit(vn+tl-1))/8;
+        if (leading_zero_bytes == (sizeof(BigNumDigit)-1)) { 
+        /* 
+         * There is only one significant byte in the most significant BigNumDigit,
+         * so zero out top digit and put "64" into the most significant byte of 
+         * the next-to-top digit 
+         */
+                temp[tl-1] = 0;
+                temp[tl-2] &= ~(0x00ff << 8*leading_zero_bytes); 
+                temp[tl-2] |= 64 << 8*leading_zero_bytes ;
+                }
+        else { 
+        /* 
+         * Zero out bytes with significant stuff in them, and put "64"
+         * in the next-most-significant byte.
+         */
+                for(i=0;i<=leading_zero_bytes+1;i++)
+                        temp[tl-1] &= ~(0x00ff << (8*(sizeof(BigNumDigit)-1-i)));
+                temp[tl-1] |= 64<<((sizeof(BigNumDigit)-2-leading_zero_bytes)*8);
+        }
+#ifdef DEBUG
+printf("\nleading_zero_bytes=%d\n",leading_zero_bytes);
+printf("\ntl=%d, vnl=%d, temp[tl-1]=%08x, temp[tl-2]=%08x\n", tl, vnl, temp[tl-1], temp[tl-2]);
+#endif
+
+        BnnSetToZero(temp, (RandomOffset+4)/sizeof(BigNumDigit));
+        /*
+         * Generate 8 bytes of DES key, copy into buffer in right order
+         */
+        random_bytes(temp, sizeof(DESblock));
+        for (i=0;i<sizeof(DESblock);i++) new_key->bytes[sizeof(DESblock)-i-1] =
+           (temp[i/sizeof(BigNumDigit)]>>((i%sizeof(BigNumDigit)*8)));
+
+        /*
+         * Assume sizeof(time_t) == sizeof(BigNumDigit).
+         * Everyone has to swap these bytes, I guess.
+         */
+        time(&when_signed);
+        p = &temp[sizeof(DESblock)/sizeof(BigNumDigit)];
+        p[0]=when_signed;
+        p[1]=when_expires;
+/*
+        for(i=0;i<sizeof(time_t);i++) {
+             p[0] |= ((when_signed>>(i*8))&(BigNumDigit)0xff)<<((sizeof(time_t)-1-i)*8);
+             p[1] |= ((when_expires>>(i*8))&(BigNumDigit)0xff)<<((sizeof(time_t)-1-i)*8);
+             }
+*/
+#ifdef DEBUG
+printf("\nBlock to encrypt: (low to high order bytes) \n");
+dumphex(temp,tl*sizeof(BigNumDigit));
+printf("\nModulus:\n");
+dumphex(vn,vnl*sizeof(BigNumDigit));
+#endif
+        rsaencrypt_1(temp,temp,verifier);
+        *encrypted_key_len = NumEncodeValueOctets(temp,tl);
+        if (EncodeBigIntegerValue(encrypted_key,temp,tl)) return(TRUE);
+        else return(FALSE);
+}
+
+/*
+ * The accept routine takes in encoded elements and yields the transferred
+ * DES key along with an expiration date.
+ *
+ */
+int AcceptAuthenticationKey (verifier, new_key, encrypted_key, 
+                                encrypted_key_len, when_expires)
+RSAKeyStorage *verifier;
+DESblock *new_key;
+unsigned char *encrypted_key;
+int encrypted_key_len;
+time_t *when_expires;
+{
+        time_t now, when_signed, when_expires_temp ;
+        int i, tl, vnl=verifier->nl, leading_zero_bytes;
+        BigNum vn=verifier->n, p = buffer1, temp = buffer1;
+        char *ptr;
+
+        BnnSetToZero(temp,vnl+1);
+        if ((tl=(encrypted_key_len+sizeof(BigNumDigit)-1)/sizeof(BigNumDigit)) > vnl) {
+#ifdef DEBUG
+printf("\nAcceptAuthenticationKey: Signature has more BigNumDigits than modulus.\n");
+#endif
+syslog(LOG_INFO, "AAK : Signature has more BigNumDigits than modulus");
+                goto error;
+        }
+        
+        DecodeBigInteger(encrypted_key,temp,encrypted_key_len);
+        if (BnnCompare(vn,vnl,temp,tl) != 1) {
+#ifdef DEBUG
+printf("\nAcceptAuthenticationKey: Signature is larger than modulus.\n");
+#endif
+syslog(LOG_INFO, "AAK : Signature is larger than modulus");
+                goto error;
+        }
+       
+        rsadecrypt_1(temp,temp,verifier);
+#ifdef DEBUG
+printf("\nAcceptAuthenticationKey: Decrypted key:\n");
+dumphex(temp,(vnl+1)*sizeof(BigNumDigit));
+fflush(stdout);
+#endif
+        /* 
+         * Check for a "64" in the right place.
+         */
+        tl = BnnNumDigits(vn,vnl);
+        leading_zero_bytes=BnnNumLeadingZeroBitsInDigit(BnnGetDigit(vn+tl-1))/8;
+        if (leading_zero_bytes == sizeof(BigNumDigit)-1) { 
+                if ((temp[tl-1] != 0) || 
+                        (((temp[tl-2]>>(8*leading_zero_bytes))&0x0ff) != 64)) {
+#ifdef DEBUG
+printf("\nTop digit not zero, or 64 byte test failed.\n");
+#endif
+syslog(LOG_INFO, "AAK : Top digit not zero, or 64 byte test failed");
+                                goto error ;
+                        }
+                }
+        else {  for(i=0;i<leading_zero_bytes;i++)
+                 if(((temp[tl-1]>>((sizeof(BigNumDigit)-leading_zero_bytes-1+i)*8))&0x0ff)
+                                != 0) {
+#ifdef DEBUG
+printf("\nTop byte zero test failed.\n");
+#endif
+syslog(LOG_INFO, "AAK : Top byte zero test failed");
+                                goto error ;
+                }
+                if (((temp[tl-1]>>((sizeof(BigNumDigit)-2-leading_zero_bytes)*8))&0xff)
+                                != 64){
+#ifdef DEBUG
+printf("\nTop byte 64 test failed.\n");
+#endif
+syslog(LOG_INFO, "AAK : Top byte 64 test failed");
+                                goto error ;
+                }
+        }
+
+        ptr = (char *) &temp[RandomOffset/sizeof(BigNumDigit)];
+        for (i=0;i<4;i++) if (*ptr++ !=0) {
+#ifdef DEBUG
+printf("\nAcceptAuthenticationKey: Zero mid-buffer error.\n");
+#endif
+syslog(LOG_INFO, "AAK : Zero mid-buffer error");
+                goto error;
+        }
+
+        when_signed=when_expires_temp=0;
+
+        p = &temp[sizeof(DESblock)/sizeof(BigNumDigit)];
+        when_signed = p[0];
+        when_expires_temp = p[1];
+/*
+        for(i=0;i<sizeof(time_t);i++) {
+             when_signed |= ((p[0]>>(i*8))&(BigNumDigit)0x0ff)<<((sizeof(time_t)-1-i)*8);
+             when_expires_temp |= ((p[1]>>(i*8))&(BigNumDigit)0x0ff)<<((sizeof(time_t)-1-i)*8);
+             }
+*/
+        time(&now);
+#ifdef DEBUG
+printf("\n Signed:  %s", ctime(&when_signed));
+printf("\n Expires: %s\n", ctime(&when_expires_temp));
+#endif
+
+        if((when_signed > now + CLOCK_SKEW) || (when_expires_temp < now - CLOCK_SKEW)) {
+#ifdef DEBUG
+printf("\nAcceptAuthenticationKey: Key Has Expired.\n");
+#endif
+syslog(LOG_INFO, "AAK : signed on (%d) %s", when_signed, ctime(&when_signed));
+syslog(LOG_INFO, "AAK : expire on (%d) %s", when_expires_temp, ctime(&when_expires_temp));
+syslog(LOG_INFO, "AAK : key has expired - now is %d", now);
+               goto error;
+        }
+        *when_expires = when_expires_temp;
+
+        for (i=0;i<sizeof(DESblock);i++) new_key->bytes[sizeof(DESblock)-i-1] =
+           (temp[i/sizeof(BigNumDigit)]>>((i%sizeof(BigNumDigit)*8)));
+        return(TRUE);
+
+error:
+        return(FALSE);
+        
+}
+
diff --git a/util/gdss/lib/crypto/algorithm/gentables.c b/util/gdss/lib/crypto/algorithm/gentables.c
new file mode 100644 (file)
index 0000000..e7faa48
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_ITAR
+#define SPHINX_ITAR
+static char copyright[] = "\n Copyright, 1989, 1990, Digital Equipment Corporation \n";
+static char warning[]= "\n  This software is subject to export restrictions under \
+\n  the U.S. Department of State's International Traffic in Arms \
+\n  Regulations (ITAR).  This software must not be transmitted \
+\n  in source form outside the United States or to a foreign \
+\n  national in the United States without a valid U.S. State \
+\n  Department export license. ";
+#endif
+
+/*
+ * Generate the permutation tables for a software implementation of DES.
+ */
+#include <stdio.h>
+
+#define FILENAME       "tables.h"
+#define EFILE           "endian.h"
+
+typedef unsigned long  INT32;   /* generic type for 32-bit integer */
+
+/*
+ * The following tables are based on those in the Data Encryption
+ * Standard document (FIPS PUB 46).
+ */
+
+/*
+ * Initial permutation IP
+ */
+static char ip[] = { 2, 4, 6, 8, 1, 3, 5, 7 };
+
+/*
+ * Final permutation IP^-1
+ */
+static char fp[] = { 8, 7, 6, 5, 4, 3, 2, 1 };
+
+/*
+ * The (in)famous S-boxes
+ */
+static char si[8][64] = {
+       /*
+        * S1
+        */
+       14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
+        0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
+        4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
+       15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
+
+       /*
+        * S2
+        */
+       15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
+        3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
+        0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
+       13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
+
+       /*
+        * S3
+        */
+       10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
+       13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
+       13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
+        1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
+
+       /*
+        * S4
+        */
+        7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
+       13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
+       10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
+        3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
+
+       /*
+        * S5
+        */
+        2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
+       14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
+        4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
+       11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
+
+       /*
+        * S6
+        */
+       12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
+       10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
+        9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
+        4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
+
+       /*
+        * S7
+        */
+        4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
+       13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
+        1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
+        6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
+
+       /*
+        * S8
+        */
+       13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
+        1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
+        7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
+        2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
+};
+
+/*
+ * 32-bit permutation function P used on the output of the S-boxes
+ */
+static char p32i[] = { 
+       16,  7, 20, 21,
+       29, 12, 28, 17,
+        1, 15, 23, 26,
+        5, 18, 31, 10,
+        2,  8, 24, 14,
+       32, 27,  3,  9,
+       19, 13, 30,  6,
+       22, 11,  4, 25
+};
+
+static char ei[] = {
+       32,  1,  2,  3,  4,  5,
+        4,  5,  6,  7,  8,  9,
+        8,  9, 10, 11, 12, 13,
+       12, 13, 14, 15, 16, 17,
+       16, 17, 18, 19, 20, 21,
+       20, 21, 22, 23, 24, 25,
+       24, 25, 26, 27, 28, 29,
+       28, 29, 30, 31, 32,  1 
+};
+
+/*
+ * Permuted choice table (key)
+ */
+static char pc1[] = {
+       57, 49, 41, 33, 25, 17,  9,
+        1, 58, 50, 42, 34, 26, 18,
+       10,  2, 59, 51, 43, 35, 27,
+       19, 11,  3, 60, 52, 44, 36,
+
+       63, 55, 47, 39, 31, 23, 15,
+        7, 62, 54, 46, 38, 30, 22,
+       14,  6, 61, 53, 45, 37, 29,
+       21, 13,  5, 28, 20, 12,  4
+};
+
+/*
+ * Permuted choice key (table)
+ */
+static char pc2[] = {
+       14, 17, 11, 24,  1,  5,
+        3, 28, 15,  6, 21, 10,
+       23, 19, 12,  4, 26,  8,
+       16,  7, 27, 20, 13,  2,
+       41, 52, 31, 37, 47, 55,
+       30, 40, 51, 45, 33, 48,
+       44, 49, 39, 56, 34, 53,
+       46, 42, 50, 36, 29, 32
+};
+
+/*
+ * Note that the Standard is written in Big Endian terms so bit 1 is the
+ * high bit of the byte.
+ */
+static int bytebit[] = {
+    0200, 0100, 040, 020, 010, 04, 02, 01
+};
+
+/*
+ * Generated tables
+ */
+static INT32 iperma[256],ipermb[256];
+static INT32 fperma[256],fpermb[256];
+static INT32 sp[8][64];
+static char pc1bit[56],pc1byte[56];
+
+static FILE *tables;
+static FILE *endian;
+
+/*
+ * Initialize a permutation array.
+ */
+static perminit( perma,permb,p )
+INT32 perma[256],permb[256];
+char p[8];
+{
+    register int i,j;
+    
+    /*
+     * Clear out the permutation array.
+     */
+    memset(perma, 0, sizeof(perma));
+    memset(permb, 0, sizeof(permb));
+    
+    /*
+     * Now produce the table.
+     */
+    for (i = 0; i < 4; i++)
+       for (j = 0; j < 256; j++)
+       {
+           if ((j & bytebit[p[i] - 1]) != 0)
+               perma[j] |= 1L << (8 * (3 - i));
+           if ((j & bytebit[p[i+4] - 1]) != 0)
+               permb[j] |= 1L << (8 * (3 - i));
+       }
+}
+
+outperm( perma,permb,name,comment )
+INT32 perma[256],permb[256];
+char *name,*comment;
+{
+    register int i, j;
+    
+    fprintf(tables, "/*\n * %s\n */\n", comment);
+    fprintf(tables, "static INT32 %sa[256] = {", name);
+    for (i = 0; i < 64; i++)
+    {
+       fprintf(tables, "\n    ");
+       for (j = 0; j < 4; j++)
+           fprintf(tables, "0x%lx, ", (long)perma[(i * 4) + j]);
+    }
+
+    fprintf(tables, "\n};\n\nstatic INT32 %sb[256] = {", name);
+    for (i = 0; i < 64; i++)
+    {
+       fprintf(tables, "\n    ");
+       for (j = 0; j < 4; j++)
+           fprintf(tables, "0x%lx, ", (long)permb[(i * 4) + j]);
+    }
+    fprintf(tables, "\n};\n\n");
+}
+
+/*
+ * Intialize the combined S and P boxes
+ */
+static spinit()
+{
+    register int i,j,k,l;
+    INT32 perm;
+    unsigned char inv[32];
+    
+    /*
+     * Invert the pbox array.
+     */
+    for (i = 0; i < 32; i++)
+       inv[p32i[i] - 1] = i;
+
+    /*
+     * Now build a combination of the p and s boxes.
+     */
+    for (i = 0; i < 8; i++)
+       for (j = 0; j < 64; j++)
+       {
+           perm = 0;
+           
+           /*
+            * Compute the index into the sbox table. The row number is
+            * formed from bits 0 and 5 (VAX terminology) and the column
+            * number from the middle 4 bits.
+            */
+           l = (j & 0x20) | ((j & 1) ? 0x10 : 0) | ((j >> 1) & 0xF);
+           
+           /*
+            * Each sbox entry gives us 4 bits which must be merged into
+            * the final table.
+            */
+           for (k = 0; k < 4; k++)
+           {
+               if ((si[i][l] & (8 >> k)) != 0)
+                   perm |= 1L << (31 - inv[(i * 4) + k]);
+           }
+           sp[i][j] = perm;
+       }
+}
+
+outsp()
+{
+    register int i,j,k;
+    
+    fprintf(tables, "/*\n * Combined s and p boxes\n */\n");
+    fprintf(tables, "static INT32 sp[8][64] = {");
+    
+    for (i = 0; i < 8; i++)
+    {
+       fprintf(tables, "\n    /*\n     * Permuted S box %d\n     */", i);
+       for (j = 0; j < 16; j++)
+       {
+           fprintf(tables, "\n    ");
+           for (k = 0; k < 4; k++)
+               fprintf(tables, "0x%lx, ", (long)(sp[i][(j * 4) + k]));
+       }
+    }
+    fprintf(tables, "\n};\n\n");
+}
+
+choiceinit( pc,bit,byte )
+char pc[],bit[],byte[];
+{
+    register int i;
+    
+    /*
+     * Convert a permuted choice table from bit addressing to 2 tables
+     * giving the byte and bit within the byte address.
+     */
+    for (i = 0; i < 56; i++)
+    {
+       bit[i] = bytebit[(pc[i] - 1) & 07];
+       byte[i] = (pc[i] - 1) >> 3;
+    }
+}
+
+outchoice( bit,byte,name,comment )
+char bit[],byte[],*name,*comment;
+{
+    register int i,j;
+    
+    fprintf(tables, "/*\n * %s\n */\n", comment);
+    fprintf(tables, "static unsigned char %sbit[56] = {", name);
+    for (i = 0; i < 7; i++)
+    {
+       fprintf(tables, "\n    ");
+       for (j = 0; j < 8; j++)
+           fprintf(tables, "0x%x, ", bit[(i * 8) + j] & 0xFF);
+    }
+    fprintf(tables, "\n};\n\n");
+
+    fprintf(tables, "static unsigned char %sbyte[56] = {", name);
+    for (i = 0; i < 7; i++)
+    {
+       fprintf(tables, "\n    ");
+       for (j = 0; j < 8; j++)
+           fprintf(tables, "%2d, ", byte[(i * 8) + j]);
+    }
+    fprintf(tables, "\n};\n\n");
+    
+}
+
+INT32 swap( x )
+INT32 x;
+{
+    register char *cp,temp;
+    
+    cp = (char *)&x;
+    temp = cp[3];
+    cp[3] = cp[0];
+    cp[0] = temp;
+    
+    temp = cp[2];
+    cp[2] = cp[1];
+    cp[1] = temp;
+    
+    return (x);
+}
+
+main( argc,argv )
+int argc;
+char *argv[];
+{
+    register int i;
+    union { char bytes [ sizeof(long) ];
+            long longs; } testword ;
+    long now;
+    
+    time(&now);
+
+    testword.longs = 1;
+
+    if ((endian = fopen(EFILE, "w")) == NULL)
+    {
+       perror("endian");
+       exit(2);
+    }
+
+    fprintf(endian, "/* endian.h */\n");
+    fprintf(endian, "/*\n * Machine generated on %s */\n", ctime(&now));
+    fprintf(endian, "\n#ifndef SPHINX_ENDIAN\n\n");
+    fprintf(endian, "/*\n");
+    fprintf(endian, " * Little endian machines are DEC/Intel like\n");
+    fprintf(endian, " * Big endian machines are IBM/SPARC/Motorola like\n *\n");
+    fprintf(endian, " * This machine is ");
+    if (testword.bytes[0]) fprintf (endian,"little "); else fprintf(endian,"big ");
+    fprintf(endian, "endian since the value of SPHINX_ENDIAN is %u\n", testword.bytes[0]);
+    fprintf(endian, " *\n */\n\n");
+    fprintf(endian, "\n#define SPHINX_ENDIAN %u\n\n", testword.bytes[0]);
+    fprintf(endian, "\n#endif\n\n\n");
+    
+    if ((tables = fopen(FILENAME, "w")) == NULL)
+    {
+       perror("gentables");
+       exit(2);
+    }
+    
+    fprintf(tables, "/*\n * Machine generated tables for DES encryption %s */\n\n",
+                                        ctime(&now));
+    if (testword.bytes[0]) 
+         fprintf(tables, "/*\n * Little Endian (DEC/Intel like)\n */\n\n");
+    else fprintf(tables, "/*\n * Big Endian (IBM/SPARC/Motorola like)\n */\n\n");
+
+    perminit(iperma, ipermb, ip);
+    perminit(fperma, fpermb, fp);
+
+    if (testword.bytes[0]) /* little endian */
+    /*
+     * Perform a byte swap on the final permutation table.
+     */
+    for (i = 0; i < 256; i++)
+    {
+       fperma[i] = swap(fperma[i]);
+       fpermb[i] = swap(fpermb[i]);
+    }
+    
+    outperm(iperma, ipermb, "iperm", "Initial permutation");
+    outperm(fperma, fpermb, "fperm", "Final permutation");
+    spinit();
+    outsp();
+    choiceinit(pc1, pc1bit, pc1byte);
+    outchoice(pc1bit, pc1byte, "pc1", "Permuted choice 1 table");
+    exit(0);
+}
diff --git a/util/gdss/lib/crypto/algorithm/hashes.h b/util/gdss/lib/crypto/algorithm/hashes.h
new file mode 100644 (file)
index 0000000..a9ac0c9
--- /dev/null
@@ -0,0 +1,60 @@
+/* hashes.h */
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+
+/*
+ * Externally Callable Routines. All arguments are character pointers
+ * or integer lengths.
+ */
+
+#ifndef SPHINX_HASHES
+#define SPHINX_HASHES
+
+void RSA_MD2();         /* RSA_MD2(input_buffer, length, hash_result) */
+void RSA_MD4();         /* RSA_MD4(input_buffer, length, hash_result) */
+void RSA_MAC();         /* RSA_MAC(input_buffer, length, mac, output_length) */
+void RSA_MD();          /* RSA_MD(input_buffer, length, hash_result) */
+
+int H1();               /* H1(username, password, hash_result) */
+int H2();               /* H2(username, password, hash_result) */
+
+/*
+ * Common data structures
+ */
+#define MAC_BLOCK_SIZE 8
+#define MD_BLOCK_SIZE  16
+
+
+#endif
+
diff --git a/util/gdss/lib/crypto/algorithm/random.c b/util/gdss/lib/crypto/algorithm/random.c
new file mode 100644 (file)
index 0000000..e117e51
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/* 
+ * NOTES:
+ *
+ *    1. This file is BSD 4.2, and possibly Ultrix specific
+ *    2. This file includes in-line DES code
+ *
+ * CONTENTS:
+ *    1. Random number generator components
+ *    2. DES MAC routine.
+ */
+#include <stdio.h>
+#ifndef ultrix
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include <sys/types.h>
+#include <sys/resource.h>
+#ifdef POSIX
+#include <sys/utsname.h>
+#endif
+#ifdef SOLARIS
+#include <sys/times.h>
+#endif
+
+#include "DEScrypto.h"
+
+static RNGState rng ;  /* this needs to be saved and restored as needed */
+static KEYschedule random_key_schedule;
+static unsigned char scramble_key[8] = {0x01, 0x23, 0x45, 0x67, 
+                                        0x89, 0xab, 0xcd, 0xef};
+static void DES_MAC();
+
+/*
+ * Routines to checkpoint and restore random number generator state.
+ */
+void read_rng_state ( state )
+RNGState *state ;
+{  
+   memcpy (state, &rng, sizeof(RNGState));
+}
+
+void restore_rng_state ( state )
+RNGState *state ;
+{
+   memcpy (&rng, state, sizeof(RNGState));
+   DES_load_key_local( &rng.key, &random_key_schedule );
+}
+
+
+/*
+ *
+ * Initialize random number generator based on nl characters supplied by caller.
+ * Introduce some other uncertanity based on current time and resource usage.
+ *
+ */
+void initialize_rng_state (seed,nl)
+unsigned char * seed;
+int nl;
+{  
+   struct timezone tz;
+   struct timeval tv;
+   struct rusage *rs;
+   int i;
+
+   /* start with hash of input string */
+   DES_load_key_local(scramble_key, &random_key_schedule) ;
+   DES_MAC (0, seed, nl, &rng.key, &random_key_schedule) ;
+
+   /* get whatever resource usage there is */
+#ifdef SOLARIS
+   rs = (struct rusage *)malloc (sizeof(struct tms));
+   (void) times((struct tms *)rs);
+   DES_MAC (0, rs, sizeof(struct tms), &rng.seed, &random_key_schedule) ;
+#else
+   rs = (struct rusage *) malloc(sizeof(struct rusage));
+   getrusage(0,rs);
+   rs->ru_stime.tv_sec += (long) rs ;
+   DES_MAC (0, rs, sizeof(struct rusage), &rng.seed, &random_key_schedule) ;
+#endif
+   free(rs);
+
+   /* get the current wall clock time, mix in process id */
+   gettimeofday(&tv,&tz);
+   rng.seed.longwords[0] = tv.tv_sec + getpid() + (long) &tz ;
+   rng.seed.longwords[1] = tv.tv_usec + clock();
+#ifdef POSIX
+   {
+       struct utsname name;
+       int i, sum = 0;
+
+       (void) uname(&name);
+       for (i = 0; name.nodename[i]; i++)
+        sum = (sum<<1) + name.nodename[i];
+       rng.seed.longwords[1] += sum;
+   }
+#else
+   rng.seed.longwords[1] += gethostid();
+#endif
+
+   DES_load_key_local( &rng.key, &random_key_schedule);
+   DESencrypt_local(&rng.seed, &rng.key, &random_key_schedule);
+   DES_load_key_local( &rng.key, &random_key_schedule);
+   rng.count=0;
+}
+
+
+/*
+ * random_bytes
+ *
+ * Pseudo-random number sequence generator based on NBS algorithm.
+ * Writes nl pseudo-random bytes to buffer n.
+ *
+ */
+void random_bytes (n,nl) 
+char *n;
+int nl;
+{
+for(;nl>0;nl--){
+        if ((rng.count&7)==0)      /* refresh */
+        {
+                struct timeval tv ;
+                struct timezone tz ;
+
+                gettimeofday(&tv, &tz);
+                rng.current.longwords[0]= tv.tv_sec + rng.count ;
+                rng.current.longwords[1]= tv.tv_usec + clock();
+                DESencrypt_local(&rng.current,&rng.current,&random_key_schedule);
+                rng.current.longwords[0] ^= rng.seed.longwords [0] ;
+                rng.current.longwords[1] ^= rng.seed.longwords [1] ;
+                DESencrypt_local(&rng.current,&rng.seed,&random_key_schedule);
+                DESdecrypt_local(&rng.current,&rng.current,&random_key_schedule);
+        }
+        rng.count++ ;
+        *n++ = rng.current.bytes [rng.count&7];
+}
+}
+
+
+static void DES_MAC (iv, inbuf, isize, mac, key_schedule)
+KEYschedule *key_schedule;
+char *iv, *inbuf, *mac;
+int isize;
+{
+        int i;
+       DESblock temp;
+
+        if(iv) memcpy(temp.bytes,iv,8) ;
+        else temp.longwords[0]=temp.longwords[1]=0;
+
+        for (;isize>=8;isize-=8) {
+            for(i=0;i<8;i++) temp.bytes[i] ^= *inbuf++ ;
+            DESencrypt_local(&temp,&temp,key_schedule);
+        }
+
+        if(isize) {
+            for(i=0;i<isize;i++) temp.bytes[i] ^= *inbuf++;
+            DESencrypt_local(&temp,&temp,key_schedule);
+        }
+
+       memcpy(mac, &temp, 8);
+}
+
+\f
+/*
+ *
+ *                     D E S _ X 9 _M A C
+ *
+ *     Compute a DES based message authentication code (MAC) over the input
+ *     buffer.  This uses the definition in ANSI X9.9
+ *
+ * Inputs:
+ *     key     - input DES key
+ *     inbuf   - Pointer to the input buffer
+ *     isize   - Size of the input buffer
+ *     mac     - Pointer to a buffer to receive the MAC
+ *
+ * Outputs:
+ *     mac     - Resultant MAC
+ *
+ * Return Value:
+ *
+ */
+void DES_X9_MAC (key, inbuf, isize, mac)
+DESblock *key;
+char *inbuf , *mac ;
+int isize;
+{
+        KEYschedule key_schedule;
+
+        DES_load_key_local(key,&key_schedule);
+        DES_MAC(0,inbuf,isize,mac,&key_schedule);
+        memset(&key_schedule, 0, sizeof(KEYschedule));
+}
+
+
diff --git a/util/gdss/lib/crypto/algorithm/random.h b/util/gdss/lib/crypto/algorithm/random.h
new file mode 100644 (file)
index 0000000..d6f960d
--- /dev/null
@@ -0,0 +1,62 @@
+/* random.h */
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#ifndef SPHINX_RANDOM
+#define SPHINX_RANDOM
+
+typedef unsigned long  INT32;          /* 32-bit unsigned integer */
+
+typedef union 
+{                                      /* data type for the DES blocks */
+    unsigned char      bytes[8];       /* for access as bytes */
+    INT32              longwords[2];   /* for access as longwords */
+} DESblock;
+
+#define DES_BLOCK_SIZE sizeof(DESblock)
+
+typedef struct {
+        int count ;
+        DESblock seed , key , current;
+        }  RNGState ;
+
+#define RNG_STATE_SIZE sizeof(RNGState) 
+void read_rng_state ();
+void restore_rng_state ();
+void initialize_rng_state ();
+void random_bytes ();
+void DES_X9_MAC();      /* DES_X9_MAC(key,input_buffer, length, hash_result) */
+
+#endif
+
diff --git a/util/gdss/lib/crypto/algorithm/random_BigNum.c b/util/gdss/lib/crypto/algorithm/random_BigNum.c
new file mode 100644 (file)
index 0000000..466f6d7
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include "random.h"
+#include "BigNum.h"
+#include "BigRSA.h"
+#include "bigkeygen.h"
+
+/*
+ * random_BigNum
+ *
+ * Pseudo-random number generator based on NBS algorithm.
+ *
+ * Writes nl pseudo-random BigNumDigits to buffer n.
+ * Called by prime finding routines
+ *
+ */
+random_BigNum (n,nl) 
+BigNum n;
+unsigned nl;
+{
+       for(;nl>0;nl--) random_bytes(n++,sizeof(BigNumDigit)) ;
+}
diff --git a/util/gdss/lib/crypto/bignum/Imakefile b/util/gdss/lib/crypto/bignum/Imakefile
new file mode 100644 (file)
index 0000000..c62d62e
--- /dev/null
@@ -0,0 +1,44 @@
+/* $Header$ */
+
+OBJECT = o/KerN.o o/bnInit.o o/bnMult.o o/bnDivide.o o/bnCmp.o o/bzf.o o/bz.o 
+DEFINES = -DDIGITon32BIT -I./h
+KERNH = h/BigNum.h 
+
+
+all:: $(OBJECT)
+
+clean::
+       $(RM) $(OBJECT)
+
+
+o/KerN.o: c/KerN.c
+       $(CC) $(CFLAGS) -c c/KerN.c
+       mv KerN.o o
+
+# Level N
+o/bnInit.o: c/bn/bnInit.c $(KERNH)
+       $(CC) $(CFLAGS) -c c/bn/bnInit.c
+       mv bnInit.o o
+
+o/bnMult.o: c/bn/bnMult.c $(KERNH)
+       $(CC) $(CFLAGS) -c c/bn/bnMult.c
+       mv bnMult.o o
+
+o/bnDivide.o: c/bn/bnDivide.c $(KERNH)
+       $(CC) $(CFLAGS) -c c/bn/bnDivide.c
+       mv bnDivide.o o
+
+o/bnCmp.o: c/bn/bnCmp.c $(KERNH)
+       $(CC) $(CFLAGS) -c c/bn/bnCmp.c
+       mv bnCmp.o o
+
+# Level Z
+o/bz.o: c/bz.c h/BigZ.h $(KERNH)
+       $(CC) $(CFLAGS) -c c/bz.c
+       mv bz.o o
+
+# Some functions build with BigZ
+o/bzf.o: c/bzf.c h/BigZ.h $(KERNH)
+       $(CC) $(CFLAGS) -c c/bzf.c
+       mv bzf.o o 
+
diff --git a/util/gdss/lib/crypto/bignum/c/KerN.c b/util/gdss/lib/crypto/bignum/c/KerN.c
new file mode 100644 (file)
index 0000000..5c2e9ef
--- /dev/null
@@ -0,0 +1,863 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Fri Mar  2 16:49:23 GMT+1:00 1990 by herve */
+/*      modified_on Mon Feb 19 20:22:20 GMT+1:00 1990 by shand */
+
+
+/* KerN.c: the kernel written in C */
+/*
+ *     Description of types and constants.
+ *
+ * Several conventions are used in the commentary:  
+ *    A "BigNum" is the name for an infinite-precision number.  
+ *    Capital letters (e.g., "N") are used to refer to the value of BigNums.
+ *    The word "digit" refers to a single BigNum digit.
+ *    The notation "Size(N)" refers to the number of digits in N,
+ *      which is typically passed to the subroutine as "nl".
+ *    The notation "Length(N)" refers to the number of digits in N,
+ *       not including any leading zeros.
+ *    The word "Base" is used for the number 2 ** BN_DIGIT_SIZE, where
+ *       BN_DIGIT_SIZE is the number of bits in a single BigNum digit.
+ *    The expression "BBase(N)" is used for Base ** NumDigits(N).
+ *    The term "leading zeros" refers to any zeros before the most 
+ *       significant digit of a number.
+ *
+ *
+ * In the code, we have:
+ *
+ *    "nn" is a pointer to a big number,
+ *    "nl" is the number of digits from nn,
+ *    "d" is a digit.
+ *
+ */
+
+
+/*\f*/
+
+
+#define BNNMACROS_OFF
+#include "BigNum.h"
+
+
+                /*** copyright ***/
+
+static char copyright[]="@(#)KerN.c: copyright Digital Equipment Corporation & INRIA 1988, 1989\n";
+
+
+       /******* non arithmetic access to digits ********/
+
+
+void BnnSetToZero (nn, nl) 
+
+register BigNum        nn; 
+register int           nl;
+
+/*
+ * Sets all the specified digits of the BigNum to 0
+ */
+
+{
+#ifdef NOMEM
+    while (--nl >= 0)
+       *(nn++) = 0;
+#else
+    memset (nn, 0, nl*BN_DIGIT_SIZE/BN_BYTE_SIZE);
+#endif
+}
+               /***************************************/
+
+
+void BnnAssign (mm, nn, nl) 
+
+register BigNum        mm, nn;
+register int   nl;
+
+/* 
+ * Copies N => M
+ */
+
+{
+    if (mm < nn || mm > nn+nl)
+#ifdef NOMEM 
+       while (--nl >= 0)
+           *mm++ = *nn++;
+#else
+        /* be care: bcopy (SRC, DEST, L): SRC-->DEST !!! */
+#ifdef SOLARIS
+        memmove (mm, nn, nl*BN_DIGIT_SIZE/BN_BYTE_SIZE);
+#else
+        bcopy (nn, mm, nl*BN_DIGIT_SIZE/BN_BYTE_SIZE);
+#endif
+#endif
+    else
+    if (mm > nn)
+    {
+       nn += nl;
+       mm += nl;
+       while (--nl >= 0) 
+           *--mm = *--nn;
+    }
+}
+               /***************************************/
+/*\f*/
+
+
+void BnnSetDigit (nn, d) 
+
+BigNum         nn; 
+int    d;
+
+/*
+ * Sets a single digit of N to the passed value
+ */
+
+{
+    *nn = d;
+}
+
+               /***************************************/
+
+
+BigNumDigit BnnGetDigit (nn)
+
+BigNum         nn;
+
+/* 
+ * Returns the single digit pointed by N
+ */
+
+{
+    return (*nn);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigNumLength BnnNumDigits (nn, nl) 
+
+register BigNum nn;
+register int   nl;
+
+/* 
+ * Returns the number of digits of N, not counting leading zeros
+ */
+
+{
+    nn += nl;
+
+    while (nl != 0 && *--nn == 0)
+        nl--;
+
+    return (nl == 0 ? 1 : nl);
+}
+
+               /***************************************/
+
+
+BigNumDigit BnnNumLeadingZeroBitsInDigit (d) 
+
+BigNumDigit d;
+
+/*
+ * Returns the number of leading zero bits in a digit 
+ */
+
+{
+    register BigNumDigit mask = 1 << (BN_DIGIT_SIZE - 1);
+    register int       p = 0;
+
+    
+    if (d == 0) 
+        return (BN_DIGIT_SIZE);
+
+    while ((d & mask) == 0)
+    {
+       p++;
+       mask >>= 1;
+    }
+
+    return (p);
+}
+
+               /***************************************/
+/*\f*/
+
+       /************** Predicates on one digit ***************/
+
+
+Boolean BnnDoesDigitFitInWord (d)
+
+BigNumDigit d;
+
+/*
+ * Returns TRUE iff the digit can be represented in just BN_WORD_SIZE bits
+ */
+{
+    /* The C compiler must evaluate the predicate at compile time */
+    if (BN_DIGIT_SIZE > BN_WORD_SIZE)
+        return (d >= 1 << BN_WORD_SIZE ? FALSE : TRUE);
+    else
+       return (TRUE);
+}
+
+               /***************************************/
+
+
+Boolean BnnIsDigitZero (d)
+
+BigNumDigit d;
+
+/* Returns TRUE iff digit = 0 */
+
+{
+    return (d == 0);
+}
+
+               /***************************************/
+
+
+Boolean BnnIsDigitNormalized (d)
+
+BigNumDigit d;
+
+/*
+ * Returns TRUE iff Base/2 <= digit < Base
+ * i.e., if digit's leading bit is 1
+ */
+
+{
+    return (d & (1 << (BN_DIGIT_SIZE - 1)) ? TRUE : FALSE);
+}
+
+               /***************************************/
+
+
+Boolean BnnIsDigitOdd (d) 
+
+BigNumDigit d;
+
+/*
+ * Returns TRUE iff digit is odd 
+ */
+
+{
+    return (d & 1 ? TRUE : FALSE);
+}
+
+               /***************************************/
+
+
+BigNumCmp BnnCompareDigits (d1, d2)
+
+BigNumDigit d1, d2;
+
+/*
+ * Returns     BN_GREATER      if digit1 > digit2
+ *             BN_EQUAL        if digit1 = digit2
+ *             BN_LESS if digit1 < digit2
+ */
+
+{
+    return (d1 > d2 ? BN_GT : (d1 == d2 ? BN_EQ : BN_LT));
+}
+
+       /***************** Logical operations ********************/
+
+
+void BnnComplement (nn, nl) 
+
+register BigNum nn;
+register int   nl;
+
+/*
+ * Performs the computation BBase(N) - N - 1 => N
+ */
+
+{
+    while (--nl >= 0)
+       *(nn++) ^= -1;
+}
+
+               /***************************************/
+/*\f*/
+
+
+void BnnAndDigits (n, d)
+
+BigNum         n;
+BigNumDigit    d;
+
+/* 
+ * Returns the logical computation n[0] AND d in n[0]
+ */
+
+{
+    *n &= d;
+}
+
+               /***************************************/
+
+
+void BnnOrDigits (n, d)
+
+BigNum         n;
+BigNumDigit    d;
+
+/*
+ * Returns the logical computation n[0] OR d2 in n[0].
+ */
+
+{
+    *n |= d;
+}
+
+               /***************************************/
+
+
+void BnnXorDigits (n, d)
+
+BigNum         n;
+BigNumDigit    d;
+
+/*
+ * Returns the logical computation n[0] XOR d in n[0].
+ */
+
+{
+    *n ^= d;
+}
+
+               /***************************************/
+/*\f*/
+
+       /****************** Shift operations *******************/
+
+
+BigNumDigit BnnShiftLeft (mm, ml, nbits)
+
+register BigNum mm;
+register int   ml;
+        int    nbits;
+
+/* 
+ * Shifts M left by "nbits", filling with 0s.  
+ * Returns the leftmost "nbits" of M in a digit.
+ * Assumes 0 <= nbits < BN_DIGIT_SIZE. 
+ */
+
+{
+    register BigNumDigit res = 0, save;
+            int         rnbits;
+
+
+    if (nbits != 0)
+    {
+       rnbits = BN_DIGIT_SIZE - nbits;
+
+       while (--ml >= 0) 
+       {
+           save = *mm;
+           *mm++ = (save << nbits) | res;
+           res = save >> rnbits;
+       }
+    }
+
+    return (res);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigNumDigit BnnShiftRight (mm, ml, nbits)
+
+register BigNum mm;
+register int   ml;
+        int    nbits;
+
+/*
+ * Shifts M right by "nbits", filling with 0s.  
+ * Returns the rightmost "nbits" of M in a digit.
+ * Assumes 0 <= nbits < BN_DIGIT_SIZE. 
+ */
+
+{
+    register BigNumDigit res = 0, save;
+            int         lnbits;
+
+
+    if (nbits != 0)
+    {
+       mm += ml;
+       lnbits = BN_DIGIT_SIZE - nbits;
+
+       while (--ml >= 0)
+       {
+           save = *(--mm);
+           *mm = (save >> nbits) | res;
+           res = save << lnbits;
+       }
+    }
+
+    return (res);
+}
+
+               /***************************************/
+/*\f*/
+
+
+       /******************* Additions **************************/
+
+
+BigNumCarry BnnAddCarry (nn, nl, carryin)
+
+register BigNum        nn;
+register int           nl;
+        BigNumCarry    carryin;
+
+/*
+ * Performs the sum N + CarryIn => N.  
+ * Returns the CarryOut.
+ */
+
+{
+    if (carryin == 0) 
+        return (0);
+
+    if (nl == 0) 
+        return (1);
+
+    while (--nl >= 0 && !(++(*nn++)))
+        ;
+
+    return (nl >= 0 ? 0 : 1);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigNumCarry BnnAdd (mm, ml, nn, nl, carryin)
+
+register BigNum        mm, nn;
+        int            ml;
+register int           nl;
+        BigNumCarry    carryin; 
+
+/* 
+ * Performs the sum M + N + CarryIn => M.
+ * Returns the CarryOut. 
+ * Assumes Size(M) >= Size(N).
+ */
+
+{
+    register BigNumProduct c = carryin;
+
+
+    ml -= nl;
+    /* test computed at compile time */
+    if (sizeof (BigNumProduct) > sizeof (BigNumDigit))
+    {
+       while (--nl >= 0)
+       {
+           c += *mm + *(nn++);
+           *(mm++) = c;
+           c >>= BN_DIGIT_SIZE;
+       }
+    }
+    else 
+    {
+       register BigNumProduct save;
+
+       while (--nl >= 0)
+       {
+           save = *mm;
+           c += save;
+           if (c < save) 
+           {
+               *(mm++) = *(nn++);
+               c = 1;
+           }
+           else
+           {
+               save = *(nn++);
+               c += save;
+               *(mm++) = c;
+               c = (c < save) ? 1 : 0;
+           }
+       }
+    }
+
+    return (BnnAddCarry (mm, ml, (BigNumCarry) c));
+}
+
+               /***************************************/
+/*\f*/
+
+       /****************** Subtraction *************************/
+
+
+
+BigNumCarry BnnSubtractBorrow (nn, nl, carryin)
+
+register BigNum        nn;
+register int           nl;
+        BigNumCarry    carryin;
+
+/*
+ * Performs the difference N + CarryIn - 1 => N.
+ * Returns the CarryOut.
+ */
+
+{
+    if (carryin == 1)
+        return (1);
+    if (nl == 0)
+        return (0);
+
+#ifdef ibm032
+    while (--nl >= 0 && !(*nn)--)  nn++;
+#else
+    while (--nl >= 0 && !((*nn++)--))
+#endif
+        ;
+
+    return (nl >= 0 ? 1 : 0);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigNumCarry BnnSubtract (mm, ml, nn, nl, carryin)
+
+register BigNum        mm, nn;
+        int            ml;
+register int           nl;
+        BigNumCarry    carryin;
+
+/* 
+ * Performs the difference M - N + CarryIn - 1 => M.
+ * Returns the CarryOut.
+ * Assumes Size(M) >= Size(N).
+ */
+
+{
+    register BigNumProduct     c = carryin;
+    register BigNumDigit       invn;
+
+
+    ml -= nl;
+    /* test computed at compile time */
+    if (sizeof (BigNumProduct) > sizeof (BigNumDigit))
+    {
+       while (--nl >= 0) 
+       {
+           invn = *(nn++) ^ -1;
+           c += *mm + invn;
+           *(mm++) = c;
+           c >>= BN_DIGIT_SIZE;
+       }
+    }
+    else
+    {
+       register BigNumProduct save;
+
+       while (--nl >= 0) 
+       {
+           save = *mm;
+           invn = *(nn++) ^ -1;
+           c += save;
+
+           if (c < save)
+           {
+               *(mm++) = invn;
+               c = 1;
+           }
+           else
+           {
+               c += invn;
+               *(mm++) = c;
+               c = (c < invn) ? 1 : 0;
+           }
+       }
+    }
+
+    return (BnnSubtractBorrow (mm, ml, (BigNumCarry) c)); }
+
+
+               /***************************************/ 
+/*\f */
+
+       /***************** Multiplication ************************/
+
+
+BigNumCarry BnnMultiplyDigit (pp, pl, mm, ml, d)
+
+register BigNum        pp, mm;
+         int           pl, ml; 
+        BigNumDigit    d;
+
+/*
+ * Performs the product:
+ * Q = P + M * d
+ * BB = BBase(P)
+ * Q mod BB => P
+ * Q div BB => CarryOut
+ * Returns the CarryOut. 
+ * Assumes Size(P) >= Size(M) + 1. 
+ */
+
+{ 
+    register BigNumProduct c = 0;
+
+    
+    if (d == 0) 
+        return (0);
+
+    if (d == 1) 
+        return (BnnAdd (pp, pl, mm, ml, (BigNumCarry) 0));
+
+    pl -= ml;
+    /* test computed at compile time */
+    if (sizeof (BigNumProduct) > sizeof (BigNumDigit)) 
+    {
+       while (ml != 0) 
+       {
+           ml--;
+           c += *pp + (d * (*(mm++)));
+           *(pp++) = c;
+           c >>= BN_DIGIT_SIZE;
+       } 
+
+       while (pl != 0) {
+           pl--;
+           c += *pp;
+           *(pp++) = c;
+           c >>= BN_DIGIT_SIZE;
+       }
+
+       return (c);
+    }
+    else
+    {
+/* help for stupid compilers--may actually be counter
+   productive on pipelined machines with decent register allocation!! */
+#define m_digit X0
+#define X3 Lm
+#define X1 Hm
+       register BigNumDigit Lm, Hm, Ld, Hd, X0, X2 /*, X1, X3 */;
+
+       Ld = d & ((1 << (BN_DIGIT_SIZE / 2)) -1);
+       Hd = d >> (BN_DIGIT_SIZE / 2);
+       while (ml != 0) 
+       {
+           ml--;
+           m_digit = *mm++;
+           Lm = m_digit & ((1 << (BN_DIGIT_SIZE / 2)) -1);
+           Hm = m_digit >> (BN_DIGIT_SIZE / 2);
+           X0 = Ld * Lm;
+           X2 = Hd * Lm;
+           X3 = Hd * Hm;
+           X1 = Ld * Hm;
+
+           if ((c += X0) < X0) X3++;
+           if ((X1 += X2) < X2) X3 += (1<<(BN_DIGIT_SIZE / 2));
+           X3 += (X1 >> (BN_DIGIT_SIZE / 2));
+           X1 <<= (BN_DIGIT_SIZE / 2);
+           if ((c += X1) < X1) X3++;
+           if ((*pp += c) < c) X3++;
+           pp++;
+
+           c = X3;
+#undef m_digit
+#undef X1
+#undef X3
+       }
+
+       X0 = *pp;
+       c += X0;
+       *(pp++) = c;
+
+       if (c >= X0)
+           return (0);
+
+       pl--;
+       while (pl != 0 && !(++(*pp++))) 
+           pl--;
+
+       return (pl != 0 ? 0 : 1);
+    }
+}
+
+#ifdef mips
+BigNumCarry BnnMultiply2Digit (pp, pl, mm, ml, d0, d1)
+
+register BigNum        pp, mm;
+register int           pl, ml; 
+        BigNumDigit    d0, d1;
+
+/*
+ * Provided for compatibility with mips assembler implementation.
+ * Performs the product:
+ * Q = P + M * d0_d1
+ * BB = BBase(P)
+ * Q mod BB => P
+ * Q div BB => CarryOut
+ * Returns the CarryOut. 
+ * Assumes Size(P) >= Size(M) + 1. 
+ */
+
+{ 
+    return
+        BnnMultiplyDigit (pp, pl, mm, ml, d0)
+        + BnnMultiplyDigit (pp+1, pl-1, mm, ml, d1);
+}
+#endif /* mips */
+
+               /***************************************/
+/*\f*/
+
+       /********************** Division *************************/
+
+
+               /* xh:xl -= yh:yl */
+#define SUB(xh,xl,yh,yl)       if (yl > xl) {xl -= yl; xh -= yh + 1;}\
+                               else         {xl -= yl; xh -= yh;}
+
+#define LOW(x)                         (x & ((1 << (BN_DIGIT_SIZE / 2)) -1)) 
+#define HIGH(x)                (x >> (BN_DIGIT_SIZE / 2)) 
+#define L2H(x)                         (x << (BN_DIGIT_SIZE / 2)) 
+
+
+BigNumDigit BnnDivideDigit (qq, nn, nl, d)
+
+register BigNum        qq, nn;
+register int           nl;
+        BigNumDigit    d;
+
+/* Performs the quotient: N div d => Q
+ * Returns R = N mod d
+ * Assumes leading digit of N < d, and d > 0.
+ */
+
+{
+    /* test computed at compile time */
+    if (sizeof (BigNumProduct) > sizeof (BigNumDigit))
+    {
+       register BigNumProduct quad;
+
+
+       nn += nl;
+       nl--;
+       qq += nl;
+       quad = *(--nn);
+
+       while (nl != 0)
+       {
+           nl--;
+           quad = (quad << BN_DIGIT_SIZE) | *(--nn);
+           *(--qq) = quad / d;
+           quad = quad % d;
+       } 
+
+       return (quad);
+    }
+    else
+    {
+       int             k;
+       int             orig_nl;
+       BigNumDigit     rh;             /* Two halves of current remainder */
+       BigNumDigit     rl;             /* Correspond to quad above */
+       register BigNumDigit qa;        /* Current appr. to quotient */
+       register BigNumDigit ph, pl;    /* product of c and qa */
+       BigNumDigit     ch, cl, prev_qq;
+       
+
+       /* Normalize divisor */
+       k = BnnNumLeadingZeroBitsInDigit (d);
+       if (k != 0) 
+       {
+           prev_qq = qq[-1];
+           orig_nl = nl;
+           d <<= k;
+           BnnShiftLeft (nn, nl, k);    
+       }
+
+       nn += nl;
+       nl--;
+       qq += nl;
+
+       ch = HIGH (d);
+       cl = LOW (d);
+
+       rl = *(--nn);
+
+       while (nl != 0)
+       {
+           nl--;
+           rh = rl; 
+           rl = *(--nn);
+           qa = rh / ch;       /* appr. quotient */
+
+           /* Compute ph, pl */
+           pl = cl * qa;
+           ph = ch * qa;
+           ph += HIGH (pl);
+           pl = L2H (pl);
+
+           /* While ph:pl > rh:rl, decrement qa, adjust qh:ql */
+           while (ph > rh || ph == rh && pl > rl) 
+           {
+               qa--;
+               SUB (ph, pl, ch, L2H (cl));
+           }
+
+           SUB (rh, rl, ph, pl);
+
+           /* Top half of quotient is correct; save it */
+           *(--qq) = L2H (qa);
+           qa = (L2H (rh) | HIGH (rl)) / ch;
+
+           /* Approx low half of q */
+           /* Compute ph, pl, again */
+           pl = cl * qa;
+           ph = ch * qa;
+           ph += HIGH (pl);
+           pl = LOW (pl) | L2H (LOW (ph));
+           ph = HIGH (ph);
+
+           /* While ph:pl > rh:rl, decrement qa, adjust qh:ql */
+           while (ph > rh || ph == rh && pl > rl)
+           {
+               qa--;
+               SUB (ph, pl, 0, d);
+           }
+
+           /* Subtract ph:pl from rh:rl; we know rh will be 0 */
+           rl -= pl;
+           *qq |= qa;
+       }
+
+       /* Denormalize dividend */
+       if (k != 0) {
+               if((qq > nn) && (qq < &nn[orig_nl])) {
+                       /* Overlap between qq and nn. Care of *qq! */
+                       orig_nl = (qq - nn);
+                       BnnShiftRight (nn, orig_nl, k);
+                       nn[orig_nl - 1] = prev_qq;
+               } else if(qq == nn) {
+                       BnnShiftRight(&nn[orig_nl - 1], 1, k);
+               } else {
+                       BnnShiftRight (nn, orig_nl, k);
+       }       }
+       return (rl >> k);
+    }
+}
+
+               /***************************************/
+
+
diff --git a/util/gdss/lib/crypto/bignum/c/bn/bnCmp.c b/util/gdss/lib/crypto/bignum/c/bn/bnCmp.c
new file mode 100644 (file)
index 0000000..132c6f7
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Fri Aug 10 17:21:47 GMT+2:00 1990 by shand */
+/*      modified_on Fri Apr 28 18:36:28 GMT+2:00 1989 by herve */
+
+
+/* bnCmp.c: a piece of the bignum kernel written in C */
+
+
+               /***************************************/
+
+#define BNNMACROS_OFF
+#include "BigNum.h"
+
+                        /*** copyright ***/
+
+static char copyright[]="@(#)bnCmp.c: copyright Digital Equipment Corporation & INRIA 1988, 1989, 1990\n";
+
+
+Boolean BnnIsZero (nn, nl)
+
+BigNum                 nn;
+BigNumLength   nl;
+
+/* 
+ * Returns TRUE iff N = 0
+ */
+
+{
+    return (BnnNumDigits (nn, nl) == 1 && (nl == 0 || BnnIsDigitZero (*nn)));
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigNumCmp BnnCompare (mm, ml, nn, nl)
+
+        BigNum         mm, nn;
+register BigNumLength  ml, nl;
+
+/*
+ * return
+ *             BN_GT   iff M > N
+ *             BN_EQ   iff N = N
+ *             BN_LT   iff N < N
+*/
+
+{
+    register BigNumCmp result = BN_EQ;
+
+
+    ml = BnnNumDigits (mm, ml);
+    nl = BnnNumDigits (nn, nl);
+
+    if (ml != nl)
+        return (ml > nl ? BN_GT : BN_LT);
+
+    while (result == BN_EQ && ml-- > 0)
+        result = BnnCompareDigits (*(mm+ml), *(nn+ml));
+
+    return (result);
+
+/**** USE memcmp() instead: extern int memcmp ();
+
+    if (ml == nl)
+    {
+        lex = memcmp (mm, nn, nl*BN_DIGIT_SIZE/BN_BYTE_SIZE);
+        return (lex > 0 ? BN_GT: (lex == 0 ? BN_EQ: BN_LT));
+    }
+    else
+        return (ml > nl ? BN_GT : BN_LT);
+******/
+}
diff --git a/util/gdss/lib/crypto/bignum/c/bn/bnDivide.c b/util/gdss/lib/crypto/bignum/c/bn/bnDivide.c
new file mode 100644 (file)
index 0000000..7f65e77
--- /dev/null
@@ -0,0 +1,154 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Fri Mar 30  3:29:17 GMT+2:00 1990 by shand */
+/*      modified_on Fri Apr 28 18:36:28 GMT+2:00 1989 by herve */
+
+
+/* bnDivide.c: a piece of the bignum kernel written in C */
+
+
+               /***************************************/
+
+#define BNNMACROS_OFF
+#include "BigNum.h"
+
+                        /*** copyright ***/
+
+static char copyright[]="@(#)bnDivide.c: copyright Digital Equipment Corporation & INRIA 1988, 1989, 1990\n";
+
+
+static divide (nn, nl, dd, dl)
+
+        BigNum         nn, dd;
+register BigNumLength  nl, dl;
+
+/*
+ * In-place division.
+ *
+ * Input (N has been EXTENDED by 1 PLACE; D is normalized):
+ *     +-----------------------------------------------+----+
+ *     |                       N                         EXT|
+ *     +-----------------------------------------------+----+
+ *
+ *     +-------------------------------+
+ *     |               D              1|
+ *     +-------------------------------+
+ *
+ * Output (in place of N):
+ *     +-------------------------------+---------------+----+
+ *     |               R               |          Q         |
+ *     +-------------------------------+---------------+----+
+ *
+ * Assumes:
+ *    N > D
+ *    Size(N) > Size(D)
+ *    last digit of N < last digit of D
+ *    D is normalized (Base/2 <= last digit of D < Base)
+ */
+
+{
+   register    int             ni;
+               BigNumDigit     DDigit, BaseMinus1, QApp, RApp;
+
+
+   /* Initialize constants */
+   BnnSetDigit (&BaseMinus1, 0);
+   BnnComplement(&BaseMinus1, 1);
+
+   /* Save the most significant digit of D */
+   BnnAssign (&DDigit, dd+dl-1, 1);
+
+   /* Replace D by Base - D */
+   BnnComplement (dd, dl);
+   BnnAddCarry (dd, dl, 1);
+
+   /* For each digit of the divisor, from most significant to least: */
+   nl += 1;
+   ni = nl-dl;
+   while (--ni >= 0) 
+   {
+      /* Compute the approximate quotient */
+      nl--;
+
+      /* If first digits of numerator and denominator are the same, */
+      if (BnnCompareDigits (*(nn+nl), DDigit) == BN_EQ)
+        /* Use "Base - 1" for the approximate quotient */
+        BnnAssign (&QApp, &BaseMinus1, 1);
+      else
+        /* Divide the first 2 digits of N by the first digit of D */
+        RApp = BnnDivideDigit (&QApp, nn+nl-1, 2, DDigit);
+
+      /* Compute the remainder */
+      BnnMultiplyDigit (nn+ni, dl+1, dd, dl, QApp);
+      
+      /* Correct the approximate quotient, in case it was too large */
+      while (BnnCompareDigits (*(nn+nl), QApp) != BN_EQ)
+      {
+        BnnSubtract (nn+ni, dl+1, dd, dl, 1);  /* Subtract D from N */
+        BnnSubtractBorrow (&QApp, 1, 0);       /* Q -= 1 */
+      }
+   }
+
+   /* Restore original D */
+   BnnComplement (dd, dl);
+   BnnAddCarry (dd, dl, 1);
+}
+
+
+               /***************************************/
+/*\f*/
+
+
+void BnnDivide (nn, nl, dd, dl)
+
+        BigNum         nn, dd;
+register BigNumLength  nl, dl;
+
+/*
+ * Performs the quotient:
+ *    N div D => high-order bits of N, starting at N[dl]
+ *    N mod D => low-order dl bits of N
+ *
+ * Assumes 
+ *    Size(N) > Size(D),
+ *    last digit of N < last digit of D (if N > D).
+ */
+
+{
+   BigNumDigit         nshift;
+
+
+   /* Take care of easy cases first */
+   switch (BnnCompare (nn, nl, dd, dl))
+   {
+      case BN_LT:      /* n < d */
+        ;                                      /* N => R */
+        BnnSetToZero (nn+dl, nl-dl);           /* 0 => Q */
+        return;
+      case BN_EQ:      /* n == d */
+        BnnSetToZero (nn, nl);                 /* 0 => R */
+        BnnSetDigit (nn+nl-1, 1);              /* 1 => Q */
+        return;
+   }
+
+   /* here: n > d */
+
+   /* If divisor is just 1 digit, use a special divide */
+   if (dl == 1)
+      *nn = BnnDivideDigit (nn+1, nn, nl, *dd);        /* note: nn+1 = nn+dl */
+   /* Otherwise, divide one digit at a time */
+   else
+   {
+      /* Normalize */
+      nshift = BnnNumLeadingZeroBitsInDigit (*(dd+dl-1));
+      BnnShiftLeft (dd, dl, nshift);
+      BnnShiftLeft (nn, nl, nshift);
+
+      /* Divide */
+      divide (nn, nl-1, dd, dl);
+
+      /* Unnormalize */
+      BnnShiftRight (dd, dl, nshift);
+      BnnShiftRight (nn, dl, nshift); 
+      /* note: unnormalize N <=> unnormalize R (with R < D) */
+   }
+}
diff --git a/util/gdss/lib/crypto/bignum/c/bn/bnInit.c b/util/gdss/lib/crypto/bignum/c/bn/bnInit.c
new file mode 100644 (file)
index 0000000..c67491e
--- /dev/null
@@ -0,0 +1,72 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Fri Mar 30  3:28:56 GMT+2:00 1990 by shand */
+/*      modified_on Wed Feb 14 16:06:50 GMT+1:00 1990 by herve */
+
+
+/* bnInit.c: a piece of the bignum kernel written in C */
+
+
+               /***************************************/
+
+#define BNNMACROS_OFF
+#include "BigNum.h"
+
+static int Initialized = FALSE;
+
+                        /*** copyright ***/
+
+static char copyright[]="@(#)bnInit.c: copyright Digital Equipment Corporation & INRIA 1988, 1989, 1990\n";
+
+
+               /***************************************/
+
+void BnnInit ()
+{
+    if (!Initialized)
+    {
+
+
+        Initialized = TRUE;
+    }
+}
+
+               /***************************************/
+
+void BnnClose ()
+{
+    if (Initialized)
+    {
+
+
+        Initialized = FALSE;
+    }
+}
+
+               /***************************************/
+
+               /* some U*x standard functions do not exist on VMS */
+
+#ifdef VMS
+
+/* Copies LENGTH bytes from string SRC to string DST */
+void bcopy(src, dst, length)
+char   *src, *dst;
+register int   length;
+{
+    for (; length > 0; length--)
+       *dst++ = *src++;
+}
+
+/* Places LENGTH 0 bytes in the string B */
+void bzero(buffer, length)
+char   *buffer;
+register int   length;
+{
+    for (;  length>0; length--)
+       *buffer++ = 0;
+}
+
+#endif
+
+
+               /***************************************/
diff --git a/util/gdss/lib/crypto/bignum/c/bn/bnMult.c b/util/gdss/lib/crypto/bignum/c/bn/bnMult.c
new file mode 100644 (file)
index 0000000..092cdde
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Fri Mar 30  4:13:47 GMT+2:00 1990 by shand */
+/*      modified_on Mon Mar 26 18:09:25 GMT+2:00 1990 by herve */
+
+
+/* bnMult.c: a piece of the bignum kernel written in C */
+
+
+               /***************************************/
+
+#define BNNMACROS_OFF
+#include "BigNum.h"
+
+                        /*** copyright ***/
+
+static char copyright[]="@(#)bnMult.c: copyright Digital Equipment Corporation & INRIA 1988, 1989, 1990\n";
+
+BigNumCarry BnnMultiply (pp, pl, mm, ml, nn, nl)
+
+register BigNum                pp, nn;
+        BigNum         mm;
+register BigNumLength  pl, nl;
+        BigNumLength   ml;
+
+/*
+ * Performs the product:
+ *    Q = P + M * N
+ *    BB = BBase(P)
+ *    Q mod BB => P
+ *    Q div BB => CarryOut
+ *
+ * Returns the CarryOut.  
+ *
+ * Assumes: 
+ *    Size(P) >= Size(M) + Size(N), 
+ *    Size(M) >= Size(N).
+ */
+
+{
+   BigNumCarry c;
+
+   /* Multiply one digit at a time */
+
+   /* the following code give higher performance squaring.
+   ** Unfortunately for small nl, procedure call overheads kills it
+   */
+#ifndef mips
+    /* Squaring code provoke a mips optimizer bug in V1.31 */
+   if (mm == nn && ml == nl && nl > 6)
+   {
+       register n_prev = 0;
+       /* special case of squaring */
+       for (c = 0; nl > 0; )
+       {
+           register BigNumDigit n = *nn;
+           c += BnnMultiplyDigit(pp, pl, nn, 1, n);
+           if (n_prev)
+               c += BnnAdd(pp, pl, nn, 1, 0);
+           nl--, nn++;
+           pp += 2, pl -= 2;
+           c += BnnMultiplyDigit(pp-1, pl+1, nn, nl, n+n+n_prev);
+           n_prev = ((long) n) < 0;
+       }
+   }
+   else
+#endif /* mips */
+       for (c = 0; nl-- > 0; pp++, nn++, pl--)
+          c += BnnMultiplyDigit (pp, pl, mm, ml, *nn);
+
+   return c;
+}
diff --git a/util/gdss/lib/crypto/bignum/c/bz.c b/util/gdss/lib/crypto/bignum/c/bz.c
new file mode 100644 (file)
index 0000000..7974fac
--- /dev/null
@@ -0,0 +1,749 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Tue Mar 27 15:35:41 GMT+2:00 1990 by herve */
+/*      modified_on Thu Mar 22 20:45:38 GMT+1:00 1990 by shand */
+
+
+/* bz.c: provides an implementation of "unlimited-precision" 
+ * arithmetic for signed integers. 
+ *
+ * Several conventions are used in the commentary:  
+ *    A "BigZ" is the name for an arbitrary-precision signed integer.  
+ *    Capital letters (e.g., "Z") are used to refer to the value of BigZs.
+ */
+
+
+#include "BigZ.h"
+
+
+               /***************************************/
+/*
+#include <stdio.h>
+#include <macros.h>
+#include <math.h>
+#include <malloc.h>
+#include <values.h>
+*/
+
+#define NULL                    0
+#define max(a,b)               (a<b ? b : a)
+#define abs(x)                 (x>=0 ? x : -(x))
+#define M_LN2                  0.69314718055994530942
+#define M_LN10                 2.30258509299404568402
+#define BITSPERBYTE            8
+#define BITS(type)             (BITSPERBYTE * (int)sizeof(type))
+#define HIBITI                 (1 << BITS(int) - 1)
+#define MAXINT                 (~HIBITI)
+
+               /***************************************/
+
+#define BzToBn(z)               ((z)->Digits)
+#define CTOI(c)                        (c >= '0' && c <= '9' ? c - '0' :\
+                                 c >= 'a' && c <= 'f' ? c - 'a' + 10:\
+                                 c >= 'A' && c <= 'F' ? c - 'A' + 10:\
+                                 0)
+
+extern char *malloc();
+
+                        /*** copyright ***/
+
+static char copyright[]="@(#)bz.c: copyright Digital Equipment Corporation & INRIA 1988, 1989\n";
+
+
+               /***************************************/
+
+static int Initialized = FALSE;
+
+/* constants used by BzToString() and BzFromString() */
+static double BzLog [] = 
+{
+    0, 
+    0,                         /* log (1) */
+    M_LN2,             /* log (2) */
+    1.098612,          /* log (3) */
+    1.386294,          /* log (4) */
+    1.609438,          /* log (5) */
+    1.791759,          /* log (6) */
+    1.945910,          /* log (7) */
+    2.079442,          /* log (8) */
+    2.197225,          /* log (9) */
+    M_LN10,            /* log (10) */
+    2.397895,          /* log (11) */
+    2.484907,          /* log (12) */
+    2.564949,          /* log (13) */
+    2.639057,          /* log (14) */
+    2.708050,          /* log (15) */
+    2.772588,          /* log (16) */
+};    
+
+/*\f*/
+    
+
+void BzInit ()
+{
+    if (!Initialized)
+    {
+        BnnInit ();
+        Initialized = TRUE;
+    }
+}
+
+               /***************************************/
+
+
+BigZ BzCreate (Size)
+
+int Size;
+
+/* 
+ * Allocates a BigZ of the desired size.
+ * Sets it to 0.
+ */
+
+{
+    BigZ z;
+
+
+    if ((z = (BigZ) (malloc (sizeof (struct BigZHeader) + Size * sizeof (BigNumDigit)))) != NULL)
+    {
+       /* reset digits */
+       BnnSetToZero (BzToBn (z), Size);
+
+       /* init header */
+       BzSetSize (z, Size);
+       BzSetSign (z, BZ_ZERO);
+    }
+
+    return (z);
+}
+
+
+
+void BzFree (z)        
+
+BigZ z;
+
+/*
+ * Frees an existing BigZ.
+ */
+
+{
+    free (z);
+}
+
+               /***************************************/
+               /***************************************/
+
+
+void BzFreeString (s)  
+
+char *s;
+
+/*
+ * Frees an existing BigZ allocated string.
+ */
+
+{
+    free (s);
+}
+
+               /***************************************/
+/*\f*/
+
+unsigned BzNumDigits (z)
+
+BigZ z;
+
+/* 
+ * Returns the number of digits used by z.
+ */
+
+{
+    return (BnnNumDigits (BzToBn (z), BzGetSize (z)));
+}
+
+
+               /***************************************/
+
+
+BigZ BzCopy (z)        
+
+BigZ z;
+
+/* 
+ * Creates a copy of the passed BigZ.
+ */
+
+{
+    BigZ y;
+    int zl;
+
+   
+    zl = BzNumDigits (z);
+    if ((y = BzCreate (zl)) != NULL)
+    {
+       /* copy the digits */
+        BnnAssign (BzToBn (y), BzToBn (z), zl);
+
+       /* copy the header WITHOUT the size !! */
+       BzSetSign (y, BzGetSign (z));
+    }
+
+    return (y);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzNegate (z)      
+
+BigZ z;
+
+/* 
+ * Negates the passed BigZ.
+ */
+
+{
+    BigZ y;
+
+    y = BzCopy (z);
+    BzSetSign (y, BzGetOppositeSign (z));
+
+    return (y);
+}
+
+               /***************************************/
+
+
+BigZ BzAbs (z) 
+
+BigZ z;
+
+/* 
+ * Takes the absolute value of the passed BigZ.
+ */
+
+{
+    BigZ y;
+
+    y = BzCopy (z);
+    BzSetSign (y, abs (BzGetSign (z)));
+
+    return (y);
+}
+
+               /***************************************/
+
+
+BzCmp BzCompare (y, z)
+
+BigZ y, z;
+
+/* 
+ * Returns BZ_GT       if Y > Z,
+ *         BZ_LT       if Y < Z, 
+ *         BZ_EQ       otherwise.
+ */
+
+{
+    return (BzGetSign (y) > BzGetSign (z) ? BZ_GT :
+           BzGetSign (y) < BzGetSign (z) ? BZ_LT :
+           BzGetSign (y) > 0 ? BnnCompare (BzToBn (y), BzGetSize (y),
+                                           BzToBn (z), BzGetSize (z)) :
+           BzGetSign (y) < 0 ? BnnCompare (BzToBn (z), BzGetSize (z),
+                                           BzToBn (y), BzGetSize (y)) :
+           BZ_EQ);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzAdd (y, z)
+
+BigZ y, z;
+
+/* 
+ * Returns Y + Z.
+ */
+
+{
+    BigZ n;
+    int yl;
+    int zl;
+
+
+    yl = BzNumDigits (y);
+    zl = BzNumDigits (z);
+
+    if (BzGetSign (y) == BzGetSign (z))
+    {
+       /* Add magnitudes if signs are the same */
+        switch (BnnCompare (BzToBn (y), yl, BzToBn (z), zl))
+       {
+           case BZ_EQ:
+           case BZ_GT: /* |Y| >= |Z| */
+
+               if ((n = BzCreate (yl+1)) != NULL)
+               {
+                   BnnAssign (BzToBn (n), BzToBn (y), yl);
+                   BnnAdd (BzToBn (n), yl+1, BzToBn (z), zl, 0);
+                   BzSetSign (n, BzGetSign (y));
+               }
+           break;
+
+           default:            /* BZ_LT: |Y| < |Z| */
+
+               if ((n = BzCreate (zl+1)) != NULL)
+               {
+                   BnnAssign (BzToBn (n), BzToBn (z), zl);
+                   BnnAdd (BzToBn (n), zl+1, BzToBn (y), yl, 0);
+                   BzSetSign (n, BzGetSign (z));
+               }
+           break;
+       }
+    }
+/*\f*/
+
+
+    else
+    {
+       /* Subtract magnitudes if signs are different */
+       switch (BnnCompare (BzToBn (y), yl, BzToBn (z), zl))
+       {
+           case BZ_EQ: /* Y = -Z */
+
+               n = BzCreate (1);
+           break;
+
+           case BZ_GT: /* |Y| > |Z| */
+
+               if ((n = BzCreate (yl)) != NULL)
+               {
+                   BnnAssign (BzToBn (n), BzToBn (y), yl);
+                   BnnSubtract (BzToBn (n), yl, BzToBn (z), zl, 1);
+                   BzSetSign (n, BzGetSign (y));
+               }
+           break;
+
+           default:            /* BZ_LT: |Y| < |Z| */
+
+               if ((n = BzCreate (zl)) != NULL)
+               {
+                   BnnAssign (BzToBn (n), BzToBn (z), zl);
+                   BnnSubtract (BzToBn (n), zl, BzToBn (y), yl, 1);
+                   BzSetSign (n, BzGetSign (z));
+               }
+           break;
+       }
+    }
+
+    return (n);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzSubtract (y, z) 
+
+BigZ y, z;
+
+/* 
+ * Returns Y - Z.
+ */
+
+{
+    BigZ diff;
+
+
+    BzSetSign (z, BzGetOppositeSign (z));
+    diff = BzAdd (y, z);
+    BzSetSign (z, BzGetOppositeSign (z));
+
+    return diff;
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzMultiply (y, z) 
+
+BigZ y, z;
+
+/* 
+ * Returns Y * Z.
+ */
+
+{
+    BigZ n;
+    int yl, zl;
+
+
+    yl = BzNumDigits (y);
+    zl = BzNumDigits (z);
+
+    if ((n = BzCreate (yl+zl)) != NULL)
+    {
+       BnnMultiply (BzToBn (n), yl+zl, BzToBn (y), yl, BzToBn (z), zl);
+       BzSetSign (n, BzGetSign (y) * BzGetSign (z));
+    }
+
+    return (n);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzDivide (y, z, r)        
+
+BigZ y, z, *r;
+
+/* 
+ * Sets Y mod Z => R, 
+ * Returns Y div Z => Q
+ * 
+ * such that Y = ZQ + R 
+ * and 0 <= R < |Z|.
+ */
+
+{
+    BigZ       q;
+    int        yl, zl, ql, rl;
+    Boolean     rnotnul;
+
+
+    if (BzGetSign (z) == BZ_ZERO)
+        return (NULL);
+
+    yl = BzNumDigits (y);
+    zl = BzNumDigits (z);
+
+    /* max +1 since BnnAddCarry can overflow */
+    ql = max (yl-zl+1, 1) +1;
+    rl = max (zl,yl) + 1;
+
+    /* Set up quotient, remainder */
+    q = BzCreate (ql); 
+    *r = BzCreate (rl);
+    
+    if (!*r || !q) 
+        return (NULL);
+
+    BnnAssign (BzToBn (*r), BzToBn (y), yl);
+    
+    /* Do the division */
+    BnnDivide (BzToBn (*r), rl, BzToBn (z), zl);
+    BnnAssign (BzToBn (q), BzToBn (*r) + zl, rl-zl);
+    BnnSetToZero (BzToBn (*r) + zl, rl-zl);
+    rl = zl;
+
+    /* Correct the signs, adjusting the quotient and remainder */
+    rnotnul = !BnnIsZero (BzToBn (*r), rl);
+    if (BzGetSign (y) == BZ_MINUS && rnotnul)
+    {
+        /* Y < 0, R > 0: (Q+1)=>Q,  Z-R=>R */
+        BnnAddCarry (BzToBn (q), ql, (BigNumCarry) 1);
+
+        BzSetSign (q, BzGetOppositeSign (z));
+        BnnComplement (BzToBn (*r), rl);
+        BnnAdd (BzToBn (*r), rl, BzToBn (z), zl, (BigNumCarry) 1);
+    }
+    else
+        BzSetSign (q, BzGetSign (y) * BzGetSign (z));
+
+    /* Correct the sign of the remainder */
+    if (rnotnul)
+        BzSetSign (*r, BZ_PLUS);
+
+    return (q);
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzDiv (y, z)              
+
+BigZ y, z;
+
+/* 
+ * Returns Y div Z.
+ */
+
+{
+    BigZ q, r;
+
+
+    q = BzDivide (y, z, &r);
+    BzFree (r);
+
+    return (q);
+}
+
+               /***************************************/
+
+
+BigZ BzMod (y, z)              
+
+BigZ y, z;
+
+/* 
+ * Returns Y mod Z.
+ */
+
+{
+    BigZ r;
+
+
+    BzFree (BzDivide (y, z, &r));
+
+    return (r);
+}
+
+               /***************************************/
+/*\f*/
+
+
+char * BzToString (z, base)
+
+BigZ           z;
+BigNumDigit    base;
+
+/*
+ * Returns a pointer to a string that represents Z in the specified base.
+ * Assumes 2 <= base <= 16.
+ */
+
+{
+    char *     string;
+    BigZ       y, q, t;
+    BigNumDigit r;
+
+    static char Digit[] = "0123456789ABCDEF";
+    char *     s;
+    int        sd, zl, sl;
+
+
+    if (base < 2 || base > 16)
+        return (NULL);
+
+    /* Allocate BigNums and set up string */
+    zl = BzNumDigits (z) + 1;
+    sl = BzLog[2] * BN_DIGIT_SIZE * zl / BzLog[base] + 3;
+
+    y = BzCreate (zl);
+    q = BzCreate (zl);
+
+    string = malloc (sl * sizeof (char));
+
+    if (!y || !q || !string)
+        return (NULL);
+
+    BnnAssign (BzToBn (y), BzToBn (z), zl-1);
+    s = string + sl;
+
+    /* Divide Z by base repeatedly; successive digits given by remainders */
+    *--s = '\0';
+    if (BzGetSign (z) == BZ_ZERO) 
+        *--s = '0';
+    else
+    do
+    {
+       r = BnnDivideDigit (BzToBn (q), BzToBn (y), zl, base);
+       *--s = Digit[r];
+
+       /* exchange y and q (to avoid BzMove (y, q) */
+       t = q,  q = y,  y = t;
+    } while (!BnnIsZero (BzToBn (y), zl));
+    
+    /* Set sign if negative */
+    if (BzGetSign (z) < 0) 
+        *--s = '-';
+
+    /* and move string into position */
+    if ((sd = s-string) > 0) 
+        while (s < string + sl)
+       {
+           *(s-sd) = *s;
+           s++;
+       }
+
+    /* Free temporary BigNums and return the string */
+    BzFree(y);
+    BzFree(q);
+
+    return string;
+}
+
+               /***************************************/
+/*\f*/
+
+
+BigZ BzFromString (s, base)
+
+char           *s;
+BigNumDigit    base;
+
+/*
+ * Creates a BigZ whose value is represented by "string" in the
+ * specified base.  The "string" may contain leading spaces,
+ * followed by an optional sign, followed by a series of digits.
+ * Assumes 2 <= base <= 16.
+ * When called from C, only the first 2 arguments are passed.
+ */
+
+{
+    BigZ       z, p, t;
+    BzSign     sign;
+    int        zl;
+
+    
+    /* Throw away any initial space */
+    while (*s == ' ') 
+        s++;
+    
+    /* Allocate BigNums */
+    zl = strlen (s) * BzLog[base] / (BzLog[2] * BN_DIGIT_SIZE) + 1;
+
+    z = BzCreate (zl);
+    p = BzCreate (zl);
+
+    if (!z || !p) 
+        return (NULL);
+    
+    /* Set up sign, base, initialize result */
+    sign = (*s == '-' ? (s++, BZ_MINUS) : *s == '+' ? (s++, BZ_PLUS) : BZ_PLUS);
+    
+    /* Multiply in the digits of the string, one at a time */
+    for (;  *s != '\0';  s++)
+    {
+       BnnSetToZero (BzToBn (p), zl);
+       BnnSetDigit (BzToBn (p), CTOI (*s));
+       BnnMultiplyDigit (BzToBn (p), zl, BzToBn (z), zl, base);  
+
+       /* exchange z and p (to avoid BzMove (z, p) */
+       t = p,  p = z,  z = t;
+    }
+    
+    /* Set sign of result */
+    BzSetSign (z, BnnIsZero (BzToBn (z), zl) ? BZ_ZERO : sign);
+    
+    /* Free temporary BigNums */
+    BzFree (p);
+
+    return (z);
+}
+
+               /***************************************/
+
+BigZ BzFromInteger (i)
+
+int i;
+
+{
+    BigZ z;
+
+
+    z = BzCreate (1);
+
+    z->Digits[0] = abs (i);
+
+    if (i > 0) 
+        BzSetSign (z, BZ_PLUS);
+    else
+    if (i < 0) 
+        BzSetSign (z, BZ_MINUS);
+    else
+        BzSetSign (z, BZ_ZERO);
+
+    return z;
+}
+
+               /***************************************/
+
+
+int BzToInteger (z)
+
+BigZ z;
+
+{
+    if (BzNumDigits (z) > 1)
+        return (MAXINT);
+
+    if (BzGetSign (z) == BZ_MINUS)
+        return (- z->Digits[0]);
+    else
+        return (z->Digits[0]);
+}
+
+               /***************************************/
+
+
+BigZ BzFromBigNum (n, nl)
+
+BigNum          n;
+BigNumLength    nl;
+
+{
+    BigZ z;
+    int  i;
+
+
+    z = BzCreate (nl);
+
+    /* set the sign of z such that the pointer n is unchanged yet */
+    if (BnnIsZero (n, nl))
+        BzSetSign (z, BZ_ZERO);
+    else
+        BzSetSign (z, BZ_PLUS);
+
+    for (i = 0; i < nl; i++, n++)
+        z->Digits[i] = *n;
+
+    return z;
+}
+
+               /***************************************/
+
+BigNum BzToBigNum (z, nl)
+
+BigZ         z;
+BigNumLength *nl;
+
+{
+    BigNum n, m;
+    int i;
+
+
+    if (BzGetSign (z) == BZ_MINUS)
+        return NULL;
+
+    *nl = BzNumDigits (z);
+
+    if ((n = (BigNum) (malloc (((*nl+1) * sizeof (BigNumDigit))))) != NULL)
+    {
+        *n = *nl; /* set size */
+
+        for (i = 0, m = ++n; i < *nl; i++, m++)
+            *m = z->Digits[i];
+    }
+
+    return n;
+}
+
+               /***************************************/
+
+
+void BzClose ()
+{
+    if (Initialized)
+    {
+        BnnClose ();
+        Initialized = FALSE;
+    }
+}
+
+               /***************************************/
diff --git a/util/gdss/lib/crypto/bignum/c/bzf.c b/util/gdss/lib/crypto/bignum/c/bzf.c
new file mode 100644 (file)
index 0000000..8b6bdc0
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Mon Jan 23 16:05:27 GMT+1:00 1989 by herve */
+
+/*
+ * bzf.c: Miscellaneous functions built on top of BigZ.
+ *
+ */
+
+
+#include "BigZ.h"
+
+               /***************************************/
+
+#define BzToBn(z)               ((z)->Digits)
+
+               /***************************************/
+
+
+BigZ BzFactorial (z)
+
+BigZ z;
+
+/*
+ * Returns Z!
+ * Assumes Z < Base.
+ */
+
+{
+    BigZ       f;
+    BigNumDigit zval;
+    int        fl = 1;
+
+
+    zval = BnnGetDigit (BzToBn (z));
+    f = BzCreate (zval+1);
+    BnnSetDigit (BzToBn (f), 1);
+    BzSetSign (f, BzGetSign (z));
+
+    while (zval-- > 1) 
+    {
+       BnnMultiplyDigit (BzToBn (f), fl+1, BzToBn (f), fl, zval);
+       fl = BnnNumDigits (BzToBn (f), fl+1);
+    }
+    
+    return (f);
+}
+
diff --git a/util/gdss/lib/crypto/bignum/c/bztest.c b/util/gdss/lib/crypto/bignum/c/bztest.c
new file mode 100644 (file)
index 0000000..bebb7ab
--- /dev/null
@@ -0,0 +1,137 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Tue Mar 27 15:29:04 GMT+2:00 1990 by herve */
+/*      modified_on Tue Feb 13 17:55:06 GMT+1:00 1990 by shand */
+
+#include <stdio.h>
+#include "BigZ.h"
+
+#define S(A,B)         strcmp(A,B)
+#define NEWLINE                fprintf(stderr,"\n")
+#define P(A)           fprintf(stderr,"%d...",A)
+#define E(A,B,C)       fprintf(stderr,"\nError in test #%d:\nComputed: %s\nCorrect:  %s\n",A,C,B)
+#define T(A,B,C)       S(B,C)?E(A,B,C):P(A)
+#define To(A)          BzToString(A,10)
+#define From(A)                BzFromString(A,10)
+#define Abs(A)         BzAbs(A)
+#define Neg(A)         BzNegate(A)
+#define Add(A,B)       BzAdd(A,B)
+#define Sub(A,B)       BzSubtract(A,B)
+#define Mul(A,B)       BzMultiply(A,B)
+#define Div(A,B)       BzDiv(A,B)
+#define Mod(A,B)       BzMod(A,B)
+#define Fac(A)         BzFactorial(A)
+#define FromI(I)        BzFromInteger(I)
+
+#define one             FromI(1)
+#define two             FromI(2)
+#define minusone        FromI(-1)
+#define two31m1         FromI(0x7FFFFFFF)
+
+main()
+{
+   BigZ a,b;
+
+
+   T(1,"12", To(From("12"))) ;
+   T(2,"12345678910", To(From("12345678910"))) ;
+   T(3,"123", To(From("00000123"))) ;
+   T(4,"-123", To(From("-123"))) ;
+   T(5,"-32768", To(From("-32768"))) ;
+   T(6,"-32768", To(Neg(From("32768")))) ;
+   T(7,"-32768", To(Add(From("-16384"),From("-16384")))) ;
+   T(8,"-32768", To(Add(From("-16383"),From("-16385")))) ;
+   T(9,"-32768", To(Mul(From("2"),From("-16384")))) ;
+   T(10,"-16384", To(Div(From("-32768"),From("2")))) ;
+   NEWLINE;
+   T(11,"100000", To(Add(From("1"),From("99999")))) ;
+   T(12,"12343994",To(Add(From("-1684"),From("12345678"))));
+   T(13,"-12329294",To(Sub(From("16384"),From("12345678"))));
+   T(14,"135801",To(Add(From("12345"),From("123456"))));
+   T(15,"123456135801",To(Add(From("12345"),From("123456123456"))));
+   T(16,"135801",To(Add(From("123456"),From("12345"))));
+   T(17,"123456135801",To(Add(From("123456123456"),From("12345"))));
+   T(18,"135801",To(Sub(From("12345"),From("-123456"))));
+   T(19,"123456135801",To(Sub(From("12345"),From("-123456123456"))));
+   T(20,"135801",To(Sub(From("123456"),From("-12345"))));
+   NEWLINE;
+   T(21,"123456135801",To(Sub(From("123456123456"),From("-12345"))));
+   T(22,"-111111",To(Sub(From("12345"),From("123456"))));
+   T(23,"111111",To(Sub(From("123456"),From("12345"))));
+   T(24,"-123456111111",To(Sub(From("12345"),From("123456123456"))));
+   T(25,"123456111111",To(Sub(From("123456123456"),From("12345"))));
+   T(26,"-111111",To(Add(From("12345"),From("-123456"))));
+   T(27,"111111",To(Add(From("123456"),From("-12345"))));
+   T(28,"-123456111111",To(Add(From("12345"),From("-123456123456"))));
+   T(29,"123456111111",To(Add(From("123456123456"),From("-12345"))));
+   T(30,"2", To(Div(From("264195"),From("97200")))) ;
+   NEWLINE;
+   T(31,"27405", To(Mod(From("97200"),From("69795")))) ;
+   T(32,"4294967295", To(Div(From("22685491128062564230891640495451214097"),From("5281877500950955845296219748")))) ;
+   T(33,"99997",To(Add(From("-3"),From("100000"))));
+   T(34,"-100003",To(Add(From("-3"),From("-100000"))));
+   T(35,"999999",To(Sub(From("1000000"),From("1"))));
+   T(36,"999999999",To(Mul(From("12345679"),From("81"))));
+   a = From("1234567");
+   b = From("123456");
+   T(37,"1234567",To(Add(Mul(Div(a,b),b),Mod(a,b))));
+   T(38,"-1234567",To(Add(Mul(Div(Neg(a),Neg(b)),Neg(b)),Mod(Neg(a),Neg(b)))));
+   T(39,"1234567",To(Add(Mul(Div(a,Neg(b)),Neg(b)),Mod(a,Neg(b)))));
+   T(40,"10000000000000000000000",To(Mul(From("-100000000000"),From("-100000000000"))));
+   NEWLINE;
+   T(41,"-10000000000000000000000",To(Mul(From("-100000000000"),From("100000000000"))));
+   T(42,"-10000000000000000000000",To(Mul(From("100000000000"),From("-100000000000"))));
+   T(43,"10000000000000000000000",To(Mul(From("100000000000"),From("100000000000"))));
+   a = Sub(From("10000000000000"),From("10000000000000"));
+   T(44,"0",To(Mod(a,From("1000000000000"))));
+   T(45,"0",To(Div(a,From("1000000000000"))));
+   T(46,"0",To(Mod(Neg(a),From("10000000000000"))));
+   T(47,"0",To(Div(Neg(a),From("10000000000000"))));
+   T(48,"2",To(Div(From("3000"),Sub(From("1234567891234"),From("1234567890000")))));
+   T(49,"532",To(Mod(From("3000"),Sub(From("1234567891234"),From("1234567890000")))));
+   T(50,"9",To(Mod(From("-1234567890"),From("1234567899"))));
+   NEWLINE;
+   T(51,"2",To(Mod(Sub(From("12345678900000"),From("12345678926887")),From("3"))));
+   T(52,"40830949904677684825316369628906250000000000000",To(Mul(From("48270948888581289062500000000"),From("845870049062500000"))));
+   T(53,"22666179639240748063923391983020279316955515",To(Mul(From("6956883693"),From("3258093801689886619170103176686855"))));
+   T(54,"1405006117752879898543142606244511569936384000000000",To(Fac(From("42"))));
+   T(55,"0",To(Mod(Fac(From("13")),Fac(From("9")))));
+   T(56,"0",To(Mod(Fac(From("34")),Fac(From("13")))));
+   T(57,"0",To(Mod(Fac(From("57")),Fac(From("21")))));
+   T(58,"0",To(Mod(Fac(From("40")),Fac(From("39")))));
+   T(59,"59",To(Div(Fac(From("59")),Fac(From("58")))));
+   T(60,"2",To(Div(From("5"),From("2"))));
+   NEWLINE;
+   T(61,"1",To(Mod(From("5"),From("2"))));
+   T(62,"-3",To(Div(From("-5"),From("2"))));
+   T(63,"1",To(Mod(From("-5"),From("2"))));
+   T(64,"3",To(Div(From("-5"),From("-2"))));
+   T(65,"1",To(Mod(From("-5"),From("-2"))));
+   T(66,"-2",To(Div(From("5"),From("-2"))));
+   T(67,"1",To(Mod(From("5"),From("-2"))));
+   T(68,"3",To(Div(From("6"),From("2"))));
+   T(69,"0",To(Mod(From("6"),From("2"))));
+   T(70,"-3",To(Div(From("-6"),From("2"))));
+   NEWLINE;
+   T(71,"0",To(Mod(From("-6"),From("2"))));
+   T(72,"3",To(Div(From("-6"),From("-2"))));
+   T(73,"0",To(Mod(From("-6"),From("-2"))));
+   T(74,"-3",To(Div(From("6"),From("-2"))));
+   T(75,"0",To(Mod(From("6"),From("-2"))));
+   T(76,"0",To(Abs(From("0"))));
+   T(77,"1234567890",To(Abs(From("1234567890"))));
+   T(78,"1234567890",To(Abs(From("-1234567890"))));
+   T(79,"1",BzCompare(From("-1234567890"),From("12345"))<0?"1":"0");
+   T(80,"1",BzGetSign(From("-1234567890"))<0?"1":"0");
+   NEWLINE; 
+   T(81,"0", To(Add(From("-1"),Mul(From("-1"),From("-1")))));
+   T(82,"-1",To(Add(From("-1"),Mul(From("0"), From("-1")))));
+   T(83,"-3",To(Add(From("-1"),Mul(From("-2"),From("1" )))));
+   T(84,"1", To(Add(From("-1"),Mul(From("-2"),From("-1")))));
+   T(85,"-1",To(Add(From("1"), Mul(From("-2"),From("1" )))));
+   T(86,"18446744065119617025",To(Mul(From("4294967295"),From("4294967295"))));
+        /* (-2^64 + 2^32 - 1) / 2^32 */
+   T(87,"-4294967296",To(Div(
+        Sub(Mul(Mul(Add(Mul(two31m1,two),one),Mul(Add(two31m1,one), two)),minusone),one),
+        Mul(Add (two31m1,one),two))));
+   NEWLINE;
+}
diff --git a/util/gdss/lib/crypto/bignum/c/testKerN.c b/util/gdss/lib/crypto/bignum/c/testKerN.c
new file mode 100644 (file)
index 0000000..f561fda
--- /dev/null
@@ -0,0 +1,1002 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* testKerN.c: tests des primitives de KerN                           */
+/* Last modified_on Mon Mar 26 20:37:00 GMT+2:00 1990 by shand        */
+/*      modified_on Wed Feb 14 16:14:04 GMT+1:00 1990 by herve        */
+/*      modified_on 17-OCT-1989 20:35:55.91 by Jim Lawton             */
+
+/* You can comment the line below if you want to test the C macro Package
+   instead of C or Assembly functions. */
+
+#define BNNMACROS_OFF 1
+
+
+#include "BigNum.h"
+#include "BntoBnn.h"
+
+
+                       /* structure d'un test */
+
+struct testenv {
+       char    *name;          /* Le nom de la fonction teste'e.        */
+       int     flag;           /* Pour savoir si l'on continue le Test. */
+       char    hist[2048];     /* L'expression qui provoque l'erreur.   */
+       char    *depend;        /* De quoi depend le Test.               */
+};
+
+
+                       /* Les nombres pre'de'finies. */
+
+static BigNum          NumbVect[5][2];
+static BigNum          NumbProto, Ntmp2, NtmpBig;
+
+#define RN(n)          NumbVect[n][0]
+#define SN(n)          NumbVect[n][1]
+
+                       /* Taille des nombres utilise's. */
+                       /* de la forme 4(n + 1) */
+#define TESTLENGTH     16
+#define DTL            TESTLENGTH/2
+#define QTL            TESTLENGTH/4
+
+/* Nombre de test. */
+int TestCount;
+
+ResetTest(n) int n; {
+       /* Remet le nieme nombre a` la valeur prototype. */
+       BnAssign(RN(n), 0, NumbProto, 0, TESTLENGTH);
+       BnAssign(SN(n), 0, NumbProto, 0, TESTLENGTH);
+}
+
+Check(n) int n; {
+       int i;
+       /* Verifie que les n nombres calcules correspondent aux simule's. */
+       for(i = 0; i < n; i++)
+               if(CheckSubRange(i, 0, TESTLENGTH)) return(1);
+       return(FALSE);
+}
+
+CheckSubRange(x, nd, nl) int x, nd, nl; {
+       /* Verifie l'e'galite' des sous-nombres
+           (RN(x), nd, nl) et (SN(x), nd, nl) */
+       while(nl) {
+               nl--;
+               if(BnCompareDigits(RN(x), nd, SN(x), nd)) return(nd + 1);
+               nd++;
+       }
+       return(FALSE);
+}
+
+ShowDiff0(e, r1, r2) struct testenv *e; int r1,r2; {
+       ErrorPrint(e);
+       if(r1 != r2)
+               printf("---- Result is %d and should be %d----\n", r1, r2);
+       return(e->flag);
+}
+
+ShowDiff1(e, r1, r2, n, nd, nl)
+               struct testenv *e; char *n; int r1, r2, nd, nl; {
+       ErrorPrint(e);
+       if(r1 != r2)
+               printf("---- Result is %d and should be %d----\n", r1, r2);
+       ShowOutRange(0, n, nd, nl);
+       ShowSubNumber(0, n, nd, nl);
+       return(e->flag);
+}
+
+ShowDiff2(e, r1, r2, n, nd, nl, m, md, ml)
+               struct testenv *e; char *n, *m; int r1, r2, nd, nl, md, ml; {
+       ErrorPrint(e);
+       if(r1 != r2)
+               printf("---- Result is %d and should be %d----\n", r1, r2);
+       ShowOutRange(0, n, nd, nl);
+       ShowOutRange(1, m, md, ml);
+       ShowSubNumber(0, n, nd, nl);
+       ShowSubNumber(1, m, md, ml);
+       return(e->flag);
+}
+
+ShowDiff3(e, r1, r2, n, nd, nl, m, md, ml, o, od, ol)
+               struct testenv *e; char *n, *m, *o;
+               int r1, r2, nd, nl, md, ml, od, ol; {
+       ErrorPrint(e);
+       if(r1 != r2)
+               printf("---- Result is %d and should be %d----\n", r1, r2);
+       ShowOutRange(0, n, nd, nl);
+       ShowOutRange(1, m, md, ml);
+       ShowOutRange(2, o, od, ol);
+       ShowSubNumber(0, n, nd, nl);
+       ShowSubNumber(1, m, md, ml);
+       ShowSubNumber(2, o, od, ol);
+       return(e->flag);
+}
+
+ShowDiff4(e, r1, r2, n, nd, nl, m, md, ml, o, od, ol, p, pd, pl)
+               struct testenv *e; char *n, *m, *o, *p;
+               int r1, r2, nd, nl, md, ml, od, ol, pd, pl; {
+       ErrorPrint(e);
+       if(r1 != r2)
+               printf("---- Result is %d and should be %d----\n", r1, r2);
+       ShowOutRange(0, n, nd, nl);
+       ShowOutRange(1, m, md, ml);
+       ShowOutRange(2, o, od, ol);
+       ShowOutRange(3, p, pd, pl);
+       ShowSubNumber(0, n, nd, nl);
+       ShowSubNumber(1, m, md, ml);
+       ShowSubNumber(2, o, od, ol);
+       ShowSubNumber(3, p, pd, pl);
+       return(e->flag);
+}
+
+ShowSubNumber(x, n, nd, nl) char *n; int x, nd, nl; {
+       printf("[%s, %d, %d] =  ", n, nd, nl);
+       RangeNumberPrint("", RN(x), nd, nl);
+       if(CheckSubRange(x, nd, nl)) {
+               RangeNumberPrint(" Before:      ", NumbProto, nd, nl);
+               RangeNumberPrint(" Simulated:   ", SN(x), nd, nl);
+}      }
+
+RangeNumberPrint(s, n, nd, nl) char *s; BigNum n; int nd, nl; {
+       int first = 1;
+
+       /* Ne marche que si BnGetDigit est garanti!!! */
+       printf("%s {", s);
+       while(nl) {
+               nl--;
+               if(!first) printf(", "); else first = 0;
+               if(BN_DIGIT_SIZE <= 16)
+                       printf("%.4X", BnGetDigit(n, nd + nl));
+               else    printf("%.8X", BnGetDigit(n, nd + nl));
+       }
+       printf("}\n");
+}
+
+char *msg = "---- Modification Out of Range of number ";
+ShowOutRange(x, n, nd, nl) char *n; int x, nd, nl; {
+       int i = 0, bol = 0;
+
+       while(i = CheckSubRange(x, i, TESTLENGTH - i)) {
+               if((i <= nd) || (i > nd + nl)) {
+                       if(!bol) {
+                               bol = 1;
+                               printf("%s %s at index: (%d", msg, n, i - 1);
+                       } else {
+                               printf(" %d", i - 1);
+       }       }       }
+       if(bol) printf(").\n");
+}              
+
+ErrorPrint(e) struct testenv *e; {
+       printf("*** Error in compute : %s\n", e->hist);
+       printf("  Depends on %s\n", e->depend);
+}
+
+/*
+ *     Tests des fonctions non redefinisables
+ */
+
+int genlengthvec[] = {9, 8, 1, 0, 2000, 32000,};
+BigNumType gentypevec[] = {0, 1, 2, 3, 4, 5,};
+
+Generique(e) struct testenv *e; {
+       int i;
+       int length, length2;
+       BigNumType type, type2;
+       int fix;
+       BigNum n;
+
+       
+   for(i=0; i < 6; i++) {
+       type = gentypevec[i];
+       length = genlengthvec[i];
+       n = BnCreate(type, length);
+       if((type2 = BnGetType(n)) != type) {
+               sprintf(e->hist,"BnGetType(BnCreate(%d, %d));", type, length);
+               if(ShowDiff0(e, type, type2)) return(TRUE);
+       }
+       if((length2 = BnGetSize(n)) != length) {
+               sprintf(e->hist,"BnGetSize(BnCreate(%d, %d));", type, length);
+               if(ShowDiff0(e, length, length2)) return(TRUE);
+       }
+       if(BnFree(n) == 0) {
+               sprintf(e->hist, "BnFree(BnCreate(%d, %d));", type, length);
+               if(ShowDiff0(e, 1, 0)) return(TRUE);
+       }
+       BnSetType((n = BnAlloc(length)), type);
+       if((type2 = BnGetType(n)) != type) {
+               sprintf(e->hist,"BnGetType(BnAlloc(%d, %d));", type, length);
+               if(ShowDiff0(e, type, type2)) return(TRUE);
+       }
+       if((length2 = BnGetSize(n)) != length) {
+               sprintf(e->hist,"BnGetSize(BnAlloc(%d, %d));", type, length);
+               if(ShowDiff0(e, length, length2)) return(TRUE);
+       }
+       if(BnFree(n) == 0) {
+               sprintf(e->hist, "BnFree(BnAlloc(%d, %d));", type, length);
+               if(ShowDiff0(e, 1, 0)) return(TRUE);
+       }
+   }
+   return(FALSE);
+}
+
+/*
+ *     BnSetToZero
+ */
+___BnSetToZero___(n, nd, nl) register BigNum n; register int nd, nl; {
+       register int i;
+       for(i=0; i<nl; i++)
+               BnSetDigit(n, nd + i, 0);
+}
+
+TestBnSetToZero(e) struct testenv *e; {
+       int nd, nl;
+
+       e->depend = "()";
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+          for(nl = 0; nl <= TESTLENGTH - nd; nl++) {
+               TestCount++;
+               ResetTest(0);
+                  BnSetToZero   (RN(0), nd, nl);
+               ___BnSetToZero___(SN(0), nd, nl);
+               if(Check(1)) {
+                       sprintf(e->hist, "%s(n, %d, %d)", e->name, nd, nl);
+                       if(ShowDiff1(e, 0, 0, "n", nd, nl)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnAssign
+ */
+___BnAssign___(m, md, n, nd, nl) BigNum m, n; int md, nd, nl; {
+       BnSetToZero(NtmpBig, 0, nl);
+       BnAdd(NtmpBig, 0, nl, n, nd, nl, 0);
+       BnSetToZero(m, md, nl);
+       BnAdd(m, md, nl, NtmpBig, 0, nl, 0);
+}
+
+TestBnAssign(e) struct testenv *e; {
+       int md, nd, nl;
+
+       e->depend = "(BnSetToZero, BnAdd)";
+       for(md = 0; md <= TESTLENGTH; md++)
+         for(nd = 0; nd <= TESTLENGTH; nd++)
+           for(nl=0; ((nl<=TESTLENGTH-nd) && (nl<=TESTLENGTH-md)); nl++) {
+               TestCount++;
+               ResetTest(0);
+                  BnAssign   (RN(0), md, RN(0), nd, nl);
+               ___BnAssign___(SN(0), md, SN(0), nd, nl);
+               if(Check(1)) {
+                       sprintf(e->hist, "%s(n, %d, n, %d, %d)", e->name,
+                                               md, nd, nl);
+                       if(ShowDiff1(e, 0, 0, "n", md, nl)) return(1);
+       }       }
+       return(FALSE);
+}
+
+
+/*
+ *     BnNumDigits
+ */
+___BnNumDigits___(n, nd, nl) register BigNum n; register int nd, nl; {
+
+       while(nl != 0) {
+               nl--;
+               if(!BnIsDigitZero(n, nd + nl)) break;
+       }
+       return(nl + 1);
+}
+
+TestBnNumDigits(e) struct testenv *e; {
+       int nd0, nl0, nd, nl, l1, l2;
+
+       e->depend = "(BnIsDigitZero)";
+       for(nd0 = 0; nd0 <= TESTLENGTH; nd0++)
+         for(nl0 = 0; nl0 <= TESTLENGTH - nd0; nl0++)
+           for(nd = 0; nd <= TESTLENGTH; nd++)
+             for(nl = 0; nl <= TESTLENGTH - nd; nl++) {
+               TestCount++;
+               ResetTest(0);
+               BnSetToZero(RN(0), nd0, nl0);
+               BnSetToZero(SN(0), nd0, nl0);
+               l1 =    BnNumDigits   (RN(0), nd, nl);
+               l2 = ___BnNumDigits___(SN(0), nd, nl);
+               if(Check(1) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d, %d)", e->name, nd, nl);
+                       if(ShowDiff1(e, l1, l2, "n", nd, nl)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnNumLeadingZeroBitsInDigit
+ */
+__BnNumLeadingZeroBitsInDigit__(n, nd) BigNum n; int nd; {
+       int p = 0;
+
+       if(BnIsDigitZero(n, nd)) return(BN_DIGIT_SIZE);
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnShiftLeft(Ntmp2, 0, 1, Ntmp2, 1, 1);
+       while(BnIsDigitZero(Ntmp2, 1)) {
+               BnShiftLeft(Ntmp2, 0, 1, Ntmp2, 1, 1);
+               p++;
+       }
+       return(p);
+}
+
+TestBnNumLeadingZeroBitsInDigit(e) struct testenv *e; {
+       int nd; int l1, l2;
+
+
+       e->depend = "(BnShiftLeft, BnIsDigitZero)";
+       ResetTest(0);
+       for(nd = 0; nd < TESTLENGTH; nd++) {
+               TestCount++;
+               l1 =    BnNumLeadingZeroBitsInDigit   (RN(0), nd);
+               l2 = __BnNumLeadingZeroBitsInDigit__(SN(0), nd);
+               if(Check(1) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d)", e->name, nd);
+                       if(ShowDiff1(e, l1, l2, "n", nd, 1)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnIsDigitZero
+ */
+___BnIsDigitZero___(n, nd) BigNum n; int nd; {
+       if(BnGetDigit(n, nd) == 0) return(1);
+       return(0);
+}
+
+TestBnIsDigitZero(e) struct testenv *e; {
+       int nd; int l1, l2;
+
+       e->depend = "()";
+       ResetTest(0);
+       for(nd = 0; nd < TESTLENGTH; nd++) {
+               TestCount++;
+               l1 =    BnIsDigitZero   (RN(0), nd);
+               l2 = ___BnIsDigitZero___(SN(0), nd);
+               if(Check(1) || ((l1 == 0) && (l2 != 0)) ||
+                              ((l1 != 0) && (l2 == 0))) {
+                       sprintf(e->hist, "%s(n, %d)", e->name, nd);
+                       if(ShowDiff1(e, l1, l2, "n", nd, 1)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnIsDigitNormalized
+ */
+___BnIsDigitNormalized___(n, nd) BigNum n; int nd; {
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnShiftLeft(Ntmp2, 0, 1, Ntmp2, 1, 1);
+       if(BnIsDigitZero(Ntmp2, 1)) return(0);
+       return(1);
+}
+
+TestBnIsDigitNormalized(e) struct testenv *e; {
+       int nd; int l1, l2;
+
+       e->depend = "(BnShiftLeft, BnIsDigitZero)";
+       ResetTest(0);
+       for(nd = 0; nd < TESTLENGTH; nd++) {
+               TestCount++;
+               l1 =    BnIsDigitNormalized   (RN(0), nd);
+               l2 = ___BnIsDigitNormalized___(SN(0), nd);
+               if(Check(1) || ((l1 == 0) && (l2 != 0)) ||
+                              ((l1 != 0) && (l2 == 0))) {
+                       sprintf(e->hist, "%s(n, %d)", e->name, nd);
+                       if(ShowDiff1(e, l1, l2, "n", nd, 1)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnIsDigitOdd
+ */
+___BnIsDigitOdd___(n, nd) BigNum n; int nd; {
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnShiftRight(Ntmp2, 0, 1, Ntmp2, 1, 1);
+       if(BnIsDigitZero(Ntmp2, 1)) return(0);
+       return(1);
+}
+
+TestBnIsDigitOdd(e) struct testenv *e; {
+       int nd; int l1, l2;
+
+       e->depend = "(BnShiftRight, BnIsDigitZero)";
+       ResetTest(0);
+       for(nd = 0; nd < TESTLENGTH; nd++) {
+               TestCount++;
+               l1 =    BnIsDigitOdd   (RN(0), nd);
+               l2 = ___BnIsDigitOdd___(SN(0), nd);
+               if(Check(1) || ((l1 == 0) && (l2 != 0)) ||
+                              ((l1 != 0) && (l2 == 0))) {
+                       sprintf(e->hist, "%s(n, %d)", e->name, nd);
+                       if(ShowDiff1(e, l1, l2, "n", nd, 1)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnCompareDigits
+ */
+___BnCompareDigits___(n, nd, m, md) BigNum n, m; int nd, md; {
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnComplement(Ntmp2, 0, 1);
+       if(BnAdd(Ntmp2, 0, 1, m, md, 1, 0)) return(-1);
+       BnComplement(Ntmp2, 0, 1);
+       if(BnIsDigitZero(Ntmp2, 0)) return(0);
+       return(1);
+}
+
+TestBnCompareDigits(e) struct testenv *e; {
+       int nd, md; int l1, l2;
+
+       e->depend = "(BnComplement, BnAdd, BnIsDigitZero)";
+       ResetTest(0);
+       ResetTest(1);
+       for(nd = 0; nd < TESTLENGTH; nd++)
+          for(md = 0; md < TESTLENGTH; md++) {
+               TestCount++;
+               l1 =    BnCompareDigits   (RN(0), nd, RN(1), md);
+               l2 = ___BnCompareDigits___(SN(0), nd, SN(1), md);
+               if(Check(2) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d, m, %d)", e->name, nd, md);
+                       if(ShowDiff2(e, l1, l2, "n", nd, 1, "m", md, 1))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnComplement
+ */
+___BnComplement___(n, nd, nl) BigNum n; int nd, nl; {
+       int i;
+
+       BnSetDigit(Ntmp2, 0, 0);
+       BnSubtractBorrow(Ntmp2, 0, 1, 0);
+       for(i = 0; i < nl; i++)
+               BnXorDigits(n, nd + i, Ntmp2, 0);
+}
+
+TestBnComplement(e) struct testenv *e; {
+       int nd, nl;
+
+       e->depend = "(BnSubtractBorrow, BnXorDigits)";
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+          for(nl = 0; nl <= TESTLENGTH - nd; nl++) {
+               TestCount++;
+               ResetTest(0);
+                  BnComplement   (RN(0), nd, nl);
+               ___BnComplement___(SN(0), nd, nl);
+               if(Check(1)) {
+                       sprintf(e->hist, "%s(n, %d, %d)", e->name, nd, nl);
+                       if(ShowDiff1(e, 0, 0, "n", nd, nl)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnAndDigits
+ */
+___BnAndDigits___(n, nd, m, md) BigNum n, m; int nd, md; {
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnOrDigits(Ntmp2, 0, m, md);
+       BnXorDigits(Ntmp2, 0, m, md);
+       BnXorDigits(n, nd, Ntmp2, 0);
+}
+
+TestBnAndDigits(e) struct testenv *e; {
+       int nd, md;
+
+       e->depend = "(BnOrDigits, BnXorDigits)";
+       ResetTest(1);
+       for(nd = 0; nd < TESTLENGTH; nd++)
+          for(md = 0; md < TESTLENGTH; md++) {
+               TestCount++;
+               ResetTest(0);
+                  BnAndDigits   (RN(0), nd, RN(1), md);
+               ___BnAndDigits___(SN(0), nd, SN(1), md);
+               if(Check(2)) {
+                       sprintf(e->hist, "%s(n, %d, m, %d)", e->name, nd, md);
+                       if(ShowDiff2(e, 0, 0, "n", nd, 1, "m", md, 1))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnOrDigits
+ */
+___BnOrDigits___(n, nd, m, md) BigNum n, m; int nd, md; {
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnAndDigits(Ntmp2, 0, m, md);
+       BnXorDigits(Ntmp2, 0, m, md);
+       BnXorDigits(n, nd, Ntmp2, 0);
+}
+
+TestBnOrDigits(e) struct testenv *e; {
+       int nd, md;
+
+       e->depend = "(BnAndDigits, BnXorDigits)";
+       ResetTest(1);
+       for(nd = 0; nd < TESTLENGTH; nd++)
+          for(md = 0; md < TESTLENGTH; md++) {
+               TestCount++;
+               ResetTest(0);
+                  BnOrDigits   (RN(0), nd, RN(1), md);
+               ___BnOrDigits___(SN(0), nd, SN(1), md);
+               if(Check(2)) {
+                       sprintf(e->hist, "%s(n, %d, m, %d)", e->name, nd, md);
+                       if(ShowDiff2(e, 0, 0, "n", nd, 1, "m", md, 1))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnXorDigits
+ */
+___BnXorDigits___(n, nd, m, md) BigNum n, m; int nd, md; {
+       BnAssign(Ntmp2, 0, n, nd, 1);
+       BnAndDigits(Ntmp2, 0, m, md);
+       BnComplement(Ntmp2, 0, 1);
+       BnOrDigits(n, nd, m, md);
+       BnAndDigits(n, nd, Ntmp2, 0);
+}
+
+TestBnXorDigits(e) struct testenv *e; {
+       int nd, md;
+
+       e->depend = "(BnAndDigits, BnComplement, BnOrDigits)";
+       ResetTest(1);
+       for(nd = 0; nd < TESTLENGTH; nd++)
+          for(md = 0; md < TESTLENGTH; md++) {
+               TestCount++;
+               ResetTest(0);
+                  BnXorDigits   (RN(0), nd, RN(1), md);
+               ___BnXorDigits___(SN(0), nd, SN(1), md);
+               if(Check(2)) {
+                       sprintf(e->hist, "%s(n, %d, m, %d)", e->name, nd, md);
+                       if(ShowDiff2(e, 0, 0, "n", nd, 1, "m", md, 1))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnShiftLeft
+ */
+___BnShiftLeft___(n, nd, nl, m, md, s) BigNum n, m; int nd, nl, md; int s; {
+       BnSetDigit(m, md, 2);
+       BnSetDigit(Ntmp2, 0, 1);
+       while(s--) {
+               BnSetToZero(NtmpBig, 0, 2);
+               BnMultiplyDigit(NtmpBig, 0, 2, Ntmp2, 0, 1, m, md);
+               BnAssign(Ntmp2, 0, NtmpBig, 0, 1);
+       }
+       BnSetToZero(NtmpBig, 0, nl + 1);
+       BnMultiplyDigit(NtmpBig, 0, nl + 1, n, nd, nl, Ntmp2, 0);
+       BnAssign(n, nd, NtmpBig, 0, nl);
+       BnAssign(m, md, NtmpBig, nl, 1);
+}
+
+TestBnShiftLeft(e) struct testenv *e; {
+       int nd, nl, md; int s;
+
+       e->depend = "(BnSetToZero, BnMultiplyDigit)";
+       ResetTest(1);
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+         for(nl = 0; nl <= TESTLENGTH - nd; nl++)
+           for(md = 0; md < 2; md++)
+             for(s = 0; s < BN_DIGIT_SIZE; s++) {
+               TestCount++;
+               ResetTest(0);
+                  BnShiftLeft   (RN(0), nd, nl, RN(1), md, s);
+               ___BnShiftLeft___(SN(0), nd, nl, SN(1), md, s);
+               if(Check(2)) {
+                       sprintf(e->hist, "%s(n, %d, %d, m, %d, %d)",
+                                       e->name, nd, nl, md, s);
+                       if(ShowDiff2(e, 0, 0, "n", nd, nl, "m", md, 1))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnShiftRight
+ */
+___BnShiftRight___(n, nd, nl, m, md, s) BigNum n, m; int nd, nl, md; int s; {
+       if((nl == 0) || (s == 0)) {
+               BnSetDigit(m, md, 0);
+               return;
+       }
+       BnAssign(NtmpBig, 0, n, nd, nl);
+       BnShiftLeft(NtmpBig, 0, nl, NtmpBig, nl, BN_DIGIT_SIZE - s);
+       BnAssign(n, nd, NtmpBig, 1, nl);
+       BnAssign(m, md, NtmpBig, 0, 1);
+}
+
+TestBnShiftRight(e) struct testenv *e; {
+       int nd, nl, md; int s;
+
+       e->depend = "(BnShiftLeft)";
+       ResetTest(1);
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+         for(nl = 0; nl <= TESTLENGTH - nd; nl++)
+           for(md = 0; md < 2; md++)
+             for(s = 0; s < BN_DIGIT_SIZE; s++) {
+               TestCount++;
+               ResetTest(0);
+                  BnShiftRight   (RN(0), nd, nl, RN(1), md, s);
+               ___BnShiftRight___(SN(0), nd, nl, SN(1), md, s);
+               if(Check(2)) {
+                       sprintf(e->hist, "%s(n, %d, %d, m, %d, %d)",
+                                       e->name, nd, nl, md, s);
+                       if(ShowDiff2(e, 0, 0, "n", nd, nl, "m", md, 1))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnAddCarry
+ */
+___BnAddCarry___(n, nd, nl, r) BigNum n; int nd, nl; int r;{
+       if(r == 0) return(0);
+       BnComplement(n, nd, nl);
+       r = BnSubtractBorrow(n, nd, nl, 0);
+       BnComplement(n, nd, nl);
+       if(r == 0) return(1);
+       return(0);
+}
+
+TestBnAddCarry(e) struct testenv *e; {
+       int nd, nl; int r, l1, l2;
+
+       e->depend = "(BnComplement, BnSubtractBorrow)";
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+         for(nl = 0; nl <= TESTLENGTH - nd; nl++)
+           for(r = 0; r < 2; r++) {
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnAddCarry   (RN(0), nd, nl, r);
+               l2 = ___BnAddCarry___(SN(0), nd, nl, r);
+               if(Check(1) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d, %d, %d)",
+                                       e->name, nd, nl, r);
+                       if(ShowDiff1(e, l1, l2, "n", nd, nl)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnAdd
+ */
+___BnAdd___(n, nd, nl, m, md, ml, r) BigNum n, m; int nd, nl, md, ml; int r;{
+       BnComplement(m, md, ml);
+       r = BnSubtract(n, nd, ml, m, md, ml, r);
+       BnComplement(m, md, ml);
+       return(BnAddCarry(n, nd + ml, nl - ml, r));
+}
+
+TestBnAdd(e) struct testenv *e; {
+       int nd, nl, md, ml; int r, l1, l2;
+
+       e->depend = "(BnComplement, BnSubtract, BnAddCarry)";
+       ResetTest(1);
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+        for(nl = 0; nl <= TESTLENGTH - nd; nl++)
+         for(md = 0; md <= TESTLENGTH - nl; md++)
+          for(ml = 0; ml <= nl ; ml++)
+           for(r = 0; r < 2; r++) {
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnAdd   (RN(0), nd, nl, RN(1), md, ml, r);
+               l2 = ___BnAdd___(SN(0), nd, nl, SN(1), md, ml, r);
+               if(Check(2) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d, %d, m, %d, %d, %d)",
+                                       e->name, nd, nl, md, ml, r);
+                       if(ShowDiff2(e, l1, l2, "n", nd, nl, "m", md, ml))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnSubtractBorrow
+ */
+___BnSubtractBorrow___(n, nd, nl, r) BigNum n; int nd, nl; int r;{
+       if(r == 1) return(1);
+       BnComplement(n, nd, nl);
+       r = BnAddCarry(n, nd, nl, 1);
+       BnComplement(n, nd, nl);
+       if(r == 0) return(1);
+       return(0);
+}
+
+TestBnSubtractBorrow(e) struct testenv *e; {
+       int nd, nl; int r, l1, l2;
+
+       e->depend = "(BnComplement, BnAddCarry)";
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+         for(nl = 0; nl <= TESTLENGTH - nd; nl++)
+           for(r = 0; r < 2; r++) {
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnSubtractBorrow   (RN(0), nd, nl, r);
+               l2 = ___BnSubtractBorrow___(SN(0), nd, nl, r);
+               if(Check(1) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d, %d, %d)",
+                                       e->name, nd, nl, r);
+                       if(ShowDiff1(e, l1, l2, "n", nd, nl)) return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnSubtract
+ */
+___BnSubtract___(n, nd, nl, m, md, ml, r) BigNum n, m; int nd, nl, md, ml; int r;{
+       BnComplement(m, md, ml);
+       r = BnAdd(n, nd, ml, m, md, ml, r);
+       BnComplement(m, md, ml);
+       return(BnSubtractBorrow(n, nd + ml, nl - ml, r));
+}
+
+TestBnSubtract(e) struct testenv *e; {
+       int nd, nl, md, ml; int r, l1, l2;
+
+       e->depend = "(BnComplement, BnAdd, BnSubtractBorrow)";
+       ResetTest(1);
+       for(nd = 0; nd <= TESTLENGTH; nd++)
+        for(nl = 0; nl <= TESTLENGTH - nd; nl++)
+         for(md = 0; md <= TESTLENGTH - nl; md++)
+          for(ml = 0; ml <= nl ; ml++)
+           for(r = 0; r < 2; r++) {    
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnSubtract   (RN(0), nd, nl, RN(1), md, ml, r);
+               l2 = ___BnSubtract___(SN(0), nd, nl, SN(1), md, ml, r);
+               if(Check(2) || l1 != l2) {
+                       sprintf(e->hist, "%s(n, %d, %d, m, %d, %d, %d)",
+                                       e->name, nd, nl, md, ml, r);
+                       if(ShowDiff2(e, l1, l2, "n", nd, nl, "m", md, ml))
+                               return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnMultiplyDigit
+ */
+___BnMultiplyDigit___(p, pd, pl, n, nd, nl, m, md) BigNum p, n, m; int pd, pl, nd, nl, md; {
+       int r = 0, ret = 0;
+
+       BnAssign(Ntmp2, 0, m, md, 1);
+       BnAssign(NtmpBig, 0, n, nd, nl);
+       BnSetToZero(NtmpBig, nl, 1);
+       while(!BnIsDigitZero(Ntmp2, 0)) {
+               if(BnIsDigitOdd(Ntmp2, 0)) {
+                       r = BnAdd(p, pd, pl, NtmpBig, 0, nl + 1, 0);
+                       if((ret == 0) && (r == 1)) ret = 1;
+                       else if((ret == 1) && (r == 1)) ret = 2;
+               }
+               BnShiftRight(Ntmp2, 0, 1, Ntmp2, 1, 1);
+               BnShiftLeft(NtmpBig, 0, nl + 1, Ntmp2, 1, 1);
+               if(!BnIsDigitZero(Ntmp2, 1)) ret = 3;
+       }
+       return(ret);
+}
+
+TestBnMultiplyDigit(e) struct testenv *e; {
+       int pd, pl, nd, nl, md; int l1, l2;
+
+       e->depend = "(BnSetToZero, BnIsDigitZero, BnIsDigitOdd, BnAdd, BnShiftRight, BnShiftLeft)";
+       ResetTest(1);
+       ResetTest(2);
+       for(pd = 0; pd <= TESTLENGTH; pd++)
+        for(pl = 0; pl <= TESTLENGTH - pd; pl++)
+         for(nd = 0; nd <= TESTLENGTH - pl; nd++)
+          for(nl = 0; nl < pl ; nl++)
+           for(md = 0; md < TESTLENGTH; md++) {
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnMultiplyDigit   (RN(0),pd,pl,RN(1),nd,nl,RN(2),md);
+               l2 = ___BnMultiplyDigit___(SN(0),pd,pl,SN(1),nd,nl,SN(2),md);
+               if(Check(3) || l1 != l2) {
+                       sprintf(e->hist,
+                          "BnMultiplyDigit(p, %d, %d, n, %d, %d, m, %d)",
+                                               pd, pl, nd, nl, md);
+                       if(ShowDiff3(e,l1,l2,"p",pd,pl,"n",nd,nl,"m",md,1))
+                                return(1);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnDivideDigit
+ */
+TestBnDivideDigit(e) struct testenv *e; {
+       int nd, nl, md, qd, rd, l2;
+
+       e->depend = "(BnSetToZero, BnMultiplyDigit, BnCompareDigits)";
+       ResetTest(2);
+       ResetTest(3);
+       for(nd = 0; nd <= TESTLENGTH - 2; nd++)
+        for(nl = 2; nl <= TESTLENGTH - nd; nl++)
+         for(md = 0; md < TESTLENGTH; md++)
+          for(qd = 0; qd < TESTLENGTH - nl + 1 ; qd++)
+           for(rd = 0; rd < 2; rd++)
+            if((!BnIsDigitZero(RN(3), md)) &&
+                       (BnCompareDigits(RN(2), nd+nl-1, RN(3), md) == -1)) {
+               TestCount++;
+               ResetTest(0);
+               ResetTest(1);
+               BnDivideDigit(RN(0), qd, RN(1), rd, RN(2), nd, nl, RN(3), md);
+               BnAssign(SN(0), qd, RN(0), qd, nl - 1);
+               BnAssign(SN(1), rd, RN(1), rd, 1);
+               BnSetToZero(SN(2), nd, nl);
+               BnAssign(SN(2), nd, SN(1), rd, 1);
+               l2 = BnMultiplyDigit(SN(2),nd,nl, SN(0),qd,nl - 1, SN(3), md);
+               if(Check(4) || l2 != 0) {
+                       sprintf(e->hist,
+                          "BnDivideDigit(q, %d, r, %d, n, %d, %d, m, %d)",
+                                               qd, rd, nd, nl, md);
+                       if(ShowDiff4(e, 0, l2, "q", qd, nl - 1, "r", rd, 1,
+                                       "n", nd, nl, "m", md, 1))
+                               return(TRUE);
+       }       }
+       return(FALSE);
+}
+
+/*
+ *     BnMultiply
+ */
+___BnMultiply___(p, pd, pl, m, md, ml, n, nd, nl) BigNum p, m, n; int pd, pl, md, ml, nd, nl; {
+       int ret;
+
+        for (ret = 0; nl-- > 0; pd++, nd++, pl--)
+           ret += BnMultiplyDigit (p, pd, pl, m, md, ml, n, nd);
+       return(ret);
+}
+
+TestBnMultiply(e) struct testenv *e; {
+       int pd, pl, nd, nl, md, ml; int l1, l2;
+
+       e->depend = "(BnSetToZero, BnMultiplyDigit)";
+       ResetTest(1);
+       ResetTest(2);
+       for(pd = 0; pd <= TESTLENGTH; pd++)
+        for(pl = 0; pl <= TESTLENGTH - pd && pl <= TESTLENGTH/2; pl++)
+         for(nd = 0; nd <= TESTLENGTH - pl; nd++)
+          for(nl = 0; nl < pl && nl <= TESTLENGTH/3; nl++)
+          {
+           if (nl <= pl-nl)
+           {
+               /* Test squaring */
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnMultiply   (RN(0),pd,pl,RN(1),nd,nl,RN(1),nd,nl);
+               l2 = ___BnMultiply___(SN(0),pd,pl,SN(1),nd,nl,SN(1),nd,nl);
+               if(Check(3) || l1 != l2) {
+                       sprintf(e->hist,
+                          "BnMultiply(p, %d, %d, n, %d, %d, n, %d, %d)",
+                                               pd, pl, nd, nl, nd, nl);
+                       if(ShowDiff3(e,l1,l2,"p",pd,pl,"n",nd,nl,"n",nd,nl))
+                                return(1);
+               }
+
+           }
+           for(md = 0; md <= TESTLENGTH; md++) 
+            for (ml = 0; ml <= pl-nl && ml <= TESTLENGTH/3 && md+ml <= TESTLENGTH; ml++) {
+               TestCount++;
+               ResetTest(0);
+               l1 =    BnMultiply   (RN(0),pd,pl,RN(1),nd,nl,RN(2),md,ml);
+               l2 = ___BnMultiply___(SN(0),pd,pl,SN(1),nd,nl,SN(2),md,ml);
+               if(Check(3) || l1 != l2) {
+                       sprintf(e->hist,
+                          "BnMultiply(p, %d, %d, n, %d, %d, m, %d, %d)",
+                                               pd, pl, nd, nl, md, ml);
+                       if(ShowDiff3(e,l1,l2,"p",pd,pl,"n",nd,nl,"m",md,ml))
+                                return(1);
+       }  }    }
+       return(FALSE);
+}
+
+/*
+ *     Main
+ */
+typedef struct {
+       int     (*TestFnt)();
+       char    *NameFnt;
+} TESTONE;
+TESTONE AllTest[] = {
+       Generique,                              "Generic Functions",
+       TestBnSetToZero,                        "BnSetToZero",
+       TestBnAssign,                           "BnAssign",
+       TestBnNumDigits,                        "BnNumDigits",
+       TestBnNumLeadingZeroBitsInDigit,        "BnNumLeadingZeroBitsInDigit",
+       TestBnIsDigitZero,                      "BnIsDigitZero",
+       TestBnIsDigitNormalized,                "BnIsDigitNormalized",
+       TestBnIsDigitOdd,                       "BnIsDigitOdd",
+       TestBnCompareDigits,                    "BnCompareDigits",
+       TestBnComplement,                       "BnComplement",
+       TestBnAndDigits,                        "BnAndDigits",
+       TestBnOrDigits,                         "BnOrDigits",
+       TestBnXorDigits,                        "BnXorDigits",
+       TestBnShiftLeft,                        "BnShiftLeft",
+       TestBnShiftRight,                       "BnShiftRight",
+       TestBnAddCarry,                         "BnAddCarry",
+       TestBnAdd,                              "BnAdd",
+       TestBnSubtractBorrow,                   "BnSubtractBorrow",
+       TestBnSubtract,                         "BnSubtract",
+       TestBnMultiplyDigit,                    "BnMultiplyDigit",
+       TestBnDivideDigit,                      "BnDivideDigit",
+       TestBnMultiply,                         "BnMultiply",
+};
+
+main(n, s) int n; char **s; {
+       struct testenv realenv, *e = &realenv;
+       int i, j, nbtest, SizeAllTest;
+
+       /* Initialisations de l'environnement de test. */
+       e->flag = 1;
+       e->depend = "()";
+       /* Allocation des 2 nombres globaux. */
+       Ntmp2 = BnAlloc(2);
+       NtmpBig = BnAlloc(2 * TESTLENGTH);
+       NumbProto = BnAlloc(TESTLENGTH);
+       /* Creation du nombre prototype. */
+       BnSetDigit(NumbProto, 0, 0);            /* Les 2 premiers a` ze'ro. */
+       BnSetDigit(NumbProto, 1, 0);
+       for(i=0; i < TESTLENGTH/4 - 1; i++)     /* Le premier quart est la */
+               BnSetDigit(NumbProto, i + 2, i + 1);    /* suite 1, 2, 3, ...      */
+       /* Le 2nd quart est le 1er shifte de BN_DIGIT_SIZE - 2. 0x4000 0x8000 ...*/
+       BnAssign(NumbProto, QTL + 1, NumbProto, 2, QTL - 1);
+       BnShiftLeft(NumbProto, QTL + 1, QTL - 1, NumbProto, 0, BN_DIGIT_SIZE - 2);
+       /* La 2nd moitie est l'inverse logique de la 1ere */
+       BnAssign(NumbProto, DTL, NumbProto, 0, DTL);
+       BnComplement(NumbProto, DTL, DTL);
+       /* Allocation des nombres utilise's */
+       for(i=0; i < 5; i++) {
+               RN(i) = BnAlloc(TESTLENGTH);
+               SN(i) = BnAlloc(TESTLENGTH);
+       }
+       if(n == 1) {
+               printf("%s [v|a|TestNum]\n", s[0]);
+       }
+       /* On y va */
+       SizeAllTest = (sizeof(AllTest)/sizeof(AllTest[0]));
+       for(i = 1; i < n; i++) {
+               if(s[i][0] == 'm') {
+                       /* 0 = No skip; 1 = skip to next; else STOP */
+                       e->flag = atoi(&s[i][1]);
+               } else if(s[i][0] == 'a') {
+                       for(i = 0; i < SizeAllTest; i++)
+                               dotest(e, i);
+               } else if(s[i][0] == 'v') {
+                       for(j = 0; j < SizeAllTest; j++)
+                               seetest(j);
+               } else {
+                       nbtest = atoi(s[i]);
+                       if((nbtest < 0) || (nbtest >= SizeAllTest))
+                               printf("Test %d is invalid\n", nbtest);
+                       else    dotest(e, nbtest);
+}      }       }
+
+dotest(e, n) struct testenv *e; int n; {
+       seetest(n);
+       TestCount = 0;
+       e->name = AllTest[n].NameFnt;
+       if(((*(AllTest[n].TestFnt)) (e)) && e->flag > 1) exit(0);
+       printf("%d tests were performed\n", TestCount);
+}
+
+seetest(n) int n; {
+       printf("%d.     Testing %s\n", n, AllTest[n].NameFnt);
+}
+
diff --git a/util/gdss/lib/crypto/bignum/h/BigNum.h b/util/gdss/lib/crypto/bignum/h/BigNum.h
new file mode 100644 (file)
index 0000000..1db90ee
--- /dev/null
@@ -0,0 +1,140 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Fri Aug 17 17:19:01 GMT+2:00 1990 by shand */
+/*      modified_on Wed Jul  5 10:19:33 GMT+2:00 1989 by bertin */
+/*      modified_on Fri Apr 28 20:03:23 GMT+2:00 1989 by herve */
+
+
+/* BigN.h - Types and structures for clients of BigNum */
+
+
+
+               /******** representation of a bignum ******/
+/*
+**  <--------------------------- nl ---------------------------->
+**  |   Least                                           Most    |
+**  |Significant|           |           |           |Significant|
+**  |BigNumDigit|           |           |           |BigNumDigit|
+**  |___________|___________|___________|___________|___________|
+**        ^                                          (sometimes
+**        |                                            is zero)
+**       nn
+*/
+
+/* signals BigNum.h already included */
+#define BIGNUM
+
+               /*************** sizes ********************/
+
+#define BN_BYTE_SIZE                   8
+#define BN_WORD_SIZE                   (sizeof (int) * BN_BYTE_SIZE)
+#define BN_DIGIT_SIZE                  (sizeof (BigNumDigit) * BN_BYTE_SIZE)
+
+/* notes: */
+/* BN_BYTE_SIZE: number of bits in a byte */
+/* BN_WORD_SIZE: number of bits in an "int" in the target language */
+/* BN_DIGIT_SIZE: number of bits in a digit of a BigNum */
+
+
+               /****** results of compare functions ******/
+
+ /* Note: we don't use "enum" to interface with Modula2+, Lisp, ... */
+#define BN_LT                          -1
+#define BN_EQ                          0
+#define BN_GT                          1
+
+               /*************** boolean ******************/
+
+#define TRUE                           1
+#define FALSE                          0
+
+
+               /* if DIGITon16BITS is defined, a single digit is on 16 bits */
+               /* otherwise (by default) a single digit is on 32 bits *****/
+               /* Note: on 32 bit machine it makes little sense to mix */
+               /* longs and short, so we define Boolean & BigNumCmp to be */
+               /* int usually */
+
+#ifdef DIGITon16BITS
+typedef unsigned short                 BigNumDigit;
+typedef short                          Boolean;
+#else
+typedef unsigned int                   BigNumDigit;
+typedef int                            Boolean;
+#endif
+
+
+               /* bignum types: digits, big numbers, carries ... */
+
+typedef BigNumDigit *  BigNum;         /* A big number is a digit pointer */
+typedef BigNumDigit    BigNumCarry;    /* Either 0 or 1 */
+typedef unsigned long  BigNumProduct;  /* The product of two digits */
+typedef unsigned long  BigNumLength;   /* The length of a bignum */
+#ifdef DIGITon16BITS
+typedef short          BigNumCmp;      /* result of comparison */
+#else
+typedef int            BigNumCmp;      /* result of comparison */
+#endif
+
+
+/*\f*/
+
+
+               /************ functions of bn.c ***********/
+
+extern void             BnnInit                        ();
+extern void             BnnClose                       ();
+
+extern Boolean         BnnIsZero                       ();
+extern BigNumCarry     BnnMultiply                     ();
+extern void            BnnDivide                       ();
+extern BigNumCmp       BnnCompare                      ();
+
+
+               /*********** functions of KerN.c **********/
+
+extern void            BnnSetToZero                    ();
+extern void            BnnAssign                       ();
+extern void            BnnSetDigit                     ();
+extern BigNumDigit     BnnGetDigit                     ();
+extern BigNumLength    BnnNumDigits                    ();
+extern BigNumDigit     BnnNumLeadingZeroBitsInDigit    ();
+extern Boolean                 BnnDoesDigitFitInWord           ();
+extern Boolean         BnnIsDigitZero                  ();
+extern Boolean         BnnIsDigitNormalized            ();
+extern Boolean                 BnnIsDigitOdd                   ();
+extern BigNumCmp               BnnCompareDigits                ();
+extern void            BnnComplement                   ();
+extern void            BnnAndDigits                    ();
+extern void            BnnOrDigits                     ();
+extern void            BnnXorDigits                    ();
+extern BigNumDigit     BnnShiftLeft                    ();
+extern BigNumDigit     BnnShiftRight                   ();
+extern BigNumCarry     BnnAddCarry                     ();
+extern BigNumCarry     BnnAdd                          ();
+extern BigNumCarry     BnnSubtractBorrow               ();
+extern BigNumCarry     BnnSubtract                     ();
+extern BigNumCarry     BnnMultiplyDigit                ();
+extern BigNumDigit     BnnDivideDigit                  ();
+
+/*\f*/
+
+               /* some functions can be written with macro-procedures */
+
+
+#ifndef BNNMACROS_OFF
+/* the functions BnnIsZero and BnnCompareDigits are not macro procedures
+since they use parameters twice, and that can produce some bugs if
+you pass a parameter like x++, the increment will be executed twice ! */
+#define BnnSetDigit(nn,d)              (*(nn) = (d))
+#define BnnGetDigit(nn)                        ((unsigned)(*(nn)))
+#define BnnDoesDigitFitInWord(d)       (BN_DIGIT_SIZE > BN_WORD_SIZE ? ((d) >= 1 << BN_WORD_SIZE ? FALSE : TRUE) : TRUE)
+#define BnnIsDigitZero(d)              ((d) == 0)
+#define BnnIsDigitNormalized(d)                ((d) & (1 << (BN_DIGIT_SIZE - 1)) ? TRUE : FALSE)
+#define BnnIsDigitOdd(d)               ((d) & 1 ? TRUE : FALSE)
+#define BnnAndDigits(nn, d)            (*(nn) &= (d))
+#define BnnOrDigits(nn, d)             (*(nn) |= (d))
+#define BnnXorDigits(nn, d)            (*(nn) ^= (d))
+
+#endif
+
+
diff --git a/util/gdss/lib/crypto/bignum/h/BigZ.h b/util/gdss/lib/crypto/bignum/h/BigZ.h
new file mode 100644 (file)
index 0000000..82f0956
--- /dev/null
@@ -0,0 +1,97 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988, 1989 */
+/* Last modified_on Thu Mar 22 21:29:09 GMT+1:00 1990 by shand */
+/*      modified_on Mon Jan 23 18:38:46 GMT+1:00 1989 by herve */
+
+/* BigZ.h: Types and structures for clients of BigZ */
+
+                               /* BigZ sign */
+
+
+#define BZ_PLUS                                1
+#define BZ_ZERO                                0
+#define BZ_MINUS                       -1
+#define BzSign                         BigNumCmp
+
+
+                               /* BigZ compare result */
+
+
+#define BZ_LT                          BN_LT
+#define BZ_EQ                          BN_EQ
+#define BZ_GT                          BN_GT
+#define BzCmp                          BigNumCmp
+
+
+                               /* BigZ number */
+
+#ifndef BIGNUM
+#include "BigNum.h"
+#endif
+
+struct BigZHeader
+{
+    unsigned long                      Size;
+    BzSign                             Sign;
+};
+
+
+struct BigZStruct
+{
+    struct BigZHeader                  Header;
+    BigNumDigit                        Digits [16];
+};
+
+
+typedef struct BigZStruct *            BigZ;
+
+/*\f*/
+
+
+               /*********** macros of bz.c **********/
+
+
+#define BzGetSize(z)                   ((z)->Header.Size)
+#define BzGetSign(z)                   ((z)->Header.Sign)
+
+#define BzSetSize(z,s)                 (z)->Header.Size = s
+#define BzSetSign(z,s)                 (z)->Header.Sign = s
+
+#define BzGetOppositeSign(z)           (-(z)->Header.Sign)
+
+
+               /*********** functions of bz.c **********/
+
+extern void             BzInit                  ();
+extern void             BzClose                  ();
+
+extern BigZ            BzCreate                ();
+extern void            BzFree                  ();
+extern void            BzFreeString            ();
+
+extern unsigned                BzNumDigits             ();
+
+extern BigZ            BzCopy                  ();
+extern BigZ            BzNegate                ();
+extern BigZ            BzAbs                   ();
+extern BzCmp           BzCompare               ();
+
+extern BigZ            BzAdd                   ();
+extern BigZ            BzSubtract              ();
+extern BigZ            BzMultiply              ();
+extern BigZ            BzDivide                ();
+extern BigZ            BzDiv                   ();
+extern BigZ            BzMod                   ();
+
+extern BigZ            BzFromString            ();
+extern char *          BzToString              ();
+
+extern BigZ             BzFromInteger           ();
+extern int             BzToInteger             ();
+
+extern BigZ            BzFromBigNum            ();
+extern BigNum          BzToBigNum              ();
+
+               /*********** functions of bzf.c **********/
+
+extern BigZ            BzFactorial             ();
diff --git a/util/gdss/lib/crypto/bignum/h/BntoBnn.h b/util/gdss/lib/crypto/bignum/h/BntoBnn.h
new file mode 100644 (file)
index 0000000..b8c068b
--- /dev/null
@@ -0,0 +1,108 @@
+/* Copyright     Digital Equipment Corporation & INRIA     1988 */
+/* Last modified_on Wed Feb 14 16:20:34 GMT+1:00 1990 by herve                */
+/*      modified_on 17-OCT-1989 20:23:23.17 by Jim Lawton SDE/Galway          */
+
+/* BntoBnn.h: allowing to use the new interfaces of KerN */
+
+
+#ifndef VMS
+extern char *malloc();
+#endif
+
+
+               /* old types of Bn */
+
+typedef unsigned int   BigNumType;     /* A BigNum's type */
+
+struct BigNumHeader                    /* The header of a BigNum */
+{
+   BigNumType  type;
+   int         length;
+};
+
+
+               /* macros of old types of Bn */
+
+#define BN_TYPE(n)     (((struct BigNumHeader *) n) - 1)->type
+#define BN_LENGTH(n)   (((struct BigNumHeader *) n) - 1)->length
+
+
+               /* macros of functions of Bn to functions Bnn */
+
+#define BnIsZero(n, nd, nl)                            BnnIsZero ((n+nd), nl)
+#define BnMultiply(p, pd, pl, m, md, ml, n, nd, nl)    BnnMultiply ((p+pd), pl, (m+md), ml, (n+nd), nl)
+#define BnDivide(n, nd, nl, d, dd, dl)                 BnnDivide ((n+nd), nl, (d+dd), dl)
+#define BnCompare(m, md, ml, n, nd, nl)                        BnnCompare ((m+md), ml, (n+nd), nl)
+#define BnSetToZero(n, nd, nl)                                 BnnSetToZero ((n+nd), nl) 
+#define BnAssign(m, md, n, nd, nl)                     BnnAssign ((m+md), (n+nd), nl)
+#define BnSetDigit(n, nd, d)                           BnnSetDigit ((n+nd), d) 
+#define BnGetDigit(n, nd)                              BnnGetDigit ((n+nd))
+#define BnNumDigits(n, nd, nl)                         BnnNumDigits ((n+nd), nl)
+#define BnNumLeadingZeroBitsInDigit(n, nd)             BnnNumLeadingZeroBitsInDigit (*(n+nd))
+#define BnDoesDigitFitInWord(n, nd)                    BnnDoesDigitFitInWord (*(n+nd))
+#define BnIsDigitZero(n, nd)                           BnnIsDigitZero (*(n+nd))
+#define BnIsDigitNormalized(n, nd)                     BnnIsDigitNormalized (*(n+nd))
+#define BnIsDigitOdd(n, nd)                            BnnIsDigitOdd (*(n+nd))
+#define BnCompareDigits(m, md, n, nd)                  BnnCompareDigits (*(m+md), *(n+nd))
+#define BnComplement(n, nd, nl)                                BnnComplement ((n+nd), nl)
+#define BnAndDigits(m, md, n, nd)                      BnnAndDigits ((m+md), *(n+nd))
+#define BnOrDigits(m, md, n, nd)                       BnnOrDigits ((m+md), *(n+nd))
+#define BnXorDigits(m, md, n, nd)                      BnnXorDigits ((m+md), *(n+nd))
+#define BnShiftLeft(m, md, ml, n, nd, nbits)           *(n+nd) = BnnShiftLeft ((m+md), ml, nbits)
+#define BnShiftRight(m, md, ml, n, nd, nbits)          *(n+nd) = BnnShiftRight ((m+md), ml, nbits)
+#define BnAddCarry(n, nd, nl, carryin)                 BnnAddCarry ((n+nd), nl, carryin)
+#define BnAdd(m, md, ml, n, nd, nl, carryin)           BnnAdd ((m+md), ml, (n+nd), nl, carryin)
+#define BnSubtractBorrow(n, nd, nl, carryin)           BnnSubtractBorrow ((n+nd), nl, carryin)
+#define BnSubtract(m, md, ml, n, nd, nl, carryin)      BnnSubtract ((m+md), ml, (n+nd), nl, carryin)
+#define BnMultiplyDigit(p, pd, pl, m, md, ml, n, nd)   BnnMultiplyDigit ((p+pd), pl, (m+md), ml, *(n+nd))
+#define BnDivideDigit(q, qd, r, rd, n, nd, nl, d, dd)  *(r+rd) = BnnDivideDigit ((q+qd), (n+nd), nl, *(d+dd))
+
+
+               /* old functions of Bn */
+
+/*
+ *     Creation and access to type and length fields.
+ */
+extern char *malloc();
+/* Allocates a BigNum structure and returns a pointer to it */
+BigNum BnAlloc(size) int size; {
+       register BigNum n;
+       n = (BigNum) (malloc(sizeof(struct BigNumHeader) +
+                               size * sizeof(BigNumDigit))
+                       + sizeof(struct BigNumHeader));
+       BN_LENGTH(n) = size;
+       return(n);
+}
+/* Allocates a BigNum, inserts its Type, and returns a pointer to it */
+BigNum BnCreate(type, size) BigNumType type; int size; {
+       register BigNum n;
+       n = BnAlloc(size);
+       BN_TYPE(n) = type;
+       BnSetToZero(n, 0, size);
+       return(n);
+}
+/* Frees a BigNum structure */
+BnFree(n) BigNum n; {
+       free(((struct BigNumHeader *) n) - 1);
+        return 1; 
+}
+/* Returns the BigNum's Type */
+BigNumType BnGetType(n) BigNum n; {
+        return(BN_TYPE(n));
+}
+/* Sets the BigNum's Type */
+BnSetType(n, type) BigNum n; BigNumType type; {
+        BN_TYPE(n) = type;
+}
+/* Returns the number of digits allocated for the BigNum */
+BnGetSize(n) BigNum n; {
+       return(BN_LENGTH(n));
+}
diff --git a/util/gdss/lib/crypto/crypto_util.c b/util/gdss/lib/crypto/crypto_util.c
new file mode 100644 (file)
index 0000000..a32711d
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#ifndef ultrix
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include <sys/types.h>
+#include "random.h"
+#include "BigNum.h"
+#include "BigRSA.h"
+#include "bigkeygen.h"
+
+/*
+ * InitDelegationKey.  Generate a new rsa key of desired bit length.
+ *                     If random number generator is not yet seeded,
+ *                     initialize with uncertainty from the principal
+ *                     prime.
+ */
+int InitDelegationKey(principal, delegation, bitlen)
+RSAKeyStorage *principal, *delegation;
+int bitlen;
+{
+    RNGState rng;
+    read_rng_state (&rng);
+    if ((rng.count)==0) initialize_rng_state (principal->p,32);
+    return(newRSAKey (delegation, bitlen));
+}
+
+/*
+ * Private2Public.  Remove private key stuff in a key storage block.
+ */
+int Private2Public (key)
+RSAKeyStorage *key;
+{
+       memset(key->p,0,PRIVATE_KEY_SIZE-PUBLIC_KEY_SIZE);
+       key->pl=key->ql=key->dpl=key->dql=0;
+}
+
+
+/* 
+ * initrandom - interactive random number initializer
+ *
+ * The following routine attempts to initialize the random number generator
+ * with a reasonable amount of uncertainty.  This is provided mostly by
+ * the user, with some additional time inputs from the system.
+ */
+int initrandom()
+{ 
+unsigned char bar[16];
+int seed ;
+char buffer[256], sphinx_ans[80];
+char *ptr=buffer, *env=NULL;
+int i;
+long tick = clock();
+struct timeval tv ;
+struct timezone tz ;
+int thischar , lastchar ;
+
+        memset(ptr,0,256);
+
+        gettimeofday(&tv, &tz);
+        memcpy(ptr,&tv,sizeof(struct timeval));
+        ptr += sizeof(struct timeval);
+/*
+        printf("\nRiddle of the Sphinx :\n\n");
+        printf("What creature is it, that in the morning goes on four feet,\n");
+        printf("at noon on two, and at night on three?\n\n");
+        fflush(stdout);
+        scanf("%s", sphinx_ans); gets(ptr);
+        if ((strcasecmp(sphinx_ans, "man") == 0) || (strcasecmp(sphinx_ans, "woman") == 0)) {
+          printf("\nCorrect!\n\n");
+        } else {
+          printf("\nWrong!  Please brush up on your Egyptian mythology.\n\n");
+        }
+*/
+        tick = clock();
+        memcpy(ptr,&tick,sizeof(long));
+        ptr += sizeof(long);
+        memcpy(ptr,&ptr,sizeof(char *));
+        ptr+=sizeof(char *);
+        gettimeofday(&tv, &tz);
+        memcpy(ptr,&tv,sizeof(struct timeval));
+        ptr += sizeof(struct timeval);
+        seed = sizeof(buffer) - (ptr - buffer) - sizeof(struct timeval);
+
+        printf("\nSome 'uncertainty' is needed to initialize  the  random");
+        printf("\nnumber generator to generate your long term key. Please");
+        printf("\nenter up to %d characters of text.  The quality of your key", seed);
+        printf("\ndepends upon how 'uncertain' this input is.  When you");
+        printf("\nthink you have entered enough text, enter two successive");
+        printf("\ncarriage returns.");
+        printf("\n\n");
+        fflush(stdout);
+
+        for( i = thischar = lastchar = 0;
+          (thischar=getchar())!= EOF,((thischar != '\n')||(lastchar != '\n')); i++) {
+              lastchar = thischar;
+              ptr[ i % seed ] += (unsigned char) thischar ;
+        } 
+
+        printf("\nThank you very much.\n");
+
+        gettimeofday(&tv, &tz);
+        memcpy(ptr,&tv,sizeof(struct timeval));
+
+        initialize_rng_state (buffer, sizeof(buffer));
+
+}
+
diff --git a/util/gdss/lib/crypto/dumphex.c b/util/gdss/lib/crypto/dumphex.c
new file mode 100644 (file)
index 0000000..a56b57f
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/* dumphex.c */
+#include <stdio.h>
+#include <ctype.h>
+
+#define CHARS_PER_LINE 16
+
+/*
+ * write out half-ASCII hex characters to a file
+ */
+
+int fdumphex (x,l,fp)
+int l;
+unsigned char * x;
+FILE *fp ;
+{
+    int i;
+    for(i=0;i<l;i++){
+       if ((i%CHARS_PER_LINE)==0)fprintf(fp,"\n");
+       fprintf(fp," %02x",*x++);
+       }
+    fprintf(fp,"\n");   
+}
+
+/*
+ * read in half-ASCII text, skipping whites, until EOF or non-hex encoded byte
+ * found, returning number of bytes read.
+ */
+int freadhex (x,l,fp)
+int l;
+unsigned char * x;
+FILE *fp ;
+{
+    int i,j;
+    for(i=0;fscanf(fp," %02x",&j);i++) *x++=j;
+    return (i);
+}
+
+
+int dumphex (x,l)
+int l;
+unsigned char * x;
+{
+    fdumphex(x,l,stdout);
+}
diff --git a/util/gdss/lib/crypto/endian.h b/util/gdss/lib/crypto/endian.h
new file mode 100644 (file)
index 0000000..ccb703b
--- /dev/null
@@ -0,0 +1,22 @@
+/* endian.h */
+/*
+ * Machine generated on Mon Jan 21 11:21:03 1991
+ */
+
+#ifndef SPHINX_ENDIAN
+
+/*
+ * Little endian machines are DEC/Intel like
+ * Big endian machines are IBM/SPARC/Motorola like
+ *
+ * This machine is little endian since the value of SPHINX_ENDIAN is 1
+ *
+ */
+
+
+#define SPHINX_ENDIAN 1
+
+
+#endif
+
+
diff --git a/util/gdss/lib/crypto/hashes.c b/util/gdss/lib/crypto/hashes.c
new file mode 100644 (file)
index 0000000..3631138
--- /dev/null
@@ -0,0 +1,709 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+/*
+ * CONTENTS:
+ *
+ *  This file contains RSA hash routines.
+ */
+#include <stdio.h>
+#include "endian.h"
+#include "hashes.h"
+
+
+/*
+ * This conditionally includes the BSAFE MD and MAC routines.  These
+ * are not used by Sphinx so usually this definition is commented out.
+ */
+/*
+#define INCLUDE_RSA_BSAFE_STUFF  1 
+*/
+
+#define TEMP_BUFSIZ 256
+
+/*
+ * Externally Callable Routines. All arguments are character pointers
+ * or integer lengths.
+ */
+
+void RSA_MD2();         /* RSA_MD2(input_buffer, length, hash_result) */
+void RSA_MD4();         /* RSA_MD4(input_buffer, length, hash_result) */
+#ifdef INCLUDE_RSA_BSAFE_STUFF  
+void RSA_MAC();         /* RSA_MAC(input_buffer, length, mac, output_length) */
+void RSA_MD();          /* RSA_MD(input_buffer, length, hash_result) */
+#endif
+
+\f
+/* 
+** **************************************************************************
+** md4.h -- Header file for implementation of MD4 Message Digest Algorithm **
+** Updated: 2/13/90 by Ronald L. Rivest                                    **
+** (C) 1990 RSA Data Security, Inc.                                        **
+** **************************************************************************
+*/
+/* MDstruct is the data structure for a message digest computation.
+*/
+typedef struct {
+  unsigned int buffer[4];    /* Holds 4-word result of MD computation */
+  unsigned char count[8];    /* Number of bits processed so far */
+  unsigned int done;         /* Nonzero means MD computation finished */
+} MDstruct, *MDptr;
+/* 
+** **************************************************************************
+** md4.c -- Implementation of MD4 Message Digest Algorithm                 **
+** Updated: 2/16/90 by Ronald L. Rivest                                    **
+** (C) 1990 RSA Data Security, Inc.                                        **
+** **************************************************************************
+*/
+/* 
+** To use MD4:
+**   -- Include md4.h in your program
+**   -- Declare an MDstruct MD to hold the state of the digest computation.
+**   -- Initialize MD using MDbegin(&MD)
+**   -- For each full block (64 bytes) X you wish to process, call
+**          MDupdate(&MD,X,512)
+**      (512 is the number of bits in a full block.)
+**   -- For the last block (less than 64 bytes) you wish to process,
+**          MDupdate(&MD,X,n)
+**      where n is the number of bits in the partial block. A partial
+**      block terminates the computation, so every MD computation should
+**      terminate by processing a partial block, even if it has n = 0.
+**   -- The message digest is available in MD.buffer[0] ... MD.buffer[3].
+**      (Least-significant byte of each word should be output first.)
+**   -- You can print out the digest using MDprint(&MD)
+*/
+/* Implementation notes:
+** This implementation assumes that ints are 32-bit quantities.
+** If the machine stores the least-significant byte of an int in the
+** least-addressed byte (eg., VAX and 8086), then LOWBYTEFIRST should be
+** set to TRUE.  Otherwise (eg., SUNS), LOWBYTEFIRST should be set to
+** FALSE.  Note that on machines with LOWBYTEFIRST FALSE the routine
+** MDupdate modifies has a side-effect on its input array (the order of bytes
+** in each word are reversed).  If this is undesired a call to MDreverse(X) can
+** reverse the bytes of X back into order after each call to MDupdate.
+*/
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#define TRUE  1
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#define FALSE 0
+
+#define LOWBYTEFIRST SPHINX_ENDIAN
+
+/* Compile-time declarations of MD4 ``magic constants''.
+*/
+#define I0  0x67452301       /* Initial values for MD buffer */
+#define I1  0xefcdab89
+#define I2  0x98badcfe
+#define I3  0x10325476
+#define C2  013240474631     /* round 2 constant = sqrt(2) in octal */
+#define C3  015666365641     /* round 3 constant = sqrt(3) in octal */
+/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
+** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
+** Table 2, page 660.
+*/
+#define fs1  3               /* round 1 shift amounts */
+#define fs2  7   
+#define fs3 11  
+#define fs4 19  
+#define gs1  3               /* round 2 shift amounts */
+#define gs2  5   
+#define gs3  9   
+#define gs4 13  
+#define hs1  3               /* round 3 shift amounts */
+#define hs2  9 
+#define hs3 11 
+#define hs4 15
+/* Compile-time macro declarations for MD4.
+** Note: The ``rot'' operator uses the variable ``tmp''.
+** It assumes tmp is declared as unsigned int, so that the >>
+** operator will shift in zeros rather than extending the sign bit.
+*/
+#define        f(X,Y,Z)             ((X&Y) | ((~X)&Z))
+#define        g(X,Y,Z)             ((X&Y) | (X&Z) | (Y&Z))
+#define h(X,Y,Z)             (X^Y^Z)
+#define rot(X,S)             (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+#define ff(A,B,C,D,i,s)      A = rot((A + f(B,C,D) + X[i]),s)
+#define gg(A,B,C,D,i,s)      A = rot((A + g(B,C,D) + X[i] + C2),s)
+#define hh(A,B,C,D,i,s)      A = rot((A + h(B,C,D) + X[i] + C3),s)
+\f
+/* MDprint(MDp)
+** Print message digest buffer MDp as 32 hexadecimal digits.
+** Order is from low-order byte of buffer[0] to high-order byte of buffer[3].
+** Each byte is printed with high-order hexadecimal digit first.
+** This is a user-callable routine.
+*/
+static void MDprint(MDp)
+MDptr MDp;
+{ int i,j;
+  for (i=0;i<4;i++)
+    for (j=0;j<32;j=j+8)
+      printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+}
+/* MDbegin(MDp)
+** Initialize message digest buffer MDp. 
+** This is a user-callable routine.
+*/
+static void MDbegin(MDp)
+MDptr MDp;
+{ int i;
+  MDp->buffer[0] = I0;  
+  MDp->buffer[1] = I1;  
+  MDp->buffer[2] = I2;  
+  MDp->buffer[3] = I3; 
+  for (i=0;i<8;i++) MDp->count[i] = 0;
+  MDp->done = 0;
+}
+/* MDreverse(X)
+** Reverse the byte-ordering of every int in X.
+** Assumes X is an array of 16 ints.
+** The macro revx reverses the byte-ordering of the next word of X.
+*/
+#define revx { t = (*X << 16) | (*X >> 16); \
+              *X++ = ((t & 0xFF00FF00) >> 8) | ((t & 0x00FF00FF) << 8); }
+static void MDreverse(X)
+unsigned int *X;
+{ register unsigned int t;
+  revx; revx; revx; revx; revx; revx; revx; revx;
+  revx; revx; revx; revx; revx; revx; revx; revx;
+}
+\f
+/* MDblock(MDp,X)
+** Update message digest buffer MDp->buffer using 16-word data block X.
+** Assumes all 16 words of X are full of data.
+** Does not update MDp->count.
+** This routine is not user-callable. 
+*/
+static void MDblock(MDp,X)
+MDptr MDp;
+unsigned int *X;
+{ 
+  register unsigned int tmp, A, B, C, D;
+#if LOWBYTEFIRST == FALSE
+  MDreverse(X);
+#endif
+  A = MDp->buffer[0];
+  B = MDp->buffer[1];
+  C = MDp->buffer[2];
+  D = MDp->buffer[3];
+  /* Update the message digest buffer */
+  ff(A , B , C , D ,  0 , fs1); /* Round 1 */
+  ff(D , A , B , C ,  1 , fs2); 
+  ff(C , D , A , B ,  2 , fs3); 
+  ff(B , C , D , A ,  3 , fs4); 
+  ff(A , B , C , D ,  4 , fs1); 
+  ff(D , A , B , C ,  5 , fs2); 
+  ff(C , D , A , B ,  6 , fs3); 
+  ff(B , C , D , A ,  7 , fs4); 
+  ff(A , B , C , D ,  8 , fs1); 
+  ff(D , A , B , C ,  9 , fs2); 
+  ff(C , D , A , B , 10 , fs3); 
+  ff(B , C , D , A , 11 , fs4); 
+  ff(A , B , C , D , 12 , fs1); 
+  ff(D , A , B , C , 13 , fs2); 
+  ff(C , D , A , B , 14 , fs3); 
+  ff(B , C , D , A , 15 , fs4); 
+  gg(A , B , C , D ,  0 , gs1); /* Round 2 */
+  gg(D , A , B , C ,  4 , gs2); 
+  gg(C , D , A , B ,  8 , gs3); 
+  gg(B , C , D , A , 12 , gs4); 
+  gg(A , B , C , D ,  1 , gs1); 
+  gg(D , A , B , C ,  5 , gs2); 
+  gg(C , D , A , B ,  9 , gs3); 
+  gg(B , C , D , A , 13 , gs4); 
+  gg(A , B , C , D ,  2 , gs1); 
+  gg(D , A , B , C ,  6 , gs2); 
+  gg(C , D , A , B , 10 , gs3); 
+  gg(B , C , D , A , 14 , gs4); 
+  gg(A , B , C , D ,  3 , gs1); 
+  gg(D , A , B , C ,  7 , gs2); 
+  gg(C , D , A , B , 11 , gs3); 
+  gg(B , C , D , A , 15 , gs4);  
+  hh(A , B , C , D ,  0 , hs1); /* Round 3 */
+  hh(D , A , B , C ,  8 , hs2); 
+  hh(C , D , A , B ,  4 , hs3); 
+  hh(B , C , D , A , 12 , hs4); 
+  hh(A , B , C , D ,  2 , hs1); 
+  hh(D , A , B , C , 10 , hs2); 
+  hh(C , D , A , B ,  6 , hs3); 
+  hh(B , C , D , A , 14 , hs4); 
+  hh(A , B , C , D ,  1 , hs1); 
+  hh(D , A , B , C ,  9 , hs2); 
+  hh(C , D , A , B ,  5 , hs3); 
+  hh(B , C , D , A , 13 , hs4); 
+  hh(A , B , C , D ,  3 , hs1); 
+  hh(D , A , B , C , 11 , hs2); 
+  hh(C , D , A , B ,  7 , hs3); 
+  hh(B , C , D , A , 15 , hs4);
+  MDp->buffer[0] += A; 
+  MDp->buffer[1] += B;
+  MDp->buffer[2] += C;
+  MDp->buffer[3] += D; 
+}
+\f
+/* MDupdate(MDp,X,count)
+** Input: MDp -- an MDptr
+**        X -- a pointer to an array of unsigned characters.
+**        count -- the number of bits of X to use.
+**                 (if not a multiple of 8, uses high bits of last byte.)
+** Update MDp using the number of bits of X given by count.
+** This is the basic input routine for an MD4 user.
+** The routine completes the MD computation when count < 512, so
+** every MD computation should end with one call to MDupdate with a
+** count less than 512.  A call with count 0 will be ignored if the
+** MD has already been terminated (done != 0), so an extra call with count
+** 0 can be given as a ``courtesy close'' to force termination if desired.
+*/
+static int MDupdate(MDp,X,count)
+MDptr MDp;
+unsigned char *X;
+unsigned int count;
+{ unsigned int i, tmp, bit, byte, mask;
+  unsigned char XX[64];
+  unsigned char *p;
+  /* return with no error if this is a courtesy close with count
+  ** zero and MDp->done is true.
+  */
+  if (count == 0 && MDp->done) return(1);
+  /* check to see if MD is already done and report error */
+  if (MDp->done) { 
+#ifdef DEBUG
+        printf("\nError: MDupdate MD already done."); 
+#endif        
+                        return(0); }
+  /* Add count to MDp->count */
+  tmp = count;
+  p = MDp->count;
+  while (tmp)
+    { tmp += *p;
+      *p++ = tmp;
+      tmp = tmp >> 8;
+    }
+  /* Process data */
+  if (count == 512) 
+    { /* Full block of data to handle */
+      MDblock(MDp,(unsigned int *)X);
+    }
+  else if (count > 512) /* Check for count too large */
+    { 
+#ifdef DEBUG
+printf("\nError: MDupdate called with illegal count value %d.",count);
+#endif
+      return(0);
+    }
+  else /* partial block -- must be last block so finish up */
+    { /* Find out how many bytes and residual bits there are */
+      byte = count >> 3;
+      bit =  count & 7;
+      /* Copy X into XX since we need to modify it */
+      for (i=0;i<=byte;i++)   XX[i] = X[i];
+      for (i=byte+1;i<64;i++) XX[i] = 0;
+      /* Add padding '1' bit and low-order zeros in last byte */
+      mask = 1 << (7 - bit);
+      XX[byte] = (XX[byte] | mask) & ~( mask - 1);
+      /* If room for bit count, finish up with this block */
+      if (byte <= 55)
+       { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
+         MDblock(MDp,(unsigned int *)XX);
+       }
+      else /* need to do two blocks to finish up */
+       { MDblock(MDp,(unsigned int *)XX);
+         for (i=0;i<56;i++) XX[i] = 0;
+         for (i=0;i<8;i++)  XX[56+i] = MDp->count[i];
+         MDblock(MDp,(unsigned int *)XX);
+       }
+      /* Set flag saying we're done with MD computation */
+      MDp->done = 1;
+    }
+  return(1);
+}
+/* 
+** End of md4.c
+*/
+
+
+\f
+/*
+ * MD4
+ */
+void RSA_MD4 (inbuf, isize, digest)
+char * inbuf, * digest ;
+int isize;
+{ unsigned int i;
+  MDstruct MD;
+  MDbegin(&MD);
+  for (i=0;i+64<=isize;i=i+64) MDupdate(&MD,inbuf+i,512);
+  MDupdate(&MD,inbuf+i,(isize-i)*8);
+  memcpy(digest,MD.buffer,16);
+}
+
+
+\f
+#ifdef INCLUDE_RSA_BSAFE_STUFF
+/* SUBSTITUTION TABLE BASED ON DIGITS OF PI -- SEE PISUBST.DOC */
+/* obtained from RSA, Inc. */
+static unsigned char _pisubst[256] = { 
+       189, 86,234,242,162,241,172, 42,176,147,209,156, 27, 51,253,208,
+        48,  4,182,220,125,223, 50, 75,247,203, 69,155, 49,187, 33, 90,
+        65,159,225,217, 74, 77,158,218,160,104, 44,195, 39, 95,128, 54,
+        62,238,251,149, 26,254,206,168, 52,169, 19,240,166, 63,216, 12,
+       120, 36,175, 35, 82,193,103, 23,245,102,144,231,232,  7,184, 96,
+        72,230, 30, 83,243,146,164,114,140,  8, 21,110,134,  0,132,250,
+       244,127,138, 66, 25,246,219,205, 20,141, 80, 18,186, 60,  6, 78,
+       236,179, 53, 17,161,136,142, 43,148,153,183,113,116,211,228,191,
+        58,222,150, 14,188, 10,237,119,252, 55,107,  3,121,137, 98,198,
+       215,192,210,124,106,139, 34,163, 91,  5, 93,  2,117,213, 97,227,
+        24,143, 85, 81,173, 31, 11, 94,133,229,194, 87, 99,202, 61,108,
+       180,197,204,112,178,145, 89, 13, 71, 32,200, 79, 88,224,  1,226,
+        22, 56,196,111, 59, 15,101, 70,190,126, 45,123,130,249, 64,181,
+        29,115,248,235, 38,199,135,151, 37, 84,177, 40,170,152,157,165,
+       100,109,122,212, 16,129, 68,239, 73,214,174, 46,221,118, 92, 47,
+       167, 28,201,  9,105,154,131,207, 41, 57,185,233, 76,255, 67,171
+ };
+
+/* The table PS given below is a permutation of 0...255 constructed    */
+/*  from the digits of pi.  It is a ``random'' nonlinear byte         */
+/*  substitution operation.                                           */
+static unsigned char PS[256] = {
+        41, 46, 67,201,162,216,124,  1, 61, 54, 84,161,236,240,  6, 19,
+        98,167,  5,243,192,199,115,140,152,147, 43,217,188, 76,130,202,
+        30,155, 87, 60,253,212,224, 22,103, 66,111, 24,138, 23,229, 18,
+       190, 78,196,214,218,158,222, 73,160,251,245,142,187, 47,238,122,
+       169,104,121,145, 21,178,  7, 63,148,194, 16,137, 11, 34, 95, 33,
+       128,127, 93,154, 90,144, 50, 39, 53, 62,204,231,191,247,151,  3,
+       255, 25, 48,179, 72,165,181,209,215, 94,146, 42,172, 86,170,198,
+        79,184, 56,210,150,164,125,182,118,252,107,226,156,116,  4,241,
+        69,157,112, 89,100,113,135, 32,134, 91,207,101,230, 45,168,  2,
+        27, 96, 37,173,174,176,185,246, 28, 70, 97,105, 52, 64,126, 15,
+        85, 71,163, 35,221, 81,175, 58,195, 92,249,206,186,197,234, 38,
+        44, 83, 13,110,133, 40,132,  9,211,223,205,244, 65,129, 77, 82,
+       106,220, 55,200,108,193,171,250, 36,225,123,  8, 12,189,177, 74,
+       120,136,149,139,227, 99,232,109,233,203,213,254, 59,  0, 29, 57,
+       242,239,183, 14,102, 88,208,228,166,119,114,248,235,117, 75, 10,
+        49, 68, 80,180,143,237, 31, 26,219,153,141, 51,159, 17,131, 20,
+};
+
+\f
+/*
+ *                     R S A _ m a c
+ *
+ *     Compute a message authentication code (MAC) over the specified
+ *     buffer.  This uses the RSADSI MAC algorithm.
+ *
+ * Inputs:
+ *     inbuf   - Pointer to the input buffer
+ *     isize   - Size of the input buffer
+ *     macsize - Number of bytes desired in MAC
+ *
+ * Outputs:
+ *     mac     - Pointer to the resultant message authentication code buffer
+ *
+ * Return Value:
+ */
+void RSA_MAC(inbuf, isize, mac, macsize)
+unsigned char * inbuf, * mac ;
+int isize, macsize ;
+{
+       int i;
+       unsigned char temp;
+       memset(mac, 0, macsize);  /* initialize the mac buffer */
+       macsize--;                /* change to index */
+       /*
+        * Run over the input buffer merging each byte into the MAC.
+        */
+       for (i = 0; i < isize; i++)
+       {
+               temp = _pisubst[mac[0] ^ mac[1]];
+               /*
+                * Shift down the MAC one place and merge the new value into
+                * the last place.
+                */
+#ifdef VAX
+               memcpy(&mac[0],&mac[1], macsize);
+#else
+               memmove(&mac[0],&mac[1], macsize);
+#endif
+               mac[macsize] = temp ^ *inbuf++;
+       }
+}
+
+
+\f
+/*
+ *                           R S A _ M D
+ *
+ *     Compute a message digest over the specified buffer using the
+ *     RSA, Inc., message digest "MD" algorithm.
+ *
+ * Inputs:
+ *     inbuf   - Pointer to the input buffer
+ *     isize   - Size of the input buffer 
+ *
+ * Outputs:
+ *     digest  - Pointer to the resultant digest buffer. Assumed to be
+ *               16 bytes.
+ *
+ */
+
+void RSA_MD (inbuf, isize, digest )
+char * inbuf, * digest ;
+int isize;
+{
+       register int            i,
+                               j,
+                               k,
+                               l;
+       static int              padlen;
+       static unsigned char    lastmac ,
+                               x,
+                               t,
+                               buf[48],
+                               mac[16];
+    
+
+       memset(digest, 0, MD_BLOCK_SIZE);  /* initialize return digest */
+       memset(buf, 0, sizeof(buf)); /* initialize temporaries */
+       memset(mac, 0, sizeof(mac));
+    
+       for (i = 0, k = 0 , lastmac = 0 ; i < isize ; i++)
+       {
+               /*
+                * Merge the new character into the buffer and 
+                * update the MAC.
+                */
+               buf[k + 16] = *inbuf;
+               buf[k + 32] = *inbuf ^ buf[k];
+               lastmac = (mac[k] ^= PS[(*inbuf++ ^ lastmac) & 0xFF]);
+               
+               k = (k + 1) & 15;
+               /*
+                * Encrypt at the end of each block.
+                */
+               if (k==0){
+                 t = 0;
+                 for (l = 0; l < 18; l++)
+                    for (j = 48; j > 0; j--)
+                        t = (buf[48 - j] ^= PS[(t + j) & 0xFF]);
+               }
+       }
+
+       padlen = MD_BLOCK_SIZE - k;
+       x = (unsigned char) padlen ;
+
+       for (i = 0; i < padlen ; i++)
+       {
+               buf[k + 16] = x ;
+               buf[k + 32] = x ^ buf[k];
+               lastmac = (mac[k] ^= PS[(x ^ lastmac) & 0xFF]);
+
+               k = (k + 1) & 15;
+               /*
+                * Encrypt 
+                */
+               if (k==0){
+                 t = 0;
+                 for (l = 0; l < 18; l++)
+                    for (j = 48; j > 0; j--)
+                        t = (buf[48 - j] ^= PS[(t + j) & 0xFF]);
+               }
+       }
+
+       /*
+        * Now merge the MAC computed above into the message digest value.
+        */
+       for (i = 0; i < 16; i++)
+       {
+               buf[i + 16] = mac[i];
+               buf[i + 32] = mac[i] ^ buf[i];
+       }
+       t = 0;
+       for (i = 0; i < 18; i++)
+       {
+               for (j = 48; j > 0; j--)
+               {
+                       t = (buf[48 - j] ^= PS[(t + j) & 0xFF]);
+               }
+       }
+    
+       /*
+        * Now copy the final digest value to the output.
+        */
+       memcpy(digest, buf, MD_BLOCK_SIZE);
+
+}
+
+#endif /* INCLUDE_RSA_BSAFE_STUFF */
+
+
+
+
+/* RSA-MD2 Message Digest algorithm in C  */
+/*  by Ronald L. Rivest 10/1/88  */
+
+/**********************************************************************/
+/* Message digest routines:                                           */
+/* To form the message digest for a message M                         */
+/*    (1) Initialize a context buffer md using MDINIT                 */
+/*    (2) Call MDUPDATE on md and each character of M in turn         */
+/*    (3) Call MDFINAL on md                                          */
+/* The message digest is now in md->D[0...15]                         */
+/**********************************************************************/
+/* An MDCTX structure is a context buffer for a message digest        */
+/*  computation; it holds the current "state" of a message digest     */
+/*  computation                                                       */
+struct MDCTX
+{
+   unsigned char  D[48];   /* buffer for forming digest in */
+                           /* At the end, D[0...15] form the message */
+                           /*  digest */
+   unsigned char  C[16];   /* checksum register */
+   unsigned char  i;       /* number of bytes handled, modulo 16 */
+   unsigned char  L;       /* last checksum char saved */
+};
+/* The table S given below is a permutation of 0...255 constructed    */
+/*  from the digits of pi.  It is a ``random'' nonlinear byte         */
+/*  substitution operation.                                           */
+int S[256] = {
+        41, 46, 67,201,162,216,124,  1, 61, 54, 84,161,236,240,  6, 19,
+        98,167,  5,243,192,199,115,140,152,147, 43,217,188, 76,130,202,
+        30,155, 87, 60,253,212,224, 22,103, 66,111, 24,138, 23,229, 18,
+       190, 78,196,214,218,158,222, 73,160,251,245,142,187, 47,238,122,
+       169,104,121,145, 21,178,  7, 63,148,194, 16,137, 11, 34, 95, 33,
+       128,127, 93,154, 90,144, 50, 39, 53, 62,204,231,191,247,151,  3,
+       255, 25, 48,179, 72,165,181,209,215, 94,146, 42,172, 86,170,198,
+        79,184, 56,210,150,164,125,182,118,252,107,226,156,116,  4,241,
+        69,157,112, 89,100,113,135, 32,134, 91,207,101,230, 45,168,  2,
+        27, 96, 37,173,174,176,185,246, 28, 70, 97,105, 52, 64,126, 15,
+        85, 71,163, 35,221, 81,175, 58,195, 92,249,206,186,197,234, 38,
+        44, 83, 13,110,133, 40,132,  9,211,223,205,244, 65,129, 77, 82,
+       106,220, 55,200,108,193,171,250, 36,225,123,  8, 12,189,177, 74,
+       120,136,149,139,227, 99,232,109,233,203,213,254, 59,  0, 29, 57,
+       242,239,183, 14,102, 88,208,228,166,119,114,248,235,117, 75, 10,
+        49, 68, 80,180,143,237, 31, 26,219,153,141, 51,159, 17,131, 20,
+};
+/*The routine MDINIT initializes the message digest context buffer md.*/
+/* All fields are set to zero.                                        */
+void MDINIT(md)
+  struct MDCTX *md;
+  { int i;
+    for (i=0;i<16;i++) md->D[i] = md->C[i] = 0;
+    md->i = 0;
+    md->L = 0;
+  }
+/* The routine MDUPDATE updates the message digest context buffer to  */
+/*  account for the presence of the character c in the message whose  */
+/*  digest is being computed.  This routine will be called for each   */
+/*   message byte in turn.                                            */
+void MDUPDATE(md,c)
+  struct MDCTX *md;
+  unsigned char c;
+  { register unsigned char i,j,t,*p;
+    /**** Put i in a local register for efficiency ****/
+       i = md->i;
+    /**** Add new character to buffer ****/
+       md->D[16+i] = c;
+       md->D[32+i] = c ^ md->D[i];
+    /**** Update checksum register C and value L ****/
+       md->L = (md->C[i] ^= S[0xFF & (c ^ md->L)]);
+    /**** Increment md->i by one modulo 16 ****/
+       i = md->i = (i + 1) & 15;
+    /**** Transform D if i=0 ****/
+       if (i == 0)
+         { t = 0;
+           for (j=0;j<18;j++)
+             {/*The following is a more efficient version of the loop:*/
+               /*  for (i=0;i<48;i++) t = md->D[i] = md->D[i] ^ S[t]; */
+               p = md->D;
+               for (i=0;i<8;i++)
+                 { t = (*p++ ^= S[t]);
+                   t = (*p++ ^= S[t]);
+                   t = (*p++ ^= S[t]);
+                   t = (*p++ ^= S[t]);
+                   t = (*p++ ^= S[t]);
+                   t = (*p++ ^= S[t]);
+                 }
+               /* End of more efficient loop implementation */
+               t = t + j;
+             }
+         }
+  }
+/* The routine MDFINAL terminates the message digest computation and  */
+/* ends with the desired message digest being in md->D[0...15].       */
+void MDFINAL(md)
+  struct MDCTX *md;
+  { int i,padlen;
+    /* pad out to multiple of 16 */
+       padlen  = 16 - (md->i);
+       for (i=0;i<padlen;i++) MDUPDATE(md,(unsigned char)padlen);
+    /* extend with checksum */
+    /* Note that although md->C is modified by MDUPDATE, character    */
+    /* md->C[i] is modified after it has been passed to MDUPDATE, so  */
+    /* the net effect is the same as if md->C were not being modified.*/
+    for (i=0;i<16;i++) MDUPDATE(md,md->C[i]);
+  }
+
+/**********************************************************************/
+/* End of message digest implementation                               */
+/**********************************************************************/
+
+void RSA_MD2 (inbuf, isize, digest )
+char * inbuf, * digest ;
+int isize;
+{
+       struct MDCTX temp ;
+       int i;
+
+       MDINIT(&temp);
+       for(i=0;i<isize;i++) MDUPDATE(&temp,*inbuf++);
+       MDFINAL(&temp);
+       memcpy(digest,temp.D,16);
+}
diff --git a/util/gdss/lib/crypto/read_password.c b/util/gdss/lib/crypto/read_password.c
new file mode 100644 (file)
index 0000000..f61fb00
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include "hashes.h"
+#include <stdio.h>
+
+int MIN_PASSWORD_LENGTH = 6 ;
+
+
+#define TEMP_BUFSIZ 256
+
+static unsigned char scramble_key [8] = { 0x01, 0x23, 0x45, 0x67, 
+               0x89, 0xab, 0xcd, 0xef };
+
+char *getpassword();
+
+\f
+/*
+ * Password hashing routine number 1.  This is stored with the encrypted
+ * private key in the LEAF database.  Result is an 8 byte quantity.
+ */
+
+int H1(username, pw, hash)
+char *username, *pw, *hash ;
+{
+    char temp[TEMP_BUFSIZ];
+    char md2_hash [16];
+
+    temp[0] = '\0';
+    
+    if (2 + (username?strlen(username):0) + strlen(pw) > sizeof(temp)) return(0);
+    
+    if (username) strcat(temp,username);
+    strcat(temp,pw);
+
+    RSA_MD2 (temp, strlen(temp), md2_hash);
+    memcpy(hash, md2_hash, 8);
+
+    memset(temp,0,sizeof(temp));    
+    memset(md2_hash,0,sizeof(md2_hash));    
+
+    return(1);
+}
+
+
+\f
+/*
+ * Password hashing routine number 2.  This is the key used to encrypt 
+ * the private key.
+ */
+
+int H2(username, pw, hash)
+char *username, *pw, *hash ;
+{
+    char temp[TEMP_BUFSIZ];
+
+    if (2 + (username?strlen(username):0) + strlen(pw) > sizeof(temp)) return(0);
+    
+    temp[0] = '\0';
+    if (username) strcat(temp,username);
+    strcat(temp,pw);
+    
+    DES_X9_MAC (scramble_key, temp, strlen(temp), hash);
+
+    memset(temp,0,sizeof(temp));    
+
+    return(1);
+}
+
+\f
+/*
+ * Read password.  Returns a DES key.
+ */
+
+int DES_read_password(k,prompt,verify)
+char *prompt, *k;
+int verify;                             /* non-zero means prompt twice for password */
+{
+    char *pw = getpassword(prompt);
+    char *env = NULL;
+    int ret = 0;
+
+    if ((verify) && (strlen(pw) < MIN_PASSWORD_LENGTH)) {
+        printf("Length error, (must be at least %d char) please re-enter: ", MIN_PASSWORD_LENGTH);
+        fflush(stdout);
+        pw = getpassword("");
+        if (strlen(pw) < MIN_PASSWORD_LENGTH) {
+            printf("Password length error. \n");
+            goto cleanup;
+        }
+    }        
+
+    if (verify) {
+        char pwcpy[80];
+        strcpy(pwcpy,pw);
+        printf("Verifying, please re-enter: ");
+        fflush(stdout);
+        pw = getpassword("");
+        if (verify = strcmp(pwcpy,pw)) {
+                printf("\nVerification Error\n");
+                memset(pwcpy,0,strlen(pwcpy));
+                goto cleanup;
+                }
+        memset(pwcpy,0,strlen(pwcpy));
+    }
+
+done:
+    ret = H2(0,pw,k);
+
+cleanup:
+    memset(pw,0,strlen(pw));
+    return(ret);
+}
+
+
+int DES_read_password_hash(H2hash,H1hash,username,prompt,verify)
+char *prompt, *H2hash, *username, *H1hash;
+int verify;                             /* non-zero means prompt twice for password */
+{
+
+    char *pw = getpassword(prompt);
+    char *env = NULL;
+    int ret = 0;
+
+    if ((verify) && (strlen(pw) < MIN_PASSWORD_LENGTH)) {
+        printf("Length error, (must be at least %d char) please re-enter: ", MIN_PASSWORD_LENGTH);
+        fflush(stdout);
+        pw = getpassword("");
+        if (strlen(pw) < MIN_PASSWORD_LENGTH) {
+            printf("Password length error. \n");
+            goto cleanup;
+        }
+    }        
+
+    if (verify) {
+        char pwcpy[80];
+        strcpy(pwcpy,pw);
+        printf("Verifying, please re-enter: ");
+        fflush(stdout);
+        pw = getpassword("");
+        if (verify = strcmp(pwcpy,pw)) {
+                printf("\nVerification Error\n");
+                memset(pwcpy,0,strlen(pwcpy));
+                goto cleanup;
+                }
+        memset(pwcpy,0,strlen(pwcpy));
+    }
+
+done:
+    H1(username,pw,H1hash);
+    H2(0,pw,H2hash);
+    ret = 1;
+
+cleanup:
+    memset(pw,0,strlen(pw));
+    return(ret);
+}
+
diff --git a/util/gdss/lib/crypto/read_privkey.c b/util/gdss/lib/crypto/read_privkey.c
new file mode 100644 (file)
index 0000000..55c19b5
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "BigNum.h"
+#include "BigRSA.h"
+#include "random.h"
+#include "hashes.h"
+#include "read_password.h"
+
+#define MAX_NAME 80
+#define MAX_UID 80
+#define MAX_KEY 2048
+#define MAX_HASH 8
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+int read_privkey_messages =0;
+RSAKeyStorage RSAKeys ;
+
+int read_privkey_verbose(filename,name,uid,uid_len,hashkey,key)
+char *filename, *name, *hashkey;
+unsigned char *uid;
+int *uid_len;
+RSAKeyStorage *key;
+{
+int save = read_privkey_messages ,x;
+  read_privkey_messages = 1;
+  x=read_privkey (filename,name,uid,uid_len,hashkey,key);
+  read_privkey_messages = save;
+  return(x);
+}
+
+int read_privkey(filename,name,uid,uid_len,hashkey,key)
+char *filename, *name, *hashkey;
+unsigned char *uid;
+int *uid_len;
+RSAKeyStorage *key;
+{
+        static unsigned char buffer [MAX_KEY];
+        DESblock pwkey ;
+        char *ptr;
+        unsigned char *uptr;
+        int i,j,c;
+        FILE *fp;
+        char tempname[80], prompt[80];
+
+        strcpy(tempname,filename);
+        strcat(tempname,"_privkey");
+
+        if((fp=fopen(tempname,"r"))==NULL) {
+                if (read_privkey_messages) 
+                        printf("\n%s: Can't open file %s.\n", __FILE__,tempname);
+               return(0);
+        }
+
+        ptr=name;
+        for(i=0,j=0;i<MAX_NAME;i++) {
+        if((c=getc(fp))==EOF) {
+                if (read_privkey_messages) 
+                        printf("\n%s: Unexpected end of file %s.\n",__FILE__,tempname);
+               return(0);
+            }
+        switch (*ptr++ = (char) c){
+           case '{': j++; 
+                     break;
+           case '}': j--;
+                     if(j==0) goto next;
+                     break;
+           case '\n': if(j==0) {ptr--; goto next;}
+                      break;
+          }
+        }      
+        next:
+        if(i>=MAX_NAME-1) {
+                if (read_privkey_messages) 
+                        printf("\n%s: Issuer name too long.\n", __FILE__);
+               return(0);
+        }
+        *ptr='\0';
+
+#ifdef DEBUG
+printf("\n%s: issuer name= %s",__FILE__,name);
+#endif
+
+        uptr=uid;
+        for(i=0;i<MAX_UID;i++)
+               if(fscanf(fp,"%2x",&j)==1) *uptr++ =j; else break;
+        if(i==MAX_UID)return(0);
+
+        *uid_len = i;
+        
+#ifdef DEBUG
+printf("\n%s: uid is ",__FILE__);
+dumphex(uid,i);
+#endif
+
+        while(getc(fp)!=';');
+        for(i=0;i<MAX_HASH;i++)
+               if(fscanf(fp,"%2x",&j)==1) hashkey[i]=j ;
+                       else break;
+#ifdef DEBUG
+printf("\n%s: Size of hash: %d\n", __FILE__,i);
+dumphex(hashkey,i);
+#endif
+        
+        /* next non-white must be a ';' */
+        do {j=getc(fp);}while(isspace(j));
+        if(j != ';'){
+                if(read_privkey_messages) printf("\n%s: Hash Overflow.\n",__FILE__);
+                return(0);
+        }
+
+        for(i=0;i<MAX_KEY;i++)
+               if(fscanf(fp,"%2x",&j)==1) buffer[i]=j ;
+                       else break;
+        if(i==MAX_KEY) return(0);
+#ifdef DEBUG
+printf("\n%s: Size of private key read: %d\n", __FILE__,i);
+dumphex(buffer,i);
+#endif
+       sprintf(prompt,"\nEnter %s's password: ", filename);
+       if (DES_read_password(&pwkey, prompt, 0) == 0) {
+            if (read_privkey_messages) printf("\n%s, Error entering password.\n",__FILE__);
+            return(0);
+        }
+
+        memset(key,0,sizeof(*key));
+        if (recover_private(&pwkey,buffer,i,key)==0) {
+               if (read_privkey_messages) printf("\nError recovering key.\n");
+               return(0);
+        }
+        
+#ifdef DEBUG
+printf("\n%s: Recovered Key: \n",__FILE__);
+PrintTestKey(key);
+#endif
+
+return(1);
+}
+
+
diff --git a/util/gdss/lib/crypto/read_pubkey.c b/util/gdss/lib/crypto/read_pubkey.c
new file mode 100644 (file)
index 0000000..d029994
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include "BigNum.h"
+#include "BigRSA.h"
+
+#define MAX_NAME 80
+#define MAX_UID 80
+#define MAX_KEY 2048
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+int read_pubkey_messages = 0;
+
+int read_pubkey_verbose (user,name,uid,uid_len,key)
+RSAKeyStorage *key;
+char *name;
+unsigned char *uid;
+int *uid_len;
+{
+int save = read_pubkey_messages, x;
+    read_pubkey_messages = 1;
+    x = read_pubkey (user,name,uid,uid_len,key);
+    read_pubkey_messages = save;
+    return(x);
+}
+
+int read_pubkey (user,name,uid,uid_len,key)
+RSAKeyStorage *key;
+char *user, *name;
+unsigned char *uid;
+int *uid_len;
+{
+        char tempname[80];
+        static unsigned char buffer [MAX_KEY];
+        char *ptr = name;
+        unsigned char *uptr = uid;
+        int i,j,c;
+        FILE *fp;
+
+        strcpy(tempname,user);
+        strcat(tempname,"_pubkey");
+        if((fp = fopen(tempname,"r")) == NULL) {
+              if (read_pubkey_messages)
+                printf("\n%s: can't open file %s.\n", __FILE__, tempname);
+                     return(0);
+        }
+
+        ptr=name;
+        for(i=0,j=0;i<MAX_NAME;i++) {
+        if((c=getc(fp))==EOF) {
+              if (read_pubkey_messages)
+               printf("\nUnexpected end of file %s.\n",tempname);
+             return(0);
+          }
+        switch (*ptr++ = (char)c){
+           case '{': j++;break;
+           case '}': j--; if (j==0) goto next; break;
+           case '\n': if(j==0){ptr--;goto next;} break;
+           }
+        }      
+        next:
+        if(i>=MAX_NAME-1) {
+                if (read_pubkey_messages)
+                    printf("\n%sIssuer name too long.\n", __FILE__);
+               return(0);
+        }
+        *ptr='\0';
+
+#ifdef DEBUG
+printf("\n%s: name is %s",__FILE__,name);
+#endif
+
+        uptr=uid;
+        for(i=0;i<MAX_UID;i++)
+               if(fscanf(fp,"%2x",&j)==1) *uptr++ =j; else break;
+        if(i==MAX_UID)return(0);
+
+        *uid_len = i;
+        
+#ifdef DEBUG
+printf("\n%s: uid is ", __FILE__);
+dumphex(uid,i);
+#endif
+
+        while(getc(fp)!=';');
+                for(i=0;i<MAX_KEY;i++)
+                       if(fscanf(fp,"%2x",&j)==1) buffer[i]=j ;
+                       else break;
+        if(i==MAX_KEY) {
+              if (read_pubkey_messages)
+                 printf("\n%s: Length error reading public key buffer.\n",__FILE__);
+              return(0);
+        }
+#ifdef DEBUG
+printf("\n%s: Size of public key read is %d\n", __FILE__,i);
+dumphex(buffer,i);
+#endif
+
+        if(i=DecodePublic(buffer,key)) {
+#ifdef DEBUG
+printf("\n%s: Recovered Key is\n",__FILE__);
+PrintTestKey(key);
+#endif
+                return(1);
+        }
+        else {
+              if (read_pubkey_messages) printf("\n%s: Key decode failed.\n",__FILE__);
+              return(0);
+        }                
+}
+
+
diff --git a/util/gdss/lib/crypto/testEncodeP.c b/util/gdss/lib/crypto/testEncodeP.c
new file mode 100644 (file)
index 0000000..55394c7
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "BigNum.h"
+#include "BigRSA.h"
+#include "random.h"
+#include "hashes.h"
+#include "read_password.h"
+#include "bigkeygen.h"
+#include "bigrsacode.h"
+
+#define MAX_NAME 80
+#define MAX_UID 80
+#define MAX_KEY 2048
+#define MAX_HASH 16
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static RSAKeyStorage keys ;
+static RSAKeyStorage public_key ;
+static RSAKeyStorage private_key ;
+
+main(argc,argv)
+int     argc;
+char    **argv;
+{
+    unsigned char *encodedP ;
+    char usernameBuf [50], uidBuf [50], x500NameBuf[50], hashkey[50];
+    int uid_len;
+    FILE *publ, *priv;
+
+    if (argc < 2)
+    {
+badargs:
+        printf("usage: %s name \n", argv[0]);
+        exit(1);
+    }
+
+    strcpy(usernameBuf, argv[1]);
+
+    memset(&keys,0,sizeof(keys));
+    
+    if (read_privkey (usernameBuf, x500NameBuf, uidBuf, &uid_len, hashkey, &private_key)) {
+        printf("\nPrivate key read.");
+        PrintTestKey(&private_key);
+    }
+    else {
+        printf("\nPrivate key read failed.\n");
+        exit(0);
+        }
+        
+    if (read_pubkey (usernameBuf, x500NameBuf, uidBuf, &uid_len, &public_key)){
+        printf("\nPublic key read.");
+        PrintTestKey(&public_key);
+    }
+
+    if ((encodedP=EncodePrivateP(&private_key))==0) {
+        printf("\nEncode private key failed.\n");
+        exit(0);
+        }
+
+    printf("\nEncoded private key (prime P only):\n");
+    dumphex(encodedP,DecodeTotalLength(encodedP));
+
+    printf("\nDecoding...\n");
+    
+    if ((DecodePrivate(encodedP, &public_key))==0) {
+        printf("\nDecode of private key failed.\n");
+        exit(0);
+        }
+    else {
+        printf("\nRecovered Private Key:\n");
+        PrintTestKey (&public_key);
+        }
+
+BnnClose();
+exit(0);
+}
+
+
+
+
+int read_privkey (filename,name,uid,uid_len,hashkey,key)
+char *filename, *name, *hashkey;
+unsigned char *uid;
+int *uid_len;
+RSAKeyStorage *key;
+{
+        static unsigned char buffer [MAX_KEY];
+        DESblock pwkey ;
+        char *ptr;
+        unsigned char *uptr;
+        int i,j,c;
+        FILE *fp;
+        char tempname[80];
+
+        strcpy(tempname,filename);
+        strcat(tempname,"_privkey");
+
+        if((fp=fopen(tempname,"r"))==NULL) {
+               printf("\nCan't open file %s.\n", tempname);
+               return(0);
+        }
+
+        ptr=name;
+        for(i=0,j=0;i<MAX_NAME;i++)
+        switch (*ptr++ =getc(fp)){
+           case '{': j++;break;
+           case '}': j--;if(j==0)goto next;break;
+           case EOF : {
+               printf("\nUnexpected end of file %s.\n",tempname);
+               return(0);
+          }
+        }      
+        next:
+        if(i>=MAX_NAME-1) {
+               printf("\nIssuer name too long.\n");
+               return(0);
+        }
+        *ptr='\0';
+
+#ifdef DEBUG
+printf("\nissuer name= %s",name);
+#endif
+
+        uptr=uid;
+        for(i=0;i<MAX_UID;i++)
+               if(fscanf(fp,"%2x",&j)==1) *uptr++ =j; else break;
+        if(i==MAX_UID)return(0);
+
+        *uid_len = i;
+        
+#ifdef DEBUG
+printf("\nuid=");
+dumphex(uid,i);
+#endif
+
+        while(getc(fp)!=';');
+                for(i=0;i<MAX_HASH;i++)
+                       if(fscanf(fp,"%2x",&j)==1) hashkey[i]=j ;
+                       else break;
+        if(i==MAX_HASH) return(0);
+#ifdef DEBUG
+printf("\nSize of hash: %d\n", i);
+dumphex(hashkey,i);
+#endif
+
+        while(getc(fp)!=';');
+                for(i=0;i<MAX_KEY;i++)
+                       if(fscanf(fp,"%2x",&j)==1) buffer[i]=j ;
+                       else break;
+        if(i==MAX_KEY) return(0);
+#ifdef DEBUG
+printf("\nSize of private key read: %d\n", i);
+dumphex(buffer,i);
+#endif
+
+       if (DES_read_password(&pwkey, "\nEnter Password: ", 0) == 0) {
+            printf("\nError entering password.\n");
+            return(0);
+        }
+
+        memset(key,0,sizeof(*key));
+        if (recover_private(&pwkey,buffer,i,key)==0) {
+               printf("\nError recovering key.\n");
+               return(0);
+        }
+        
+#ifdef DEBUG
+printf("\nRecovered Key: \n");
+PrintTestKey(key);
+#endif
+
+
+return(1);
+}
+
+
diff --git a/util/gdss/lib/crypto/testsignverify.c b/util/gdss/lib/crypto/testsignverify.c
new file mode 100644 (file)
index 0000000..f1d7b52
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include "bigsignverify.h"
+
+#define MAX_NAME 80
+#define MAX_UID 80
+#define MAX_KEY 2048
+#define MAX_HASH 16
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+RSAKeyStorage keys ;
+RSAKeyStorage public_key ;
+RSAKeyStorage private_key ;
+unsigned char bigbuf [2*DigitLim*sizeof(BigNumDigit)];
+unsigned char testdata[]="Now is the time for all good men to come to the aid";
+
+main(argc,argv)
+int     argc;
+char    **argv;
+{
+    char usernameBuf [50], uidBuf [50], x500NameBuf[50], hashkey[50];
+    int uid_len;
+    FILE *publ, *priv;
+    DESblock newkey1, newkey2;
+    int bigbuflen;
+    time_t expires1, expires2;
+
+    if (argc < 2)
+    {
+badargs:
+        printf("usage: %s name \n", argv[0]);
+        exit(1);
+    }
+
+    strcpy(usernameBuf, argv[1]);
+
+    memset(&keys,0,sizeof(keys));
+    
+    if (read_privkey (usernameBuf, x500NameBuf, uidBuf, &uid_len, hashkey, &private_key)) {
+        printf("\nPrivate key read.");
+        PrintTestKey(&private_key);
+    }
+    else {
+        printf("\nUnable to read private key for %s.\n", usernameBuf);
+        exit(0);
+        }
+        
+    if (read_pubkey (usernameBuf, x500NameBuf, uidBuf, &uid_len, &public_key)){
+        printf("\nPublic key read.");
+        PrintTestKey(&public_key);
+    }
+    else {
+        printf("\nUnable to read public key for %s.\n", usernameBuf);
+        exit(0);
+        }
+
+    if(!RSASign(testdata, sizeof(testdata), &private_key, bigbuf, &bigbuflen)) {
+        printf("\nError signing test data.\n");
+        exit(0);
+    }
+
+    printf("\nSigned Data:\n");
+    dumphex(bigbuf, bigbuflen);
+    
+    if(!RSAVerify(testdata, sizeof(testdata), &public_key, bigbuf, bigbuflen)) {
+        printf("\nError verifying signature.\n");
+        exit(0);
+    }
+    printf("\nSignature verifies.\n");
+
+    time(&expires1);
+    printf("\nCurrent time: %s", ctime(&expires1));
+    expires1 += (time_t) 60; /* one minute */
+    
+    InitAuthenticationKey ( &private_key, &public_key, &newkey1, bigbuf, 
+                                &bigbuflen, expires1);
+    
+    printf("\nNew generated key:\n");
+    dumphex(&newkey1, sizeof(DESblock));
+    printf("\nExpires %s", ctime(&expires1));
+    printf("\nEncrypted key (length %d):\n", bigbuflen);
+    dumphex(bigbuf, bigbuflen);
+
+    if (AcceptAuthenticationKey (&private_key, &newkey2, bigbuf, bigbuflen, &expires2)) {
+        printf("\nRecovered key:\n");
+        dumphex(&newkey1, sizeof(DESblock));
+        printf("\nExpires %s", ctime(&expires2));
+    }
+    else {
+        printf("\nRecovery of key failed.\n");
+    }
+
+exit(0);
+}
+
diff --git a/util/gdss/lib/crypto/write b/util/gdss/lib/crypto/write
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/util/gdss/lib/crypto/write_pubkey.c b/util/gdss/lib/crypto/write_pubkey.c
new file mode 100644 (file)
index 0000000..ee991d4
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
+ * ALL RIGHTS RESERVED
+ *
+ * "Digital Equipment Corporation authorizes the reproduction,
+ * distribution and modification of this software subject to the following
+ * restrictions:
+ * 
+ * 1.  Any partial or whole copy of this software, or any modification
+ * thereof, must include this copyright notice in its entirety.
+ *
+ * 2.  This software is supplied "as is" with no warranty of any kind,
+ * expressed or implied, for any purpose, including any warranty of fitness 
+ * or merchantibility.  DIGITAL assumes no responsibility for the use or
+ * reliability of this software, nor promises to provide any form of 
+ * support for it on any basis.
+ *
+ * 3.  Distribution of this software is authorized only if no profit or
+ * remuneration of any kind is received in exchange for such distribution.
+ * 
+ * 4.  This software produces public key authentication certificates
+ * bearing an expiration date established by DIGITAL and RSA Data
+ * Security, Inc.  It may cease to generate certificates after the expiration
+ * date.  Any modification of this software that changes or defeats
+ * the expiration date or its effect is unauthorized.
+ * 
+ * 5.  Software that will renew or extend the expiration date of
+ * authentication certificates produced by this software may be obtained
+ * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
+ * 94065, (415)595-8782, or from DIGITAL"
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "BigZ.h"
+#include "BigRSA.h"
+
+write_pubkey(keys,name,subject,uidBuf,uid_len)
+RSAKeyStorage *keys;
+int  uid_len;
+char *uidBuf, *name, *subject;
+{
+        char publicBuf [80], *tempbuf;
+        FILE *publ;
+        
+        strcpy(publicBuf,name);
+        strcat(publicBuf,"_pubkey");
+        
+        if ((publ = fopen(publicBuf, "w")) == NULL)
+        {
+            printf("\n%s: could not open/create %s", __FILE__, publicBuf);
+            return(0);
+        }
+        fprintf(publ, "%s", subject);
+       fdumphex(uidBuf, uid_len, publ);
+       fprintf(publ," ;");
+       if ((tempbuf = (char *)EncodePublic(keys))==NULL) {
+                printf("\n%s: Allocation Error.\n", __FILE__);
+                return(0);
+        }
+       fdumphex(tempbuf, DecodeTotalLength(tempbuf), publ);
+       FreePublic(tempbuf);
+       fprintf(publ," ;");
+        fclose(publ);
+}
diff --git a/util/gdss/lib/gdss.c b/util/gdss/lib/gdss.c
new file mode 100644 (file)
index 0000000..f724359
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ */
+/*
+ * GDSS The Generic Digital Signature Service
+ *
+ * gdss.c: Main interface routines
+ */
+
+#include <BigNum.h>
+#include <BigRSA.h>
+#include <krb.h>
+#include <gdss.h>
+#include <stdio.h>
+
+static RSAKeyStorage gdss_pubkey;
+static int gdss_have_key;
+static int pfetchkey();
+
+#ifdef notdef
+/* This function is obsolete */
+int GDSS_Sig_Info(Signature, aSigInfo)
+unsigned char *Signature;
+SigInfo *aSigInfo;
+{
+  int status;
+  static int pfetchkey();
+  unsigned char hash[16];
+  unsigned char *cp;
+
+  cp = aSigInfo->rawsig;
+  memset(aSigInfo, 0, sizeof(SigInfo));
+  aSigInfo->rawsig = cp;
+  aSigInfo->SigInfoVersion = 0;
+  do {
+    status = pfetchkey();
+    if (status) break;
+    status = gdss_rverify(Signature, hash, &(*aSigInfo).pname,
+                         &(*aSigInfo).pinst, &(*aSigInfo).prealm,
+                         &gdss_pubkey, &(*aSigInfo).timestamp,
+                         aSigInfo->rawsig);
+  } while(0);
+  return (status);
+}
+#endif
+
+int GDSS_Verify(Data, DataLen, Signature, aSigInfo)
+unsigned char *Data;
+unsigned int DataLen;
+unsigned char *Signature;
+SigInfo *aSigInfo;
+{
+  unsigned char hash[16];
+  SigInfo bSigInfo, *iSigInfo;
+  int status;
+  unsigned char *cp;
+
+  if (aSigInfo == NULL) {
+    iSigInfo = &bSigInfo;
+  } else {
+    iSigInfo = aSigInfo;
+  }
+  status = pfetchkey();
+  if (status) return (status);
+
+  memset(&bSigInfo, 0, sizeof(bSigInfo));
+  cp = iSigInfo->rawsig;
+  memset(iSigInfo, 0, sizeof(bSigInfo));
+  iSigInfo->rawsig = cp;
+
+  RSA_MD2(Data, DataLen, hash);
+
+  status = gdss_rverify(Signature, hash, iSigInfo->pname,
+                       iSigInfo->pinst, iSigInfo->prealm,
+                       &gdss_pubkey, &iSigInfo->timestamp, iSigInfo->rawsig);
+
+  if (status) return (status);
+  return (GDSS_SUCCESS);
+}
+
+int GDSS_Sig_Size()
+{
+  int status;
+  int retval;
+  status = pfetchkey();
+  if (status) retval = 512;    /* No provision for errors, so default value */
+  retval = sizeof(SigInfo) + (gdss_pubkey.nl)*4 + GDSS_PAD + 5;
+  return (retval);
+}
+
+static int pfetchkey()
+{
+  FILE *keyf;
+  unsigned char buffer[512];
+
+  if (gdss_have_key) return (0);
+  keyf = fopen("/etc/athena/gdss_public_key", "r");
+  if (keyf == NULL) {
+      keyf = fopen("/afs/net.mit.edu/system/config/gdss_public_key", "r");
+      if (keyf == NULL) return (GDSS_E_NOPUBKEY);
+  }
+  fread(buffer, 1, 512, keyf);
+  fclose(keyf);
+  DecodePublic(buffer, &gdss_pubkey);
+  gdss_have_key++;
+  return (GDSS_SUCCESS);
+}
+
+GDSS_Recompose(aSigInfo, signature)
+SigInfo *aSigInfo;
+unsigned char *signature;
+{
+  if (aSigInfo->rawsig == NULL) return (GDSS_E_BADINPUT);
+  return(gdss_recompose(aSigInfo, signature));
+}
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include <hesiod.h>
+
+static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0 };
+GDSS_Sign(Data, DataLen, Signature)
+unsigned char *Data;
+unsigned int DataLen;
+unsigned char *Signature;
+{
+  KTEXT_ST authent;
+  char lrealm[REALM_SZ];
+  char linst[INST_SZ];
+  char sinst[INST_SZ];
+  char *cp;
+  unsigned char hash[16];
+  unsigned char dhash[16];     /* Second level hash */
+  int s;                       /* Socket to do i/o on */
+  int status;
+  register int i;
+  unsigned int cksum;
+  unsigned char packet[2048];
+  int plen;
+  unsigned char ipacket[2048];
+  int iplen;
+  struct hostent *hp;
+  struct sockaddr_in sin, lsin;
+  fd_set readfds;
+  char **hostname;
+  int trys;
+  char *krb_get_phost();
+
+  memset(packet, 0, sizeof(packet)); /* Zeroize Memory */
+  memset(ipacket, 0, sizeof(ipacket));
+  krb_get_lrealm(lrealm, 1);   /* Get our Kerberos realm */
+
+  RSA_MD2(Data, DataLen, hash);
+  RSA_MD2(hash, 16, dhash);    /* For use of Kerberos */
+  memcpy(packet, hash, 16);
+
+  cksum = 0;
+  for (i = 0; i < 4; i++)      /* High order 32 bits of dhash is the
+                                  Kerberos checksum, I wish we could do
+                                  better, but this is all kerberos allows
+                                  us */
+    cksum = (cksum << 8) + dhash[i];
+
+  /* Use Hesiod to find service location of GDSS Server Here */
+
+  hostname = hes_resolve("gdss", "sloc");
+  if (hostname == NULL) return(-1); /* No hesiod available */
+
+  cp = krb_get_phost(*hostname);
+  if (cp == NULL) return (-1); /* Should use a better error code */
+
+  strcpy(sinst, cp);
+
+  hp = gethostbyname(*hostname);
+
+  if(hp == NULL) return (-1);  /* Could not find host, you lose */
+
+  memset(&sin, 0, sizeof(sin));
+  sin.sin_family = hp->h_addrtype;
+  memcpy(&sin.sin_addr, hp->h_addr, sizeof(hp->h_addr));
+  sin.sin_port = htons(7201);  /* Should get this from services or Hesiod */
+
+  strcpy(linst, "gdss");       /* Grrr... krb_mk_req bashes its input
+                                  So we better copy it first! */
+  status = krb_mk_req(&authent, linst, sinst, lrealm, cksum);
+  if (status != KSUCCESS) return (GDSS_E_KRBFAIL);
+  packet[0] = 0;               /* Version 0 of protocol */
+  memcpy(&packet[1], hash, 16);
+  memcpy(&packet[17], &authent, sizeof(authent));
+  plen = sizeof(authent) + 16 + 1;     /* KTEXT_ST plus the hash + version */
+
+  s = -1;                      /* "NULL" Value for socket */
+  do {
+    s = socket(AF_INET, SOCK_DGRAM, 0);
+    if (s < 0) {
+      status = GDSS_E_NOSOCKET;
+      break;
+    }
+    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+      status = GDSS_E_NOCONNECT;
+      break;
+    }
+    trys = 3;
+    status = GDSS_E_TIMEDOUT;
+    while (trys > 0) {
+      if(send(s, packet, plen, 0) < 0) break;
+      FD_ZERO(&readfds);
+      FD_SET(s, &readfds);
+      if ((select(s+1, &readfds, (fd_set *)0, (fd_set *)0, &timeout) < 1)
+         || !FD_ISSET(s, &readfds)) {
+       trys--;
+       continue;
+      }
+      if((iplen = recv(s, (char *)ipacket, 2048, 0)) < 0) break;
+      status = GDSS_SUCCESS;
+      break;
+    }
+  } while (0);
+  shutdown(s, 0);
+  close(s);
+  if (status != GDSS_SUCCESS) return (status);
+  memcpy(Signature, ipacket, iplen);
+  return (GDSS_SUCCESS);
+}
diff --git a/util/gdss/lib/rgdss.c b/util/gdss/lib/rgdss.c
new file mode 100644 (file)
index 0000000..10e3e06
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * $Source$
+ * $Author$
+ * $Header$
+ */
+/*
+ * GDSS The Generic Digital Signature Service
+ *
+ * rgdss.c: Raw signature signing and verification routines.
+ */
+
+#include <BigNum.h>
+#include <BigRSA.h>
+#include <krb.h>
+#include <gdss.h>
+#include <stdio.h>
+#include <time.h>
+
+int gdss_rsign(signature, hash, name, instance, realm, key)
+unsigned char *signature;
+unsigned char *hash;
+char *name;
+char *instance;
+char *realm;
+RSAKeyStorage *key;
+{
+  unsigned char *cp, *ip;
+  time_t the_time;
+  register int i;
+  register int status;
+  int loopcnt;
+  int siglen;
+
+  for (loopcnt = 0; loopcnt < 10; loopcnt++) {
+    cp = signature;
+    for (i = 0; i < 16; i++)
+      *cp++ = hash[i];
+    *cp++ = 0x44;   /* Version Number */
+    ip = (unsigned char *) name;
+    while (*cp++ = *ip++);
+    ip = (unsigned char *) instance;
+    while (*cp++ = *ip++);
+    ip = (unsigned char *) realm;
+    while (*cp++ = *ip++);
+    time(&the_time);
+    *cp++ = ((the_time) >> 24) & 0xff;
+    *cp++ = ((the_time) >> 16) & 0xff;
+    *cp++ = ((the_time) >> 8) & 0xff;
+    *cp++ = the_time & 0xff;
+    if(!RSASign(signature, cp - signature, key, &signature[cp - signature],
+               &siglen)) return (-1);
+    status = gdss_rpadout(&signature[16], cp - signature + siglen - 16);
+    if ((status == GDSS_SUCCESS) || (status != GDSS_E_PADTOOMANY)) {
+      ip = &signature[16];
+      cp = signature;
+      while (*cp++ = *ip++);   /* shuffle over hash */
+      return(GDSS_SUCCESS);
+    }
+    sleep(1);                  /* Allow time to change */
+  }
+  return (GDSS_E_PADTOOMANY);
+}
+
+/* gdss_rpadout: Remove null bytes from signature by replacing them with
+   the sequence GDSS_ESCAPE, GDSS_NULL. Keep track of how much bigger
+   the signature block is getting and abort if too many bytes (more than
+   GDSS_PAD) would be required.
+*/
+
+int gdss_rpadout(signature, siglen)
+unsigned char *signature;
+int siglen;
+{
+  register unsigned char *cp;
+  register unsigned char *bp;
+  unsigned char *buf;
+  register int i;
+  register int c;
+  buf = (unsigned char *)malloc(siglen + GDSS_PAD + 1); /* 1 for the null! */
+  if (buf == NULL) return (GDSS_E_ALLOC);
+  memset(buf, 0, siglen + GDSS_PAD + 1); /* Just to be safe */
+  bp = buf;
+  cp = signature;
+  c = 0;
+  for (i = 0; i < siglen; i++) {
+    if ((*cp != '\0') && (*cp != GDSS_ESCAPE)) {
+      *bp++ = *cp++;
+      continue;
+    }
+    if (c++ > GDSS_PAD) {
+      free(buf);               /* Don't have to zeroize, nothing
+                                  confidential */
+      return (GDSS_E_PADTOOMANY);
+    }
+    *bp++ = GDSS_ESCAPE;
+    *bp++ = (*cp == '\0') ? GDSS_NULL : GDSS_ESCAPE;
+    cp++;
+  }
+  *bp++ = '\0';                        /* Null Terminate */
+  memcpy(signature, buf, bp - buf);
+  free(buf);
+  return (GDSS_SUCCESS);
+}
+  
+int gdss_rpadin(signature, outlen)
+unsigned char *signature;
+int *outlen;
+{
+  unsigned char *buf;
+  register unsigned char *cp;
+  register unsigned char *bp;
+  buf = (unsigned char *) malloc(strlen(signature));
+  if (buf == NULL) return (GDSS_E_ALLOC);
+  bp = buf;
+  cp = signature;
+  while (*cp) {
+    if (*cp != GDSS_ESCAPE) {
+      *bp++ = *cp++;
+      continue;
+    }
+    if (*(++cp) == GDSS_NULL) {
+      *bp++ = '\0';
+    } else *bp++ = GDSS_ESCAPE;
+    if(!*cp++) break;
+  }
+  *outlen = bp - buf;
+  memcpy(signature, buf, *outlen);
+  free (buf);
+  return (GDSS_SUCCESS);
+}
+
+int gdss_rverify(isignature, hash, name, instance,
+                realm, key, the_time, rawsig)
+unsigned char *isignature;
+unsigned char *hash;
+char *name;
+char *instance;
+char *realm;
+RSAKeyStorage *key;
+unsigned int *the_time;
+unsigned char *rawsig;
+{
+  unsigned char *cp, *ip;
+  register int i;
+  int status;
+  int siglen;
+  unsigned char *signature;
+
+  if (*isignature != 0x44) return (GDSS_E_BVERSION); /* Bad Version */
+
+  signature = (unsigned char *) malloc (strlen(isignature) + 17);
+       /* Length of input signature + null byte + 16 bytes of hash */
+  strcpy(&signature[16], isignature);
+
+  status = gdss_rpadin(&signature[16], &siglen);
+  if (status) return (status);
+  
+  siglen += 16;                        /* Account for the hash */
+  cp = signature;
+  for (i = 0; i < 16; i++)
+    *cp++ = hash[i];
+  if (*cp++ != 0x44) return (GDSS_E_BVERSION); /* Bad Version */
+  ip = (unsigned char *) name;
+  while (*ip++ = *cp++);
+  ip = (unsigned char *) instance;
+  while (*ip++ = *cp++);
+  ip = (unsigned char *) realm;
+  while (*ip++ = *cp++);
+  *the_time = 0;
+  *the_time |= *cp++ << 24;
+  *the_time |= *cp++ << 16;
+  *the_time |= *cp++ << 8;
+  *the_time |= *cp++;
+  if(!RSAVerify(signature, cp - signature, key, &signature[cp - signature],
+               siglen - (cp - signature))) {
+    free (signature);
+    return (GDSS_E_BADSIG);
+  }
+  if (rawsig == NULL) {
+    free (signature);
+    return (GDSS_SUCCESS);
+  }
+  memcpy(rawsig, &signature[cp - signature], siglen - (cp - signature));
+  status = gdss_rpadout(rawsig, siglen - (cp - signature));
+  free (signature);
+  return (status);
+}
+    
+gdss_recompose(aSigInfo, signature)
+SigInfo *aSigInfo;
+unsigned char *signature;
+{
+  register unsigned char *ip;
+  register unsigned char *cp;
+  unsigned char *isignature;
+  int siglen;
+  int status;
+
+  isignature = (unsigned char *) malloc(strlen(aSigInfo->rawsig) + 1);
+  if (isignature == NULL) return (GDSS_E_ALLOC);
+  strcpy(isignature, aSigInfo->rawsig);
+  status = gdss_rpadin(isignature, &siglen);
+  if (status) {
+    free(isignature);
+    return (status);
+  }
+
+  cp = signature;
+  *cp++ = 0x44;                        /* Version */
+  ip = (unsigned char *) aSigInfo->pname;
+  while (*cp++ = *ip++);
+  ip = (unsigned char *) aSigInfo->pinst;
+  while (*cp++ = *ip++);
+  ip = (unsigned char *) aSigInfo->prealm;
+  while (*cp++ = *ip++);
+  *cp++ = ((aSigInfo->timestamp) >> 24) & 0xff;
+  *cp++ = ((aSigInfo->timestamp) >> 16) & 0xff;
+  *cp++ = ((aSigInfo->timestamp) >> 8) & 0xff;
+  *cp++ = aSigInfo->timestamp & 0xff;
+  memcpy(cp, isignature, siglen);
+  free(isignature);
+  return(gdss_rpadout(signature, cp - signature + siglen));
+}
This page took 2.298436 seconds and 5 git commands to generate.