Przeglądaj źródła

added libtomcrypt-0.96

Tom St Denis 21 lat temu
rodzic
commit
3fe312ccef
92 zmienionych plików z 3219 dodań i 4894 usunięć
  1. 0 38
      PLAN
  2. 191 96
      aes.c
  3. 8 0
      aes_tab.c
  4. 1 46
      base64_decode.c
  5. 63 0
      base64_encode.c
  6. 4 3
      cbc_decrypt.c
  7. 30 0
      cbc_getiv.c
  8. 28 0
      cbc_setiv.c
  9. 30 0
      cfb_getiv.c
  10. 39 0
      cfb_setiv.c
  11. 25 0
      changes
  12. 17 7
      crypt.c
  13. 0 88
      crypt.out
  14. BIN
      crypt.pdf
  15. 324 141
      crypt.tex
  16. 32 32
      crypt_hash_descriptor.c
  17. 30 0
      ctr_getiv.c
  18. 43 0
      ctr_setiv.c
  19. 1 1
      demos/small.c
  20. 3 363
      demos/test.c
  21. 0 1985
      demos/test.c~
  22. 20 0
      demos/test/base64_test.c
  23. 20 0
      demos/test/cipher_hash_test.c
  24. 87 0
      demos/test/dh_tests.c
  25. 51 0
      demos/test/dsa_test.c
  26. 89 0
      demos/test/ecc_test.c
  27. 12 0
      demos/test/mac_test.c
  28. 13 0
      demos/test/makefile
  29. 14 0
      demos/test/makefile.icc
  30. 14 0
      demos/test/makefile.msvc
  31. 112 0
      demos/test/modes_test.c
  32. 103 0
      demos/test/pkcs_1_test.c
  33. 91 0
      demos/test/rsa_test.c
  34. 43 0
      demos/test/store_test.c
  35. 177 0
      demos/test/test.c
  36. 29 0
      demos/test/test.h
  37. BIN
      doc/crypt.pdf
  38. 3 0
      ecb_decrypt.c
  39. 0 26
      error_to_string.c
  40. 0 305
      gf.c
  41. 0 862
      keyring.c
  42. 0 0
      ltc_tommath.h
  43. 42 60
      makefile
  44. 19 13
      makefile.cygwin_dll
  45. 23 31
      makefile.icc
  46. 19 17
      makefile.msvc
  47. 7 0
      md2.c
  48. 5 0
      md4.c
  49. 62 0
      md5.c
  50. 46 0
      modes_test.c
  51. 112 112
      mpi.c
  52. 36 0
      mpi_to_ltc_error.c
  53. 2 4
      mycrypt.h
  54. 18 0
      mycrypt_cipher.h
  55. 32 1
      mycrypt_custom.h
  56. 0 32
      mycrypt_gf.h
  57. 2 0
      mycrypt_hash.h
  58. 39 31
      mycrypt_pk.h
  59. 34 7
      mycrypt_pkcs.h
  60. 5 0
      ocb_decrypt.c
  61. 30 0
      ofb_getiv.c
  62. 38 0
      ofb_setiv.c
  63. 14 6
      pkcs_1_oaep_decode.c
  64. 4 4
      pkcs_1_oaep_encode.c
  65. 4 1
      pkcs_1_pss_decode.c
  66. 3 3
      pkcs_1_pss_encode.c
  67. 61 0
      pkcs_1_v15_es_decode.c
  68. 55 0
      pkcs_1_v15_es_encode.c
  69. 77 0
      pkcs_1_v15_sa_decode.c
  70. 71 0
      pkcs_1_v15_sa_encode.c
  71. 1 5
      rand_prime.c
  72. 5 0
      rmd128.c
  73. 6 0
      rmd160.c
  74. 0 273
      rsa.c
  75. 61 0
      rsa_decrypt_key.c
  76. 59 0
      rsa_encrypt_key.c
  77. 72 0
      rsa_export.c
  78. 19 9
      rsa_exptmod.c
  79. 81 0
      rsa_import.c
  80. 1 1
      rsa_make_key.c
  81. 59 0
      rsa_sign_hash.c
  82. 0 274
      rsa_sys.c
  83. 69 0
      rsa_verify_hash.c
  84. 30 0
      sha1.c
  85. 5 0
      sha224.c
  86. 20 13
      sha256.c
  87. 7 0
      sha384.c
  88. 7 0
      sha512.c
  89. 7 0
      tiger.c
  90. 77 0
      tim_exptmod.c
  91. 6 1
      whirl.c
  92. 20 3
      yarrow.c

+ 0 - 38
PLAN

@@ -1,38 +0,0 @@
-The following functions are marked for removal and/or behavioural change by v1.00 of LibTomCrypt
-
-1.  RSA Support
-
-      rsa_pad, rsa_signpad, rsa_depad, rsa_signdepad, rsa_import, rsa_export
-
-They will be replaced with PKCS #1 compliant OAEP/PSS padding function as early as v0.96
-
-2.  DSA Support
-
-      dsa_import, dsa_export
-
-Will be replaced with suitable DSS [what is the standard?] compliant formats.  Planned for v0.96
-
-3.  Key Ring Support
-  
-      (all)
-
-The entire API will be dropped as early as v0.96.  It was just an experiment and nobody uses it anyways.
-
-4.  Test Harness
- 
-      demos/test.c
-
-The test harness is well overdue for a makeover.  Planned for as early as v0.97
-
-
-Put things in order...
-
-v0.96  -- removed keyring.c and gf.c
-       -- removed LTC RSA padding
-       -- DSS support [whatever this entails]
-       -- Bug fixes/updates to the PKCS/DSS support, should be stable in this release
-
-v0.97  -- Re-written test harness
-       -- More demos in the manual and demos/ directory
-
-... future???

+ 191 - 96
aes.c

@@ -30,16 +30,20 @@
 
 #ifdef RIJNDAEL
 
+#ifndef ENCRYPT_ONLY 
+
+#define SETUP    rijndael_setup
+#define ECB_ENC  rijndael_ecb_encrypt
+#define ECB_DEC  rijndael_ecb_decrypt
+#define ECB_TEST rijndael_test
+#define ECB_KS   rijndael_keysize
+
 const struct _cipher_descriptor rijndael_desc =
 {
     "rijndael",
     6,
     16, 32, 16, 10,
-    &rijndael_setup,
-    &rijndael_ecb_encrypt,
-    &rijndael_ecb_decrypt,
-    &rijndael_test,
-    &rijndael_keysize
+    SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
 };
 
 const struct _cipher_descriptor aes_desc =
@@ -47,21 +51,63 @@ const struct _cipher_descriptor aes_desc =
     "aes",
     6,
     16, 32, 16, 10,
-    &rijndael_setup,
-    &rijndael_ecb_encrypt,
-    &rijndael_ecb_decrypt,
-    &rijndael_test,
-    &rijndael_keysize
+    SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
 };
 
+#else
+
+#define SETUP    rijndael_enc_setup
+#define ECB_ENC  rijndael_enc_ecb_encrypt
+#define ECB_KS   rijndael_enc_keysize
+
+const struct _cipher_descriptor rijndael_enc_desc =
+{
+    "rijndael",
+    6,
+    16, 32, 16, 10,
+    SETUP, ECB_ENC, NULL, NULL, ECB_KS
+};
+
+const struct _cipher_descriptor aes_enc_desc =
+{
+    "aes",
+    6,
+    16, 32, 16, 10,
+    SETUP, ECB_ENC, NULL, NULL, ECB_KS
+};
+
+#endif
+
 #include "aes_tab.c"
 
-int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
+static ulong32 setup_mix(ulong32 temp)
+{
+   return (Te4_3[byte(temp, 2)]) ^
+          (Te4_2[byte(temp, 1)]) ^
+          (Te4_1[byte(temp, 0)]) ^
+          (Te4_0[byte(temp, 3)]);
+}
+
+#ifndef ENCRYPT_ONLY
+
+static ulong32 setup_mix2(ulong32 temp)
+{
+   return Td0(255 & Te4[byte(temp, 3)]) ^
+          Td1(255 & Te4[byte(temp, 2)]) ^
+          Td2(255 & Te4[byte(temp, 1)]) ^
+          Td3(255 & Te4[byte(temp, 0)]);
+}
+
+#endif
+
+int SETUP(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
 {
     int i, j;
-    ulong32 temp, *rk, *rrk;
-    
-    _ARGCHK(key != NULL);
+    ulong32 temp, *rk;
+#ifndef ENCRYPT_ONLY
+    ulong32 *rrk;
+#endif    
+    _ARGCHK(key  != NULL);
     _ARGCHK(skey != NULL);
     
     if (keylen != 16 && keylen != 24 && keylen != 32) {
@@ -85,12 +131,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
         j = 44;
         for (;;) {
             temp  = rk[3];
-            rk[4] = rk[0] ^
-                (Te4_3[byte(temp, 2)]) ^
-                (Te4_2[byte(temp, 1)]) ^
-                (Te4_1[byte(temp, 0)]) ^
-                (Te4_0[byte(temp, 3)]) ^
-                rcon[i];
+            rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
             rk[5] = rk[1] ^ rk[4];
             rk[6] = rk[2] ^ rk[5];
             rk[7] = rk[3] ^ rk[6];
@@ -109,12 +150,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
         #else
             temp = rk[5];
         #endif
-            rk[ 6] = rk[ 0] ^
-                (Te4_3[byte(temp, 2)]) ^
-                (Te4_2[byte(temp, 1)]) ^
-                (Te4_1[byte(temp, 0)]) ^
-                (Te4_0[byte(temp, 3)]) ^
-                rcon[i];
+            rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
             rk[ 7] = rk[ 1] ^ rk[ 6];
             rk[ 8] = rk[ 2] ^ rk[ 7];
             rk[ 9] = rk[ 3] ^ rk[ 8];
@@ -137,12 +173,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
         #else
             temp = rk[7];
         #endif
-            rk[ 8] = rk[ 0] ^
-                (Te4_3[byte(temp, 2)]) ^
-                (Te4_2[byte(temp, 1)]) ^
-                (Te4_1[byte(temp, 0)]) ^
-                (Te4_0[byte(temp, 3)]) ^
-                rcon[i];
+            rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
             rk[ 9] = rk[ 1] ^ rk[ 8];
             rk[10] = rk[ 2] ^ rk[ 9];
             rk[11] = rk[ 3] ^ rk[10];
@@ -150,11 +181,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
                 break;
             }
             temp = rk[11];
-            rk[12] = rk[ 4] ^
-                (Te4_3[byte(temp, 3)]) ^
-                (Te4_2[byte(temp, 2)]) ^
-                (Te4_1[byte(temp, 1)]) ^
-                (Te4_0[byte(temp, 0)]);
+            rk[12] = rk[ 4] ^ setup_mix(ROR(temp, 8));
             rk[13] = rk[ 5] ^ rk[12];
             rk[14] = rk[ 6] ^ rk[13];
             rk[15] = rk[ 7] ^ rk[14];
@@ -164,7 +191,8 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
        /* this can't happen */
        j = 4;
     }
-    
+
+#ifndef ENCRYPT_ONLY    
     /* setup the inverse key now */
     rk   = skey->rijndael.dK;
     rrk  = skey->rijndael.eK + j - 4; 
@@ -182,29 +210,13 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
         rk  += 4;
     #ifdef SMALL_CODE        
         temp = rrk[0];
-        rk[0] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[0] = setup_mix2(temp);
         temp = rrk[1];
-        rk[1] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[1] = setup_mix2(temp);
         temp = rrk[2];
-        rk[2] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[2] = setup_mix2(temp);
         temp = rrk[3];
-        rk[3] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[3] = setup_mix2(temp);
      #else
         temp = rrk[0];
         rk[0] =
@@ -241,6 +253,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
     *rk++ = *rrk++;
     *rk++ = *rrk++;
     *rk   = *rrk;
+#endif /* ENCRYPT_ONLY */
 
     return CRYPT_OK;   
 }
@@ -248,7 +261,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
 #ifdef CLEAN_STACK
 static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
 #else
-void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@@ -270,6 +283,44 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
     LOAD32H(s2, pt  +  8); s2 ^= rk[2];
     LOAD32H(s3, pt  + 12); s3 ^= rk[3];
 
+
+#ifdef SMALL_CODE
+
+    for (r = 0; ; r++) {
+        rk += 4;
+        t0 =
+            Te0(byte(s0, 3)) ^
+            Te1(byte(s1, 2)) ^
+            Te2(byte(s2, 1)) ^
+            Te3(byte(s3, 0)) ^
+            rk[0];
+        t1 =
+            Te0(byte(s1, 3)) ^
+            Te1(byte(s2, 2)) ^
+            Te2(byte(s3, 1)) ^
+            Te3(byte(s0, 0)) ^
+            rk[1];
+        t2 =
+            Te0(byte(s2, 3)) ^
+            Te1(byte(s3, 2)) ^
+            Te2(byte(s0, 1)) ^
+            Te3(byte(s1, 0)) ^
+            rk[2];
+        t3 =
+            Te0(byte(s3, 3)) ^
+            Te1(byte(s0, 2)) ^
+            Te2(byte(s1, 1)) ^
+            Te3(byte(s2, 0)) ^
+            rk[3];
+        if (r == Nr-2) { 
+           break;
+        }
+        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
+    }
+    rk += 4;
+
+#else
+
     /*
      * Nr - 1 full rounds:
      */
@@ -330,52 +381,57 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
             Te3(byte(t2, 0)) ^
             rk[3];
     }
+
+#endif
+
     /*
      * apply last round and
      * map cipher state to byte array block:
      */
     s0 =
-        (Te4_3[(t0 >> 24)       ]) ^
-        (Te4_2[(t1 >> 16) & 0xff]) ^
-        (Te4_1[(t2 >>  8) & 0xff]) ^
-        (Te4_0[(t3      ) & 0xff]) ^
+        (Te4_3[byte(t0, 3)]) ^
+        (Te4_2[byte(t1, 2)]) ^
+        (Te4_1[byte(t2, 1)]) ^
+        (Te4_0[byte(t3, 0)]) ^
         rk[0];
     STORE32H(s0, ct);
     s1 =
-        (Te4_3[(t1 >> 24)       ]) ^
-        (Te4_2[(t2 >> 16) & 0xff]) ^
-        (Te4_1[(t3 >>  8) & 0xff]) ^
-        (Te4_0[(t0      ) & 0xff]) ^
+        (Te4_3[byte(t1, 3)]) ^
+        (Te4_2[byte(t2, 2)]) ^
+        (Te4_1[byte(t3, 1)]) ^
+        (Te4_0[byte(t0, 0)]) ^
         rk[1];
     STORE32H(s1, ct+4);
     s2 =
-        (Te4_3[(t2 >> 24)       ]) ^
-        (Te4_2[(t3 >> 16) & 0xff]) ^
-        (Te4_1[(t0 >>  8) & 0xff]) ^
-        (Te4_0[(t1      ) & 0xff]) ^
+        (Te4_3[byte(t2, 3)]) ^
+        (Te4_2[byte(t3, 2)]) ^
+        (Te4_1[byte(t0, 1)]) ^
+        (Te4_0[byte(t1, 0)]) ^
         rk[2];
     STORE32H(s2, ct+8);
     s3 =
-        (Te4_3[(t3 >> 24)       ]) ^
-        (Te4_2[(t0 >> 16) & 0xff]) ^
-        (Te4_1[(t1 >>  8) & 0xff]) ^
-        (Te4_0[(t2      ) & 0xff]) ^ 
+        (Te4_3[byte(t3, 3)]) ^
+        (Te4_2[byte(t0, 2)]) ^
+        (Te4_1[byte(t1, 1)]) ^
+        (Te4_0[byte(t2, 0)]) ^ 
         rk[3];
     STORE32H(s3, ct+12);
 }
 
 #ifdef CLEAN_STACK
-void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
+void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
 {
    _rijndael_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
 }
 #endif
 
+#ifndef ENCRYPT_ONLY 
+
 #ifdef CLEAN_STACK
 static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
 #else
-void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@@ -397,6 +453,42 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
     LOAD32H(s2, ct  +  8); s2 ^= rk[2];
     LOAD32H(s3, ct  + 12); s3 ^= rk[3];
 
+#ifdef SMALL_CODE
+    for (r = 0; ; r++) {
+        rk += 4;
+        t0 =
+            Td0(byte(s0, 3)) ^
+            Td1(byte(s3, 2)) ^
+            Td2(byte(s2, 1)) ^
+            Td3(byte(s1, 0)) ^
+            rk[0];
+        t1 =
+            Td0(byte(s1, 3)) ^
+            Td1(byte(s0, 2)) ^
+            Td2(byte(s3, 1)) ^
+            Td3(byte(s2, 0)) ^
+            rk[1];
+        t2 =
+            Td0(byte(s2, 3)) ^
+            Td1(byte(s1, 2)) ^
+            Td2(byte(s0, 1)) ^
+            Td3(byte(s3, 0)) ^
+            rk[2];
+        t3 =
+            Td0(byte(s3, 3)) ^
+            Td1(byte(s2, 2)) ^
+            Td2(byte(s1, 1)) ^
+            Td3(byte(s0, 0)) ^
+            rk[3];
+        if (r == Nr-2) {
+           break; 
+        }
+        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
+    }
+    rk += 4;
+
+#else       
+
     /*
      * Nr - 1 full rounds:
      */
@@ -459,51 +551,52 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
             Td3(byte(t0, 0)) ^
             rk[3];
     }
+#endif
 
     /*
      * apply last round and
      * map cipher state to byte array block:
      */
     s0 =
-        (Td4[(t0 >> 24)       ] & 0xff000000) ^
-        (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t1      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t0, 3)] & 0xff000000) ^
+        (Td4[byte(t3, 2)] & 0x00ff0000) ^
+        (Td4[byte(t2, 1)] & 0x0000ff00) ^
+        (Td4[byte(t1, 0)] & 0x000000ff) ^
         rk[0];
     STORE32H(s0, pt);
     s1 =
-        (Td4[(t1 >> 24)       ] & 0xff000000) ^
-        (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t2      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t1, 3)] & 0xff000000) ^
+        (Td4[byte(t0, 2)] & 0x00ff0000) ^
+        (Td4[byte(t3, 1)] & 0x0000ff00) ^
+        (Td4[byte(t2, 0)] & 0x000000ff) ^
         rk[1];
     STORE32H(s1, pt+4);
     s2 =
-        (Td4[(t2 >> 24)       ] & 0xff000000) ^
-        (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t3      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t2, 3)] & 0xff000000) ^
+        (Td4[byte(t1, 2)] & 0x00ff0000) ^
+        (Td4[byte(t0, 1)] & 0x0000ff00) ^
+        (Td4[byte(t3, 0)] & 0x000000ff) ^
         rk[2];
     STORE32H(s2, pt+8);
     s3 =
-        (Td4[(t3 >> 24)       ] & 0xff000000) ^
-        (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t0      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t3, 3)] & 0xff000000) ^
+        (Td4[byte(t2, 2)] & 0x00ff0000) ^
+        (Td4[byte(t1, 1)] & 0x0000ff00) ^
+        (Td4[byte(t0, 0)] & 0x000000ff) ^
         rk[3];
     STORE32H(s3, pt+12);
 }
 
 
 #ifdef CLEAN_STACK
-void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
+void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
 {
    _rijndael_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
 }
 #endif
 
-int rijndael_test(void)
+int ECB_TEST(void)
 {
  #ifndef LTC_TEST
     return CRYPT_NOP;
@@ -584,7 +677,9 @@ int rijndael_test(void)
  #endif
 }
 
-int rijndael_keysize(int *desired_keysize)
+#endif /* ENCRYPT_ONLY */
+
+int ECB_KS(int *desired_keysize)
 {
    _ARGCHK(desired_keysize != NULL);
 

+ 8 - 0
aes_tab.c

@@ -157,6 +157,8 @@ static const ulong32 Te4[256] = {
     0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
 };
 
+#ifndef ENCRYPT_ONLY
+
 static const ulong32 TD0[256] = {
     0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
     0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
@@ -291,6 +293,8 @@ static const ulong32 Td4[256] = {
     0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
 };
 
+#endif /* ENCRYPT_ONLY */
+
 #ifdef SMALL_CODE
 
 #define Te0(x) TE0[x]
@@ -660,6 +664,8 @@ static const ulong32 Te4_3[] = {
 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL
 };
 
+#ifndef ENCRYPT_ONLY
+
 static const ulong32 TD1[256] = {
     0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
     0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
@@ -999,6 +1005,8 @@ static const ulong32 Tks3[] = {
 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL
 };
 
+#endif /* ENCRYPT_ONLY */
+
 #endif /* SMALL CODE */
 
 static const ulong32 rcon[] = {

+ 1 - 46
base64.c → base64_decode.c

@@ -8,14 +8,12 @@
  *
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
+
 /* compliant base64 code donated by Wayne Scott ([email protected]) */
 #include "mycrypt.h"
 
 #ifdef BASE64
 
-static const char *codes = 
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
 static const unsigned char map[256] = {
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
@@ -40,49 +38,6 @@ static const unsigned char map[256] = {
 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255 };
 
-int base64_encode(const unsigned char *in,  unsigned long len, 
-                        unsigned char *out, unsigned long *outlen)
-{
-   unsigned long i, len2, leven;
-   unsigned char *p;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* valid output size ? */
-   len2 = 4 * ((len + 2) / 3);
-   if (*outlen < len2 + 1) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-   p = out;
-   leven = 3*(len / 3);
-   for (i = 0; i < leven; i += 3) {
-       *p++ = codes[(in[0] >> 2) & 0x3F];
-       *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
-       *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
-       *p++ = codes[in[2] & 0x3F];
-       in += 3;
-   }
-   /* Pad it if necessary...  */
-   if (i < len) {
-       unsigned a = in[0];
-       unsigned b = (i+1 < len) ? in[1] : 0;
-
-       *p++ = codes[(a >> 2) & 0x3F];
-       *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
-       *p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
-       *p++ = '=';
-   }
-
-   /* append a NULL byte */
-   *p = '\0';
-
-   /* return ok */
-   *outlen = p - out;
-   return CRYPT_OK;
-}
-
 int base64_decode(const unsigned char *in,  unsigned long len, 
                         unsigned char *out, unsigned long *outlen)
 {

+ 63 - 0
base64_encode.c

@@ -0,0 +1,63 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+/* compliant base64 code donated by Wayne Scott ([email protected]) */
+#include "mycrypt.h"
+
+#ifdef BASE64
+
+static const char *codes = 
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+int base64_encode(const unsigned char *in,  unsigned long len, 
+                        unsigned char *out, unsigned long *outlen)
+{
+   unsigned long i, len2, leven;
+   unsigned char *p;
+
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+
+   /* valid output size ? */
+   len2 = 4 * ((len + 2) / 3);
+   if (*outlen < len2 + 1) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   p = out;
+   leven = 3*(len / 3);
+   for (i = 0; i < leven; i += 3) {
+       *p++ = codes[(in[0] >> 2) & 0x3F];
+       *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
+       *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
+       *p++ = codes[in[2] & 0x3F];
+       in += 3;
+   }
+   /* Pad it if necessary...  */
+   if (i < len) {
+       unsigned a = in[0];
+       unsigned b = (i+1 < len) ? in[1] : 0;
+
+       *p++ = codes[(a >> 2) & 0x3F];
+       *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
+       *p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
+       *p++ = '=';
+   }
+
+   /* append a NULL byte */
+   *p = '\0';
+
+   /* return ok */
+   *outlen = p - out;
+   return CRYPT_OK;
+}
+
+#endif
+

+ 4 - 3
cbc_decrypt.c

@@ -25,14 +25,15 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc)
    if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
        return err;
    }
-   cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
-   
+   _ARGCHK(cipher_descriptor[cbc->cipher].ecb_decrypt != NULL);
+      
    /* is blocklen valid? */
    if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
       return CRYPT_INVALID_ARG;
    } 
 
-   /* xor IV against the plaintext of the previous step */
+   /* decrypt and xor IV against the plaintext of the previous step */
+   cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
    for (x = 0; x < cbc->blocklen; x++) { 
        /* copy CT in case ct == pt */
        tmp2[x] = ct[x]; 

+ 30 - 0
cbc_getiv.c

@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CBC
+
+int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(cbc != NULL);
+   if ((unsigned long)cbc->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, cbc->IV, cbc->blocklen);
+   *len = cbc->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif

+ 28 - 0
cbc_setiv.c

@@ -0,0 +1,28 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CBC
+
+int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(cbc != NULL);
+   if (len != (unsigned long)cbc->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+   memcpy(cbc->IV, IV, len);
+   return CRYPT_OK;
+}
+
+#endif 
+

+ 30 - 0
cfb_getiv.c

@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CFB
+
+int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(cfb != NULL);
+   if ((unsigned long)cfb->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, cfb->IV, cfb->blocklen);
+   *len = cfb->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif

+ 39 - 0
cfb_setiv.c

@@ -0,0 +1,39 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CFB
+
+int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
+{
+   int err;
+   
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(cfb != NULL);
+
+   if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
+       return err;
+   }
+   
+   if (len != (unsigned long)cfb->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+      
+   /* force next block */
+   cfb->padlen = 0;
+   cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
+
+   return CRYPT_OK;
+}
+
+#endif 
+

+ 25 - 0
changes

@@ -1,3 +1,28 @@
+May 30th, 2004
+v0.96  -- Removed GF and Keyring code
+       -- Extended OAEP decoder to distinguish better [and use a more uniform API]
+       -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments)
+       -- rsa_exptmod() now pads with leading zeroes as per I2OSP.
+       -- added error checking to yarrow code
+       -- Mike Frysinger pointed out that tommath.h from this distro will overwrite tommath.h
+          from libtommath.  I changed this to ltc_tommath.h to avoid any such problems.
+       -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly
+       -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space.
+       -- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-)
+       -- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used.
+       -- replaced old RSA code with new code that uses PKCS #1 v2.0 padding
+       -- replaced old test harness with new over-engineer'ed one in /demos/test/
+       -- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying.
+       -- Added PKCS #1 v1.5 RSA encryption and signature padding routines
+       -- Added DER OID's to most hash descriptors (as many as I could find) 
+       -- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations 
+          added #define RSA_TIMING which can turn on/off this feature.
+       -- No more config.pl so please just read mycrypt_custom.h for build-time tweaks
+       -- Small update to rand_prime()
+       -- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined.  If you want speed though,
+          you're going to have to undefine SMALL_CODE ;-)
+       -- Worked over AES so that it's even smaller now [in both modes].
+       
 May 12th, 2004
 v0.95  -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact
           the transforms are circulant.  AES dropped 5KB and WHIRLPOOL dropped 13KB

+ 17 - 7
crypt.c

@@ -120,6 +120,9 @@ const char *crypt_build_settings =
 #if defined(RIPEMD160)
    "   RIPEMD160\n"
 #endif
+#if defined(WHIRLPOOL)
+   "   WHIRLPOOL\n"
+#endif
 
     "\nBlock Chaining Modes:\n"
 #if defined(CFB)
@@ -151,7 +154,11 @@ const char *crypt_build_settings =
 
     "\nPK Algs:\n"
 #if defined(MRSA)
-    "   RSA\n"
+    "   RSA"
+#if defined(RSA_TIMING)
+    " + RSA_TIMING "
+#endif
+    "\n"
 #endif
 #if defined(MDH)
     "   DH\n"
@@ -162,9 +169,6 @@ const char *crypt_build_settings =
 #if defined(MDSA)
     "   DSA\n"
 #endif
-#if defined(KR)
-    "   KR\n"
-#endif
 
     "\nCompiler:\n"
 #if defined(WIN32)
@@ -187,9 +191,6 @@ const char *crypt_build_settings =
 #endif
 
     "\nVarious others: "
-#if defined(GF)
-    " GF "
-#endif
 #if defined(BASE64)
     " BASE64 "
 #endif
@@ -222,6 +223,15 @@ const char *crypt_build_settings =
 #endif
 #if defined(PKCS_5)
     " PKCS#5 "
+#endif
+#if defined(SMALL_CODE)
+    " SMALL_CODE "
+#endif
+#if defined(NO_FILE)
+    " NO_FILE "
+#endif
+#if defined(LTC_TEST)
+    " LTC_TEST "
 #endif
     "\n"
     "\n\n\n"

+ 0 - 88
crypt.out

@@ -1,88 +0,0 @@
-\BOOKMARK [0][-]{chapter.1}{Introduction}{}
-\BOOKMARK [1][-]{section.1.1}{What is the LibTomCrypt?}{chapter.1}
-\BOOKMARK [2][-]{subsection.1.1.1}{What the library IS for?}{section.1.1}
-\BOOKMARK [2][-]{subsection.1.1.2}{What the library IS NOT for?}{section.1.1}
-\BOOKMARK [1][-]{section.1.2}{Why did I write it?}{chapter.1}
-\BOOKMARK [2][-]{subsection.1.2.1}{Modular}{section.1.2}
-\BOOKMARK [1][-]{section.1.3}{License}{chapter.1}
-\BOOKMARK [1][-]{section.1.4}{Patent Disclosure}{chapter.1}
-\BOOKMARK [1][-]{section.1.5}{Building the library}{chapter.1}
-\BOOKMARK [1][-]{section.1.6}{Building against the library}{chapter.1}
-\BOOKMARK [1][-]{section.1.7}{Thanks}{chapter.1}
-\BOOKMARK [0][-]{chapter.2}{The Application Programming Interface \(API\)}{}
-\BOOKMARK [1][-]{section.2.1}{Introduction}{chapter.2}
-\BOOKMARK [1][-]{section.2.2}{Macros}{chapter.2}
-\BOOKMARK [1][-]{section.2.3}{Functions with Variable Length Output}{chapter.2}
-\BOOKMARK [1][-]{section.2.4}{Functions that need a PRNG}{chapter.2}
-\BOOKMARK [1][-]{section.2.5}{Functions that use Arrays of Octets}{chapter.2}
-\BOOKMARK [0][-]{chapter.3}{Symmetric Block Ciphers}{}
-\BOOKMARK [1][-]{section.3.1}{Core Functions}{chapter.3}
-\BOOKMARK [1][-]{section.3.2}{Key Sizes and Number of Rounds}{chapter.3}
-\BOOKMARK [1][-]{section.3.3}{The Cipher Descriptors}{chapter.3}
-\BOOKMARK [2][-]{subsection.3.3.1}{Notes}{section.3.3}
-\BOOKMARK [1][-]{section.3.4}{Symmetric Modes of Operations}{chapter.3}
-\BOOKMARK [2][-]{subsection.3.4.1}{Background}{section.3.4}
-\BOOKMARK [2][-]{subsection.3.4.2}{Choice of Mode}{section.3.4}
-\BOOKMARK [2][-]{subsection.3.4.3}{Implementation}{section.3.4}
-\BOOKMARK [1][-]{section.3.5}{Encrypt and Authenticate Modes}{chapter.3}
-\BOOKMARK [2][-]{subsection.3.5.1}{EAX Mode}{section.3.5}
-\BOOKMARK [2][-]{subsection.3.5.2}{OCB Mode}{section.3.5}
-\BOOKMARK [0][-]{chapter.4}{One-Way Cryptographic Hash Functions}{}
-\BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
-\BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
-\BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2}
-\BOOKMARK [0][-]{chapter.5}{Message Authentication Codes}{}
-\BOOKMARK [1][-]{section.5.1}{HMAC Protocol}{chapter.5}
-\BOOKMARK [1][-]{section.5.2}{OMAC Support}{chapter.5}
-\BOOKMARK [1][-]{section.5.3}{PMAC Support}{chapter.5}
-\BOOKMARK [0][-]{chapter.6}{Pseudo-Random Number Generators}{}
-\BOOKMARK [1][-]{section.6.1}{Core Functions}{chapter.6}
-\BOOKMARK [2][-]{subsection.6.1.1}{Remarks}{section.6.1}
-\BOOKMARK [2][-]{subsection.6.1.2}{Example}{section.6.1}
-\BOOKMARK [1][-]{section.6.2}{PRNG Descriptors}{chapter.6}
-\BOOKMARK [1][-]{section.6.3}{The Secure RNG}{chapter.6}
-\BOOKMARK [2][-]{subsection.6.3.1}{The Secure PRNG Interface}{section.6.3}
-\BOOKMARK [0][-]{chapter.7}{RSA Routines}{}
-\BOOKMARK [1][-]{section.7.1}{Background}{chapter.7}
-\BOOKMARK [1][-]{section.7.2}{Core Functions}{chapter.7}
-\BOOKMARK [1][-]{section.7.3}{Packet Routines}{chapter.7}
-\BOOKMARK [1][-]{section.7.4}{Remarks}{chapter.7}
-\BOOKMARK [0][-]{chapter.8}{Diffie-Hellman Key Exchange}{}
-\BOOKMARK [1][-]{section.8.1}{Background}{chapter.8}
-\BOOKMARK [1][-]{section.8.2}{Core Functions}{chapter.8}
-\BOOKMARK [2][-]{subsection.8.2.1}{Remarks on Usage}{section.8.2}
-\BOOKMARK [2][-]{subsection.8.2.2}{Remarks on The Snippet}{section.8.2}
-\BOOKMARK [1][-]{section.8.3}{Other Diffie-Hellman Functions}{chapter.8}
-\BOOKMARK [1][-]{section.8.4}{DH Packet}{chapter.8}
-\BOOKMARK [0][-]{chapter.9}{Elliptic Curve Cryptography}{}
-\BOOKMARK [1][-]{section.9.1}{Background}{chapter.9}
-\BOOKMARK [1][-]{section.9.2}{Core Functions}{chapter.9}
-\BOOKMARK [1][-]{section.9.3}{ECC Packet}{chapter.9}
-\BOOKMARK [1][-]{section.9.4}{ECC Keysizes}{chapter.9}
-\BOOKMARK [0][-]{chapter.10}{Digital Signature Algorithm}{}
-\BOOKMARK [1][-]{section.10.1}{Introduction}{chapter.10}
-\BOOKMARK [1][-]{section.10.2}{Key Generation}{chapter.10}
-\BOOKMARK [1][-]{section.10.3}{Key Verification}{chapter.10}
-\BOOKMARK [1][-]{section.10.4}{Signatures}{chapter.10}
-\BOOKMARK [1][-]{section.10.5}{Import and Export}{chapter.10}
-\BOOKMARK [0][-]{chapter.11}{Public Keyrings}{}
-\BOOKMARK [1][-]{section.11.1}{Introduction}{chapter.11}
-\BOOKMARK [1][-]{section.11.2}{The Keyring API}{chapter.11}
-\BOOKMARK [0][-]{chapter.12}{GF\(2w\) Math Routines}{}
-\BOOKMARK [0][-]{chapter.13}{Miscellaneous}{}
-\BOOKMARK [1][-]{section.13.1}{Base64 Encoding and Decoding}{chapter.13}
-\BOOKMARK [1][-]{section.13.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.13}
-\BOOKMARK [2][-]{subsection.13.2.1}{Binary Forms of ``mp\137int'' Variables}{section.13.2}
-\BOOKMARK [2][-]{subsection.13.2.2}{Primality Testing}{section.13.2}
-\BOOKMARK [0][-]{chapter.14}{Programming Guidelines}{}
-\BOOKMARK [1][-]{section.14.1}{Secure Pseudo Random Number Generators}{chapter.14}
-\BOOKMARK [1][-]{section.14.2}{Preventing Trivial Errors}{chapter.14}
-\BOOKMARK [1][-]{section.14.3}{Registering Your Algorithms}{chapter.14}
-\BOOKMARK [1][-]{section.14.4}{Key Sizes}{chapter.14}
-\BOOKMARK [2][-]{subsection.14.4.1}{Symmetric Ciphers}{section.14.4}
-\BOOKMARK [2][-]{subsection.14.4.2}{Assymetric Ciphers}{section.14.4}
-\BOOKMARK [1][-]{section.14.5}{Thread Safety}{chapter.14}
-\BOOKMARK [0][-]{chapter.15}{Configuring the Library}{}
-\BOOKMARK [1][-]{section.15.1}{Introduction}{chapter.15}
-\BOOKMARK [1][-]{section.15.2}{mycrypt\137cfg.h}{chapter.15}
-\BOOKMARK [1][-]{section.15.3}{The Configure Script}{chapter.15}

BIN
crypt.pdf


Plik diff jest za duży
+ 324 - 141
crypt.tex


+ 32 - 32
crypt_hash_descriptor.c

@@ -11,35 +11,35 @@
 #include "mycrypt.h"
 
 struct _hash_descriptor hash_descriptor[TAB_SIZE] = {
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } };
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
+{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL } };

+ 30 - 0
ctr_getiv.c

@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CTR
+
+int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(ctr != NULL);
+   if ((unsigned long)ctr->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, ctr->ctr, ctr->blocklen);
+   *len = ctr->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif

+ 43 - 0
ctr_setiv.c

@@ -0,0 +1,43 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CTR
+
+int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
+{
+   int err;
+   
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(ctr != NULL);
+
+   /* bad param? */
+   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
+      return err;
+   }
+   
+   if (len != (unsigned long)ctr->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* set IV */
+   memcpy(ctr->ctr, IV, len);
+   
+   /* force next block */
+   ctr->padlen = 0;
+   cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
+   
+   return CRYPT_OK;
+}
+
+#endif 
+

+ 1 - 1
demos/small.c

@@ -4,7 +4,7 @@
 
 int main(void)
 {
-   register_cipher(&rijndael_desc);
+   register_cipher(&rijndael_enc_desc);
    register_prng(&yarrow_desc);
    register_hash(&sha256_desc);
    return 0;

+ 3 - 363
demos/test.c

@@ -1202,69 +1202,6 @@ ecc_tests (void)
 }
 #endif
 
-#ifdef GF
-void
-gf_tests (void)
-{
-  gf_int  a, b, c, d;
-  int     n;
-  unsigned char buf[1024];
-
-  printf ("GF tests\n");
-  gf_zero (a);
-  gf_zero (b);
-  gf_zero (c);
-  gf_zero (d);
-
-  /* a == 0x18000000b */
-  a[1] = 1;
-  a[0] = 0x8000000bUL;
-
-  /* b == 0x012345678 */
-  b[0] = 0x012345678UL;
-
-  /* find 1/b mod a */
-  gf_invmod (b, a, c);
-
-  /* find 1/1/b mod a */
-  gf_invmod (c, a, d);
-
-  /* display them */
-  printf ("  %08lx %08lx\n", c[0], d[0]);
-
-  /* store as binary string */
-  n = gf_size (a);
-  printf ("  a takes %d bytes\n", n);
-  gf_toraw (a, buf);
-  gf_readraw (a, buf, n);
-  printf ("  a == %08lx%08lx\n", a[1], a[0]);
-
-  /* primality testing */
-  gf_zero (a);
-  a[0] = 0x169;
-  printf ("  GF prime: %s, ", gf_is_prime (a) ? "passed" : "failed");
-  a[0] = 0x168;
-  printf ("  %s\n", gf_is_prime (a) ? "failed" : "passed");
-
-  /* test sqrt code */
-  gf_zero (a);
-  a[1] = 0x00000001;
-  a[0] = 0x8000000bUL;
-  gf_zero (b);
-  b[0] = 0x12345678UL;
-
-  gf_sqrt (b, a, c);
-  gf_mulmod (c, c, a, b);
-  printf ("  (%08lx)^2 = %08lx (mod %08lx%08lx) \n", c[0], b[0], a[1], a[0]);
-}
-#else
-void
-gf_tests (void)
-{
-  printf ("GF not compiled in\n");
-}
-#endif
-
 #ifdef MPI
 void
 test_prime (void)
@@ -1390,299 +1327,6 @@ register_all_algs (void)
 #endif
 }
 
-#ifdef KR
-void
-kr_display (pk_key * kr)
-{
-  static const char *sys[] = { "NON-KEY", "RSA", "DH", "ECC" };
-  static const char *type[] = { "PRIVATE", "PUBLIC", "PRIVATE_OPTIMIZED" };
-
-  while (kr->system != NON_KEY) {
-    printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
-        sys[kr->system], type[kr->key_type], kr->name, kr->email,
-        kr->description);
-    kr = kr->next;
-  }
-  printf ("\n");
-}
-
-void
-kr_test_makekeys (pk_key ** kr)
-{
-  if ((errnum = kr_init (kr)) != CRYPT_OK) {
-    printf ("KR init error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a DH key */
-  printf ("KR: Making DH key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey",
-            "[email protected]", "dhkey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a ECC key */
-  printf ("KR: Making ECC key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey",
-            "[email protected]", "ecckey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a RSA key */
-  printf ("KR: Making RSA key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey",
-            "[email protected]", "rsakey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-}
-
-void
-kr_test (void)
-{
-  pk_key *kr, *_kr;
-  unsigned char buf[8192], buf2[8192], buf3[8192];
-  unsigned long len;
-  int     i, j, stat;
-#ifndef NO_FILE
-  FILE   *f;
-#endif
-
-  kr_test_makekeys (&kr);
-
-  printf ("The original list:\n");
-  kr_display (kr);
-
-  for (i = 0; i < 3; i++) {
-    len = sizeof (buf);
-    if ((errnum = kr_export (kr, kr->ID, kr->key_type, buf, &len)) != CRYPT_OK) {
-      printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("Exported key was: %lu bytes\n", len);
-    if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
-      printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-    if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-      printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-  }
-
-  for (i = 0; i < 3; i++) {
-    len = sizeof (buf);
-    if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-      printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("Exported key was: %lu bytes\n", len);
-    if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
-      printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-    if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-      printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-  }
-
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("Error clearing ring: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-
-/* TEST output to file */
-#ifndef NO_FILE
-
-  if ((errnum = kr_init (&kr)) != CRYPT_OK) {
-    printf ("KR init error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_test_makekeys (&kr);
-
-  /* save to file */
-  f = fopen ("ring.dat", "wb");
-  if ((errnum = kr_save (kr, f, NULL)) != CRYPT_OK) {
-    printf ("kr_save error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  fclose (f);
-
-  /* delete and load */
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("clear error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  f = fopen ("ring.dat", "rb");
-  if ((errnum = kr_load (&kr, f, NULL)) != CRYPT_OK) {
-    printf ("kr_load error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  fclose (f);
-  remove ("ring.dat");
-  printf ("After load and save...\n");
-  kr_display (kr);
-
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("clear error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-#endif
-
-/* test the packet encryption/sign stuff */
-  for (i = 0; i < 32; i++)
-    buf[i] = i;
-  kr_test_makekeys (&kr);
-  _kr = kr;
-  for (i = 0; i < 3; i++) {
-    printf ("Testing a key with system %d, type %d:\t", _kr->system,
-        _kr->key_type);
-    len = sizeof (buf2);
-    if ((errnum =
-     kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
-             find_prng ("yarrow"),
-             find_hash ("md5"))) != CRYPT_OK) {
-      printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    len = sizeof (buf3);
-    if ((errnum = kr_decrypt_key (kr, buf2, buf3, &len)) != CRYPT_OK) {
-      printf ("decrypt error, %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    if (len != 16 || memcmp (buf3, buf, 16)) {
-      printf ("kr_decrypt_key failed, %i, %lu\n", i, len);
-      exit (-1);
-    }
-    printf ("kr_encrypt_key passed, ");
-
-    len = sizeof (buf2);
-    if ((errnum =
-     kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
-               find_prng ("yarrow"))) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("kr_sign_hash: ");
-    if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("%s, ", stat ? "passed" : "failed");
-    buf[15] ^= 1;
-    if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("%s\n", (!stat) ? "passed" : "failed");
-    buf[15] ^= 1;
-
-    len = sizeof (buf);
-    if ((errnum =
-     kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
-             &len)) != CRYPT_OK) {
-      printf ("kr_fingerprint failed, %i, %lu\n", i, len);
-      exit (-1);
-    }
-    printf ("Fingerprint:  ");
-    for (j = 0; j < 20; j++) {
-      printf ("%02x", buf[j]);
-      if (j < 19)
-    printf (":");
-    }
-    printf ("\n\n");
-
-    _kr = _kr->next;
-  }
-
-/* Test encrypting/decrypting to a public key */
-/* first dump the other two keys */
-  kr_del (&kr, kr->ID);
-  kr_del (&kr, kr->ID);
-  kr_display (kr);
-
-  /* now export it as public and private */
-  len = sizeof (buf);
-  if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-    printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check boundaries */
-  memset (buf + len, 0, sizeof (buf) - len);
-
-  len = sizeof (buf2);
-  if ((errnum = kr_export (kr, kr->ID, PK_PRIVATE, buf2, &len)) != CRYPT_OK) {
-    printf ("Error exporting key  %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check boundaries */
-  memset (buf2 + len, 0, sizeof (buf2) - len);
-
-  /* delete the key and import the public */
-  kr_clear (&kr);
-  kr_init (&kr);
-  kr_display (kr);
-  if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-    printf ("Error importing key %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_display (kr);
-
-  /* now encrypt a buffer */
-  for (i = 0; i < 16; i++)
-    buf[i] = i;
-  len = sizeof (buf3);
-  if ((errnum =
-       kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng,
-               find_prng ("yarrow"),
-               find_hash ("md5"))) != CRYPT_OK) {
-    printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now delete the key and import the private one */
-  kr_clear (&kr);
-  kr_init (&kr);
-  kr_display (kr);
-  if ((errnum = kr_import (kr, buf2, len)) != CRYPT_OK) {
-    printf ("Error importing key %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_display (kr);
-
-  /* now decrypt */
-  len = sizeof (buf2);
-  if ((errnum = kr_decrypt_key (kr, buf3, buf2, &len)) != CRYPT_OK) {
-    printf ("decrypt error, %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  printf ("KR encrypt to public, decrypt with private: ");
-  if (len == 16 && !memcmp (buf2, buf, 16)) {
-    printf ("passed\n");
-  } else {
-    printf ("failed\n");
-  }
-
-  kr_clear (&kr);
-}
-#endif
-
 void
 test_errs (void)
 {
@@ -1840,13 +1484,13 @@ void pkcs1_test(void)
 
       /* decode it */
       l2 = sizeof(buf[2]);
-      if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2)) != CRYPT_OK) {
+      if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2, &res1)) != CRYPT_OK) {
          printf("OAEP decode: %s\n", error_to_string(err));
          exit(-1);
       }
 
-      if (l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
-         printf("Outsize == %lu, should have been %lu, msg contents follow.\n", l2, l3);
+      if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
+         printf("res == %d, Outsize == %lu, should have been %lu, msg contents follow.\n", res1, l2, l3);
          printf("ORIGINAL:\n");
          for (x = 0; x < l3; x++) {
              printf("%02x ", buf[0][x]);
@@ -1959,16 +1603,12 @@ main (void)
   rng_tests ();
   test_prime();
 
-#ifdef KR
-  kr_test ();
-#endif
   dsa_tests();
   rsa_test ();
   pad_test ();
   ecc_tests ();
   dh_tests ();
 
-  gf_tests ();
   base64_test ();
 
   time_ecb ();

+ 0 - 1985
demos/test.c~

@@ -1,1985 +0,0 @@
-/* This is the worst code you have ever seen written on purpose.... this code is just a big hack to test
-out the functionality of the library */
-
-#ifdef SONY_PS2
-#include <eetypes.h>
-#include <eeregs.h>
-#include "timer.h"
-#endif
-
-#include <mycrypt.h>
-
-int     errnum;
-
-
-int
-null_setup (const unsigned char *key, int keylen, int num_rounds,
-        symmetric_key * skey)
-{
-  return CRYPT_OK;
-}
-
-void
-null_ecb_encrypt (const unsigned char *pt, unsigned char *ct,
-          symmetric_key * key)
-{
-  memcpy (ct, pt, 8);
-}
-
-void
-null_ecb_decrypt (const unsigned char *ct, unsigned char *pt,
-          symmetric_key * key)
-{
-  memcpy (pt, ct, 8);
-}
-
-int
-null_test (void)
-{
-  return CRYPT_OK;
-}
-
-int
-null_keysize (int *desired_keysize)
-{
-  return CRYPT_OK;
-}
-
-const struct _cipher_descriptor null_desc = {
-  "memcpy()",
-  255,
-  8, 8, 8, 1,
-  &null_setup,
-  &null_ecb_encrypt,
-  &null_ecb_decrypt,
-  &null_test,
-  &null_keysize
-};
-
-
-prng_state prng;
-
-void
-store_tests (void)
-{
-  unsigned char buf[8];
-  unsigned long L;
-  ulong64 LL;
-
-  printf ("LOAD32/STORE32 tests\n");
-  L = 0x12345678UL;
-  STORE32L (L, &buf[0]);
-  L = 0;
-  LOAD32L (L, &buf[0]);
-  if (L != 0x12345678UL) {
-    printf ("LOAD/STORE32 Little don't work\n");
-    exit (-1);
-  }
-  LL = CONST64 (0x01020304050607);
-  STORE64L (LL, &buf[0]);
-  LL = 0;
-  LOAD64L (LL, &buf[0])
-    if (LL != CONST64 (0x01020304050607)) {
-    printf ("LOAD/STORE64 Little don't work\n");
-    exit (-1);
-  }
-
-  L = 0x12345678UL;
-  STORE32H (L, &buf[0]);
-  L = 0;
-  LOAD32H (L, &buf[0]);
-  if (L != 0x12345678UL) {
-    printf ("LOAD/STORE32 High don't work, %08lx\n", L);
-    exit (-1);
-  }
-  LL = CONST64 (0x01020304050607);
-  STORE64H (LL, &buf[0]);
-  LL = 0;
-  LOAD64H (LL, &buf[0])
-    if (LL != CONST64 (0x01020304050607)) {
-    printf ("LOAD/STORE64 High don't work\n");
-    exit (-1);
-  }
-}
-
-void
-cipher_tests (void)
-{
-  int     x;
-
-  printf ("Ciphers compiled in\n");
-  for (x = 0; cipher_descriptor[x].name != NULL; x++) {
-    printf
-      (" %12s (%2d) Key Size: %4d to %4d, Block Size: %3d, Default # of rounds: %2d\n",
-       cipher_descriptor[x].name, cipher_descriptor[x].ID,
-       cipher_descriptor[x].min_key_length * 8,
-       cipher_descriptor[x].max_key_length * 8,
-       cipher_descriptor[x].block_length * 8,
-       cipher_descriptor[x].default_rounds);
-  }
-
-}
-
-void
-ecb_tests (void)
-{
-  int     x;
-
-  printf ("ECB tests\n");
-  for (x = 0; cipher_descriptor[x].name != NULL; x++) {
-    printf (" %12s: ", cipher_descriptor[x].name);
-    if ((errnum = cipher_descriptor[x].test ()) != CRYPT_OK) {
-      printf (" **failed** Reason: %s\n", error_to_string (errnum));
-      exit (-1);
-    } else {
-      printf ("passed\n");
-    }
-  }
-}
-
-#ifdef CBC
-void
-cbc_tests (void)
-{
-  symmetric_CBC cbc;
-  int     x, y;
-  unsigned char blk[32], ct[32], key[32], IV[32];
-  const unsigned char test[] =
-    { 0XFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-  printf ("CBC tests\n");
-  /* ---- CBC ENCODING ---- */
-  /* make up a block and IV */
-  for (x = 0; x < 32; x++)
-    blk[x] = IV[x] = x;
-
-  /* now lets start a cbc session */
-  if ((errnum =
-       cbc_start (find_cipher ("blowfish"), IV, key, 16, 0,
-          &cbc)) != CRYPT_OK) {
-    printf ("CBC Setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets encode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = cbc_encrypt (blk + 8 * x, ct + 8 * x, &cbc)) != CRYPT_OK) {
-      printf ("CBC encrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  zeromem (blk, sizeof (blk));
-
-  /* ---- CBC DECODING ---- */
-  /* make up a IV */
-  for (x = 0; x < 32; x++)
-    IV[x] = x;
-
-  /* now lets start a cbc session */
-  if ((errnum =
-       cbc_start (find_cipher ("blowfish"), IV, key, 16, 0,
-          &cbc)) != CRYPT_OK) {
-    printf ("CBC Setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets decode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = cbc_decrypt (ct + 8 * x, blk + 8 * x, &cbc)) != CRYPT_OK) {
-      printf ("CBC decrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-
-  /* print output */
-  for (x = y = 0; x < 32; x++)
-    if (blk[x] != x)
-      y = 1;
-  printf ("  %s\n", y ? "failed" : "passed");
-
-  /* lets actually check the bytes */
-  memset (IV, 0, 8);
-  IV[0] = 0xFF;         /* IV  = FF 00 00 00 00 00 00 00 */
-  memset (blk, 0, 32);
-  blk[8] = 0xFF;        /* BLK = 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 */
-  cbc_start (find_cipher ("memcpy()"), IV, key, 8, 0, &cbc);
-  cbc_encrypt (blk, ct, &cbc);  /* expect: FF 00 00 00 00 00 00 00 */
-  cbc_encrypt (blk + 8, ct + 8, &cbc);  /* expect: 00 00 00 00 00 00 00 00 */
-  if (memcmp (ct, test, 16)) {
-    printf ("CBC failed logical testing.\n");
-    for (x = 0; x < 16; x++)
-      printf ("%02x ", ct[x]);
-    printf ("\n");
-    exit (-1);
-  } else {
-    printf ("CBC passed logical testing.\n");
-  }
-}
-#else
-void
-cbc_tests (void)
-{
-  printf ("CBC not compiled in\n");
-}
-#endif
-
-#ifdef OFB
-void
-ofb_tests (void)
-{
-  symmetric_OFB ofb;
-  int     x, y;
-  unsigned char blk[32], ct[32], key[32], IV[32];
-
-  printf ("OFB tests\n");
-  /* ---- ofb ENCODING ---- */
-  /* make up a block and IV */
-  for (x = 0; x < 32; x++)
-    blk[x] = IV[x] = x;
-
-  /* now lets start a ofb session */
-  if ((errnum =
-       ofb_start (find_cipher ("cast5"), IV, key, 16, 0, &ofb)) != CRYPT_OK) {
-    printf ("OFB Setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets encode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = ofb_encrypt (blk + 8 * x, ct + 8 * x, 8, &ofb)) != CRYPT_OK) {
-      printf ("OFB encrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  zeromem (blk, sizeof (blk));
-
-  /* ---- ofb DECODING ---- */
-  /* make up a IV */
-  for (x = 0; x < 32; x++)
-    IV[x] = x;
-
-  /* now lets start a ofb session */
-  if ((errnum =
-       ofb_start (find_cipher ("cast5"), IV, key, 16, 0, &ofb)) != CRYPT_OK) {
-    printf ("OFB setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets decode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = ofb_decrypt (ct + 8 * x, blk + 8 * x, 8, &ofb)) != CRYPT_OK) {
-      printf ("OFB decrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  /* print output */
-  for (x = y = 0; x < 32; x++)
-    if (blk[x] != x)
-      y = 1;
-  printf ("  %s\n", y ? "failed" : "passed");
-  if (y)
-    exit (-1);
-}
-#else
-void
-ofb_tests (void)
-{
-  printf ("OFB not compiled in\n");
-}
-#endif
-
-#ifdef CFB
-void
-cfb_tests (void)
-{
-  symmetric_CFB cfb;
-  int     x, y;
-  unsigned char blk[32], ct[32], key[32], IV[32];
-
-  printf ("CFB tests\n");
-  /* ---- cfb ENCODING ---- */
-  /* make up a block and IV */
-  for (x = 0; x < 32; x++)
-    blk[x] = IV[x] = x;
-
-  /* now lets start a cfb session */
-  if ((errnum =
-       cfb_start (find_cipher ("blowfish"), IV, key, 16, 0,
-          &cfb)) != CRYPT_OK) {
-    printf ("CFB setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets encode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = cfb_encrypt (blk + 8 * x, ct + 8 * x, 8, &cfb)) != CRYPT_OK) {
-      printf ("CFB encrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  zeromem (blk, sizeof (blk));
-
-  /* ---- cfb DECODING ---- */
-  /* make up ahash_descriptor[prng->yarrow.hash].hashsize IV */
-  for (x = 0; x < 32; x++)
-    IV[x] = x;
-
-  /* now lets start a cfb session */
-  if ((errnum =
-       cfb_start (find_cipher ("blowfish"), IV, key, 16, 0,
-          &cfb)) != CRYPT_OK) {
-    printf ("CFB Setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets decode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = cfb_decrypt (ct + 8 * x, blk + 8 * x, 8, &cfb)) != CRYPT_OK) {
-      printf ("CFB decrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  /* print output */
-  for (x = y = 0; x < 32; x++)
-    if (blk[x] != x)
-      y = 1;
-  printf ("  %s\n", y ? "failed" : "passed");
-  if (y)
-    exit (-1);
-}
-#else
-void
-cfb_tests (void)
-{
-  printf ("CFB not compiled in\n");
-}
-#endif
-
-#ifdef CTR
-void
-ctr_tests (void)
-{
-  symmetric_CTR ctr;
-  int     x, y;
-  unsigned char blk[32], ct[32], key[32], count[32];
-  const unsigned char test[] =
-    { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0 };
-
-  printf ("CTR tests\n");
-  /* ---- CTR ENCODING ---- */
-  /* make up a block and IV */
-  for (x = 0; x < 32; x++)
-    blk[x] = count[x] = x;
-
-  /* now lets start a ctr session */
-  if ((errnum =
-       ctr_start (find_cipher ("xtea"), count, key, 16, 0,
-          &ctr)) != CRYPT_OK) {
-    printf ("CTR Setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets encode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = ctr_encrypt (blk + 8 * x, ct + 8 * x, 8, &ctr)) != CRYPT_OK) {
-      printf ("CTR encrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  zeromem (blk, sizeof (blk));
-
-  /* ---- CTR DECODING ---- */
-  /* make up a IV */
-  for (x = 0; x < 32; x++)
-    count[x] = x;
-
-  /* now lets start a cbc session */
-  if ((errnum =
-       ctr_start (find_cipher ("xtea"), count, key, 16, 0,
-          &ctr)) != CRYPT_OK) {
-    printf ("CTR Setup: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now lets decode 32 bytes */
-  for (x = 0; x < 4; x++) {
-    if ((errnum = ctr_decrypt (ct + 8 * x, blk + 8 * x, 8, &ctr)) != CRYPT_OK) {
-      printf ("CTR decrypt: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-  }
-
-  /* print output */
-  for (x = y = 0; x < 32; x++)
-    if (blk[x] != x)
-      y = 1;
-  printf ("  %s\n", y ? "failed" : "passed");
-  if (y)
-    exit (-1);
-
-  /* lets actually check the bytes */
-  memset (count, 0, 8);
-  count[0] = 0xFF;      /* IV  = FF 00 00 00 00 00 00 00 */
-  memset (blk, 0, 32);
-  blk[9] = 2;           /* BLK = 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 */
-  ctr_start (find_cipher ("memcpy()"), count, key, 8, 0, &ctr);
-  ctr_encrypt (blk, ct, 8, &ctr);   /* expect: FF 00 00 00 00 00 00 00 */
-  ctr_encrypt (blk + 8, ct + 8, 8, &ctr);   /* expect: 00 03 00 00 00 00 00 00 */
-  if (memcmp (ct, test, 16)) {
-    printf ("CTR failed logical testing.\n");
-    for (x = 0; x < 16; x++)
-      printf ("%02x ", ct[x]);
-    printf ("\n");
-  } else {
-    printf ("CTR passed logical testing.\n");
-  }
-
-}
-#else
-void
-ctr_tests (void)
-{
-  printf ("CTR not compiled in\n");
-}
-#endif
-
-void
-hash_tests (void)
-{
-  int     x;
-  printf ("Hash tests\n");
-  for (x = 0; hash_descriptor[x].name != NULL; x++) {
-    printf (" %10s (%2d) ", hash_descriptor[x].name, hash_descriptor[x].ID);
-    if ((errnum = hash_descriptor[x].test ()) != CRYPT_OK) {
-      printf ("**failed** Reason: %s\n", error_to_string (errnum));
-      exit(-1);
-    } else {
-      printf ("passed\n");
-    }
-  }
-}
-
-#ifdef MRSA
-void
-pad_test (void)
-{
-  unsigned char in[100], out[100];
-  unsigned long x, y;
-
-  /* make a dummy message */
-  for (x = 0; x < 16; x++)
-    in[x] = (unsigned char) x;
-
-  /* pad the message so that random filler is placed before and after it */
-  y = 100;
-  if ((errnum =
-       rsa_pad (in, 16, out, &y, find_prng ("yarrow"), &prng)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* depad the message to get the original content */
-  memset (in, 0, sizeof (in));
-  x = 100;
-  if ((errnum = rsa_depad (out, y, in, &x)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check outcome */
-  printf ("rsa_pad: ");
-  if (x != 16) {
-    printf ("Failed.  Wrong size.\n");
-    exit (-1);
-  }
-  for (x = 0; x < 16; x++)
-    if (in[x] != x) {
-      printf ("Failed.  Expected %02lx and got %02x.\n", x, in[x]);
-      exit (-1);
-    }
-  printf ("passed.\n");
-}
-void
-rsa_test (void)
-{
-  unsigned char in[520], out[520];
-  unsigned long x, y, z, limit;
-  int     stat;
-  rsa_key key;
-  clock_t t;
-
-  /* ---- SINGLE ENCRYPT ---- */
-  /* encrypt a short 8 byte string */
-  if ((errnum =
-       rsa_make_key (&prng, find_prng ("yarrow"), 1024 / 8, 65537,
-             &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  for (x = 0; x < 8; x++)
-    in[x] = (unsigned char) (x + 1);
-  y = sizeof (in);
-  if ((errnum = rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* decrypt it */
-  zeromem (in, sizeof (in));
-  x = sizeof (out);
-  if ((errnum = rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* compare */
-  printf ("RSA    : ");
-  for (x = 0; x < 8; x++)
-    if (in[x] != (x + 1)) {
-      printf ("Failed.  x==%02lx, in[%ld]==%02x\n", x, x, in[x]);
-      exit (-1);
-    }
-  printf ("passed.\n");
-
-  /* test the rsa_encrypt_key functions */
-  for (x = 0; x < 16; x++)
-    in[x] = x;
-  y = sizeof (out);
-  if ((errnum =
-       rsa_encrypt_key (in, 16, out, &y, &prng, find_prng ("yarrow"),
-            &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  zeromem (in, sizeof (in));
-  x = sizeof (in);
-  if ((errnum = rsa_decrypt_key (out, y, in, &x, &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("RSA en/de crypt key routines: ");
-  if (x != 16) {
-    printf ("Failed (length)\n");
-    exit (-1);
-  }
-  for (x = 0; x < 16; x++)
-    if (in[x] != x) {
-      printf ("Failed (contents)\n");
-      exit (-1);
-    }
-  printf ("Passed\n");
-
-  /* test sign_hash functions */
-  for (x = 0; x < 16; x++)
-    in[x] = x;
-  x = sizeof (in);
-  if ((errnum = rsa_sign_hash (in, 16, out, &x, &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("RSA signed hash: %lu bytes\n", x);
-  if ((errnum = rsa_verify_hash (out, x, in, &stat, &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("Verify hash: %s, ", stat ? "passed" : "failed");
-  in[0] ^= 1;
-  if ((errnum = rsa_verify_hash (out, x, in, &stat, &key)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("%s\n", (!stat) ? "passed" : "failed");
-  if (stat)
-    exit (-1);
-  rsa_free (&key);
-
-  /* make a RSA key */
-#ifdef SONY_PS2_NOPE
-  limit = 1024;
-#else
-  limit = 2048;
-#endif
-
-  {
-    int     tt;
-
-    for (z = 1024; z <= limit; z += 512) {
-      t = XCLOCK ();
-      for (tt = 0; tt < 3; tt++) {
-         if ((errnum = rsa_make_key (&prng, find_prng ("yarrow"), z / 8, 65537, &key)) != CRYPT_OK) {
-            printf ("Error: %s\n", error_to_string (errnum));
-            exit (-1);
-         }
-
-         /* check modulus size */
-         if (mp_unsigned_bin_size(&key.N) != (int)(z/8)) { 
-            printf("\nRSA key supposed to be %lu bits but was %d bits\n", z, mp_count_bits(&key.N));
-            exit(EXIT_FAILURE);
-         }
-
-         if (tt < 2) {
-            rsa_free (&key);
-         }
-      }
-      t = XCLOCK () - t;
-      printf ("Took %.0f ms to make a %ld-bit RSA key.\n", 1000.0 * (((double) t / 3.0) / (double) XCLOCKS_PER_SEC), z);
-
-      /* time encryption */
-      t = XCLOCK ();
-
-      for (tt = 0; tt < 20; tt++) {
-         y = sizeof (in);
-         if ((errnum = rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) {
-            printf ("Error: %s\n", error_to_string (errnum));
-            exit (-1);
-         }
-      }
-      t = XCLOCK () - t;
-      printf ("Took %.0f ms to encrypt with a %ld-bit RSA key.\n",
-              1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z);
-
-      /* time decryption */
-      t = XCLOCK ();
-      for (tt = 0; tt < 20; tt++) {
-          x = sizeof (out);
-          if ((errnum = rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
-             printf ("Error: %s\n", error_to_string (errnum));
-             exit (-1);
-          }
-      }
-      t = XCLOCK () - t;
-      printf ("Took %.0f ms to decrypt with a %ld-bit RSA key.\n",
-      1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z);
-      rsa_free (&key);
-    }
-  }
-}
-#else
-void
-pad_test (void)
-{
-  printf ("MRSA not compiled in\n");
-}
-
-void
-rsa_test (void)
-{
-  printf ("MRSA not compiled in\n");
-}
-#endif
-
-#ifdef BASE64
-void
-base64_test (void)
-{
-  unsigned char buf[2][100];
-  unsigned long x, y;
-
-  printf ("Base64 tests\n");
-  zeromem (buf, sizeof (buf));
-  for (x = 0; x < 16; x++)
-    buf[0][x] = (unsigned char) x;
-
-  x = 100;
-  if (base64_encode (buf[0], 16, buf[1], &x) != CRYPT_OK) {
-    printf ("  error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("  encoded 16 bytes to %ld bytes...[%s]\n", x, buf[1]);
-  memset (buf[0], 0, 100);
-  y = 100;
-  if (base64_decode (buf[1], x, buf[0], &y) != CRYPT_OK) {
-    printf ("  error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("  decoded %ld bytes to %ld bytes\n", x, y);
-  for (x = 0; x < 16; x++)
-    if (buf[0][x] != x) {
-      printf (" **failed**\n");
-      exit (-1);
-    }
-  printf ("  passed\n");
-}
-#else
-void
-base64_test (void)
-{
-  printf ("Base64 not compiled in\n");
-}
-#endif
-
-void
-time_hash (void)
-{
-  clock_t t1;
-  int     x, y;
-  unsigned long z;
-  unsigned char input[4096], out[MAXBLOCKSIZE];
-  printf ("Hash Time Trials (4KB blocks):\n");
-  for (x = 0; hash_descriptor[x].name != NULL; x++) {
-    t1 = XCLOCK ();
-    z = sizeof (out);
-    y = 0;
-    while (XCLOCK () - t1 < (5 * XCLOCKS_PER_SEC)) {
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      hash_memory (x, input, 4096, out, &z);
-      y += 32;
-    }
-    t1 = XCLOCK () - t1;
-    printf ("%-20s: Hash at %5.2f Mbit/sec\n", hash_descriptor[x].name,
-        ((8.0 * 4096.0) *
-         ((double) y / ((double) t1 / (double) XCLOCKS_PER_SEC))) /
-        1000000.0);
-  }
-}
-
-void
-time_ecb (void)
-{
-  clock_t t1, t2;
-  long    x, y1, y2;
-  unsigned char pt[32], key[32];
-  symmetric_key skey;
-  void    (*func) (const unsigned char *, unsigned char *, symmetric_key *);
-
-  printf ("ECB Time Trials for the Symmetric Ciphers:\n");
-  for (x = 0; cipher_descriptor[x].name != NULL; x++) {
-    cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0,
-                &skey);
-
-#define DO1   func(pt,pt,&skey);
-#define DO2   DO1 DO1
-#define DO4   DO2 DO2
-#define DO8   DO4 DO4
-#define DO16  DO8 DO8
-#define DO32  DO16 DO16
-#define DO64  DO32 DO32
-#define DO128 DO64 DO64
-#define DO256 DO128 DO128
-
-    func = cipher_descriptor[x].ecb_encrypt;
-    y1 = 0;
-    t1 = XCLOCK ();
-    while (XCLOCK () - t1 < 3 * XCLOCKS_PER_SEC) {
-      DO256;
-      y1 += 256;
-    }
-    t1 = XCLOCK () - t1;
-
-    func = cipher_descriptor[x].ecb_decrypt;
-    y2 = 0;
-    t2 = XCLOCK ();
-    while (XCLOCK () - t2 < 3 * XCLOCKS_PER_SEC) {
-      DO256;
-      y2 += 256;
-    }
-    t2 = XCLOCK () - t2;
-    printf
-      ("%-20s: Encrypt at %5.2f Mbit/sec and Decrypt at %5.2f Mbit/sec\n",
-       cipher_descriptor[x].name,
-       ((8.0 * (double) cipher_descriptor[x].block_length) *
-    ((double) y1 / ((double) t1 / (double) XCLOCKS_PER_SEC))) / 1000000.0,
-       ((8.0 * (double) cipher_descriptor[x].block_length) *
-    ((double) y2 / ((double) t2 / (double) XCLOCKS_PER_SEC))) /
-       1000000.0);
-
-#undef DO256
-#undef DO128
-#undef DO64
-#undef DO32
-#undef DO16
-#undef DO8
-#undef DO4
-#undef DO2
-#undef DO1
-  }
-}
-
-#ifdef MDH
-void
-dh_tests (void)
-{
-  unsigned char buf[3][4096];
-  unsigned long x, y, z;
-  int     low, high, stat, stat2;
-  dh_key  usera, userb;
-  clock_t t1;
-
-  printf("Testing builting DH parameters...."); fflush(stdout);
-  if ((errnum = dh_test()) != CRYPT_OK) {
-     printf("DH Error: %s\n", error_to_string(errnum));
-     exit(-1);
-  }
-  printf("Passed.\n");
-
-  dh_sizes (&low, &high);
-  printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8);
-
-  /* make up two keys */
-  if ((errnum =
-       dh_make_key (&prng, find_prng ("yarrow"), 96, &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  if ((errnum =
-       dh_make_key (&prng, find_prng ("yarrow"), 96, &userb)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make the shared secret */
-  x = 4096;
-  if ((errnum = dh_shared_secret (&usera, &userb, buf[0], &x)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  y = 4096;
-  if ((errnum = dh_shared_secret (&userb, &usera, buf[1], &y)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  if (y != x) {
-    printf ("DH Shared keys are not same size.\n");
-    exit (-1);
-  }
-  if (memcmp (buf[0], buf[1], x)) {
-    printf ("DH Shared keys not same contents.\n");
-    exit (-1);
-  }
-
-  /* now export userb */
-  y = 4096;
-  if ((errnum = dh_export (buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  dh_free (&userb);
-
-  /* import and make the shared secret again */
-  if ((errnum = dh_import (buf[1], y, &userb)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  z = 4096;
-  if ((errnum = dh_shared_secret (&usera, &userb, buf[2], &z)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  printf ("DH routines: ");
-  if (z != x) {
-    printf ("failed.  Size don't match?\n");
-    exit (-1);
-  }
-  if (memcmp (buf[0], buf[2], x)) {
-    printf ("Failed.  Content didn't match.\n");
-    exit (-1);
-  }
-  printf ("Passed\n");
-  dh_free (&usera);
-  dh_free (&userb);
-
-/* time stuff */
-  {
-    static int sizes[] = { 96, 128, 160, 192, 224, 256, 320, 384, 512 };
-    int     ii, tt;
-
-    for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) {
-      t1 = XCLOCK ();
-      for (tt = 0; tt < 25; tt++) {
-    dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera);
-    dh_free (&usera);
-      }
-      t1 = XCLOCK () - t1;
-      printf ("Make dh-%d key took %f msec\n", sizes[ii] * 8,
-          1000.0 * (((double) t1 / 25.0) / (double) XCLOCKS_PER_SEC));
-    }
-  }
-
-/* test encrypt_key */
-  dh_make_key (&prng, find_prng ("yarrow"), 128, &usera);
-  for (x = 0; x < 16; x++)
-    buf[0][x] = x;
-  y = sizeof (buf[1]);
-  if ((errnum =
-       dh_encrypt_key (buf[0], 16, buf[1], &y, &prng, find_prng ("yarrow"),
-               find_hash ("md5"), &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  zeromem (buf[0], sizeof (buf[0]));
-  x = sizeof (buf[0]);
-  if ((errnum = dh_decrypt_key (buf[1], y, buf[0], &x, &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("DH en/de crypt key routines: ");
-  if (x != 16) {
-    printf ("Failed (length)\n");
-    exit (-1);
-  }
-  for (x = 0; x < 16; x++)
-    if (buf[0][x] != x) {
-      printf ("Failed (contents)\n");
-      exit (-1);
-    }
-  printf ("Passed (size %lu)\n", y);
-
-/* test sign_hash */
-  for (x = 0; x < 16; x++)
-    buf[0][x] = x;
-  x = sizeof (buf[1]);
-  if ((errnum =
-       dh_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"),
-             &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  if ((errnum = dh_verify_hash (buf[1], x, buf[0], 16, &stat, &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  buf[0][0] ^= 1;
-  if ((errnum = dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("dh_sign/verify_hash: %s (%d,%d), %lu\n",
-      ((stat == 1)
-       && (stat2 == 0)) ? "passed" : "failed", stat, stat2, x);
-  dh_free (&usera);
-}
-#else
-void
-dh_tests (void)
-{
-  printf ("MDH not compiled in\n");
-}
-#endif
-
-int     callback_x = 0;
-void
-callback (void)
-{
-  printf ("%c\x08", "-\\|/"[++callback_x & 3]);
-#ifndef SONY_PS2
-  fflush (stdout);
-#endif
-}
-
-void
-rng_tests (void)
-{
-  unsigned char buf[16];
-  clock_t t1;
-  int     x, y;
-
-  printf ("RNG tests\n");
-  t1 = XCLOCK ();
-  x = rng_get_bytes (buf, sizeof (buf), &callback);
-  t1 = XCLOCK () - t1;
-  printf ("  %f bytes per second...",
-      (double) x / ((double) t1 / (double) XCLOCKS_PER_SEC));
-  printf ("read %d bytes.\n  ", x);
-  for (y = 0; y < x; y++)
-    printf ("%02x ", buf[y]);
-  printf ("\n");
-
-#ifdef YARROW
-  if ((errnum =
-       rng_make_prng (128, find_prng ("yarrow"), &prng,
-              &callback)) != CRYPT_OK) {
-    printf (" starting yarrow error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-#endif
-}
-
-#ifdef MECC
-void
-ecc_tests (void)
-{
-  unsigned char buf[4][4096];
-  unsigned long x, y, z;
-  int     stat, stat2, low, high;
-  ecc_key usera, userb;
-  clock_t t1;
-
-  if ((errnum = ecc_test ()) != CRYPT_OK) {
-    printf ("ecc Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  ecc_sizes (&low, &high);
-  printf ("ecc Keys from %d to %d supported.\n", low * 8, high * 8);
-
-  /* make up two keys */
-  if ((errnum =
-       ecc_make_key (&prng, find_prng ("yarrow"), 24, &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  if ((errnum =
-       ecc_make_key (&prng, find_prng ("yarrow"), 24, &userb)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make the shared secret */
-  x = 4096;
-  if ((errnum = ecc_shared_secret (&usera, &userb, buf[0], &x)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  y = 4096;
-  if ((errnum = ecc_shared_secret (&userb, &usera, buf[1], &y)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  if (y != x) {
-    printf ("ecc Shared keys are not same size.\n");
-    exit (-1);
-  }
-
-  if (memcmp (buf[0], buf[1], x)) {
-    printf ("ecc Shared keys not same contents.\n");
-    exit (-1);
-  }
-
-  /* now export userb */
-  y = 4096;
-  if ((errnum = ecc_export (buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  ecc_free (&userb);
-  printf ("ECC-192 export took %ld bytes\n", y);
-
-  /* import and make the shared secret again */
-  if ((errnum = ecc_import (buf[1], y, &userb)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  z = 4096;
-  if ((errnum = ecc_shared_secret (&usera, &userb, buf[2], &z)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  printf ("ecc routines: ");
-  if (z != x) {
-    printf ("failed.  Size don't match?\n");
-    exit (-1);
-  }
-  if (memcmp (buf[0], buf[2], x)) {
-    printf ("Failed.  Content didn't match.\n");
-    exit (-1);
-  }
-  printf ("Passed\n");
-  ecc_free (&usera);
-  ecc_free (&userb);
-
-/* time stuff */
-  {
-    static int sizes[] = { 20, 24, 28, 32, 48, 65 };
-    int     ii, tt;
-
-    for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) {
-      t1 = XCLOCK ();
-      for (tt = 0; tt < 10; tt++) {
-    if ((errnum =
-         ecc_make_key (&prng, find_prng ("yarrow"), sizes[ii],
-               &usera)) != CRYPT_OK) {
-      printf ("Error: %s\n", error_to_string (errnum));
-      exit (-1);
-    }
-    ecc_free (&usera);
-      }
-      t1 = XCLOCK () - t1;
-      printf ("Make ECC-%d key took %f msec\n", sizes[ii] * 8,
-          1000.0 * (((double) t1 / 10.0) / (double) XCLOCKS_PER_SEC));
-    }
-  }
-
-/* test encrypt_key */
-  ecc_make_key (&prng, find_prng ("yarrow"), 20, &usera);
-  for (x = 0; x < 32; x++)
-    buf[0][x] = x;
-  y = sizeof (buf[1]);
-  if ((errnum =
-       ecc_encrypt_key (buf[0], 32, buf[1], &y, &prng, find_prng ("yarrow"),
-            find_hash ("sha256"), &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  zeromem (buf[0], sizeof (buf[0]));
-  x = sizeof (buf[0]);
-  if ((errnum = ecc_decrypt_key (buf[1], y, buf[0], &x, &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("ECC en/de crypt key routines: ");
-  if (x != 32) {
-    printf ("Failed (length)\n");
-    exit (-1);
-  }
-  for (x = 0; x < 32; x++)
-    if (buf[0][x] != x) {
-      printf ("Failed (contents)\n");
-      exit (-1);
-    }
-  printf ("Passed (size: %lu)\n", y);
-/* test sign_hash */
-  for (x = 0; x < 16; x++)
-    buf[0][x] = x;
-  x = sizeof (buf[1]);
-  if ((errnum =
-       ecc_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"),
-              &usera)) != CRYPT_OK) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf("Signature size: %lu\n", x);
-  if (ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &usera)) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  buf[0][0] ^= 1;
-  if (ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera)) {
-    printf ("Error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  printf ("ecc_sign/verify_hash: %s (%d,%d)\n",
-      ((stat == 1) && (stat2 == 0)) ? "passed" : "failed", stat, stat2);
-  ecc_free (&usera);
-}
-#else
-void
-ecc_tests (void)
-{
-  printf ("MECC not compiled in\n");
-}
-#endif
-
-#ifdef GF
-void
-gf_tests (void)
-{
-  gf_int  a, b, c, d;
-  int     n;
-  unsigned char buf[1024];
-
-  printf ("GF tests\n");
-  gf_zero (a);
-  gf_zero (b);
-  gf_zero (c);
-  gf_zero (d);
-
-  /* a == 0x18000000b */
-  a[1] = 1;
-  a[0] = 0x8000000bUL;
-
-  /* b == 0x012345678 */
-  b[0] = 0x012345678UL;
-
-  /* find 1/b mod a */
-  gf_invmod (b, a, c);
-
-  /* find 1/1/b mod a */
-  gf_invmod (c, a, d);
-
-  /* display them */
-  printf ("  %08lx %08lx\n", c[0], d[0]);
-
-  /* store as binary string */
-  n = gf_size (a);
-  printf ("  a takes %d bytes\n", n);
-  gf_toraw (a, buf);
-  gf_readraw (a, buf, n);
-  printf ("  a == %08lx%08lx\n", a[1], a[0]);
-
-  /* primality testing */
-  gf_zero (a);
-  a[0] = 0x169;
-  printf ("  GF prime: %s, ", gf_is_prime (a) ? "passed" : "failed");
-  a[0] = 0x168;
-  printf ("  %s\n", gf_is_prime (a) ? "failed" : "passed");
-
-  /* test sqrt code */
-  gf_zero (a);
-  a[1] = 0x00000001;
-  a[0] = 0x8000000bUL;
-  gf_zero (b);
-  b[0] = 0x12345678UL;
-
-  gf_sqrt (b, a, c);
-  gf_mulmod (c, c, a, b);
-  printf ("  (%08lx)^2 = %08lx (mod %08lx%08lx) \n", c[0], b[0], a[1], a[0]);
-}
-#else
-void
-gf_tests (void)
-{
-  printf ("GF not compiled in\n");
-}
-#endif
-
-#ifdef MPI
-void
-test_prime (void)
-{
-  char buf[1024];
-  mp_int  a;
-  int     x;
-
-  /* make a 1024 bit prime */
-  mp_init (&a);
-  rand_prime (&a, 128*8, &prng, find_prng ("yarrow"));
-
-  /* dump it */
-  mp_todecimal (&a, buf);
-  printf ("1024-bit prime:\n");
-  for (x = 0; x < (int) strlen (buf);) {
-    printf ("%c", buf[x]);
-    if (!(++x % 60))
-      printf ("\\ \n");
-  }
-  printf ("\n\n");
-
-  mp_clear (&a);
-}
-#else
-void
-test_prime (void)
-{
-  printf ("MPI not compiled in\n");
-}
-#endif
-
-void
-register_all_algs (void)
-{
-#ifdef RIJNDAEL
-  register_cipher (&aes_desc);
-#endif
-#ifdef BLOWFISH
-  register_cipher (&blowfish_desc);
-#endif
-#ifdef XTEA
-  register_cipher (&xtea_desc);
-#endif
-#ifdef RC5
-  register_cipher (&rc5_desc);
-#endif
-#ifdef RC6
-  register_cipher (&rc6_desc);
-#endif
-#ifdef SAFERP
-  register_cipher (&saferp_desc);
-#endif
-#ifdef TWOFISH
-  register_cipher (&twofish_desc);
-#endif
-#ifdef SAFER
-  register_cipher (&safer_k64_desc);
-  register_cipher (&safer_sk64_desc);
-  register_cipher (&safer_k128_desc);
-  register_cipher (&safer_sk128_desc);
-#endif
-#ifdef RC2
-  register_cipher (&rc2_desc);
-#endif
-#ifdef DES
-  register_cipher (&des_desc);
-  register_cipher (&des3_desc);
-#endif
-#ifdef CAST5
-  register_cipher (&cast5_desc);
-#endif
-#ifdef NOEKEON
-  register_cipher (&noekeon_desc);
-#endif
-#ifdef SKIPJACK
-  register_cipher (&skipjack_desc);
-#endif
-  register_cipher (&null_desc);
-
-#ifdef TIGER
-  register_hash (&tiger_desc);
-#endif
-#ifdef MD2
-  register_hash (&md2_desc);
-#endif
-#ifdef MD4
-  register_hash (&md4_desc);
-#endif
-#ifdef MD5
-  register_hash (&md5_desc);
-#endif
-#ifdef SHA1
-  register_hash (&sha1_desc);
-#endif
-#ifdef SHA256
-  register_hash (&sha256_desc);
-#endif
-#ifdef SHA224
-  register_hash (&sha224_desc);
-#endif
-#ifdef SHA384
-  register_hash (&sha384_desc);
-#endif
-#ifdef SHA512
-  register_hash (&sha512_desc);
-#endif
-#ifdef RIPEMD128
-  register_hash (&rmd128_desc);
-#endif
-#ifdef RIPEMD160
-  register_hash (&rmd160_desc);
-#endif
-#ifdef WHIRLPOOL
-  register_hash (&whirlpool_desc);
-#endif
-
-#ifdef YARROW
-  register_prng (&yarrow_desc);
-#endif
-#ifdef SPRNG
-  register_prng (&sprng_desc);
-#endif
-}
-
-#ifdef KR
-void
-kr_display (pk_key * kr)
-{
-  static const char *sys[] = { "NON-KEY", "RSA", "DH", "ECC" };
-  static const char *type[] = { "PRIVATE", "PUBLIC", "PRIVATE_OPTIMIZED" };
-
-  while (kr->system != NON_KEY) {
-    printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
-        sys[kr->system], type[kr->key_type], kr->name, kr->email,
-        kr->description);
-    kr = kr->next;
-  }
-  printf ("\n");
-}
-
-void
-kr_test_makekeys (pk_key ** kr)
-{
-  if ((errnum = kr_init (kr)) != CRYPT_OK) {
-    printf ("KR init error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a DH key */
-  printf ("KR: Making DH key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey",
-            "[email protected]", "dhkey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a ECC key */
-  printf ("KR: Making ECC key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey",
-            "[email protected]", "ecckey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a RSA key */
-  printf ("KR: Making RSA key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey",
-            "[email protected]", "rsakey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-}
-
-void
-kr_test (void)
-{
-  pk_key *kr, *_kr;
-  unsigned char buf[8192], buf2[8192], buf3[8192];
-  unsigned long len;
-  int     i, j, stat;
-#ifndef NO_FILE
-  FILE   *f;
-#endif
-
-  kr_test_makekeys (&kr);
-
-  printf ("The original list:\n");
-  kr_display (kr);
-
-  for (i = 0; i < 3; i++) {
-    len = sizeof (buf);
-    if ((errnum = kr_export (kr, kr->ID, kr->key_type, buf, &len)) != CRYPT_OK) {
-      printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("Exported key was: %lu bytes\n", len);
-    if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
-      printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-    if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-      printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-  }
-
-  for (i = 0; i < 3; i++) {
-    len = sizeof (buf);
-    if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-      printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("Exported key was: %lu bytes\n", len);
-    if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
-      printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-    if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-      printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-  }
-
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("Error clearing ring: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-
-/* TEST output to file */
-#ifndef NO_FILE
-
-  if ((errnum = kr_init (&kr)) != CRYPT_OK) {
-    printf ("KR init error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_test_makekeys (&kr);
-
-  /* save to file */
-  f = fopen ("ring.dat", "wb");
-  if ((errnum = kr_save (kr, f, NULL)) != CRYPT_OK) {
-    printf ("kr_save error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  fclose (f);
-
-  /* delete and load */
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("clear error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  f = fopen ("ring.dat", "rb");
-  if ((errnum = kr_load (&kr, f, NULL)) != CRYPT_OK) {
-    printf ("kr_load error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  fclose (f);
-  remove ("ring.dat");
-  printf ("After load and save...\n");
-  kr_display (kr);
-
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("clear error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-#endif
-
-/* test the packet encryption/sign stuff */
-  for (i = 0; i < 32; i++)
-    buf[i] = i;
-  kr_test_makekeys (&kr);
-  _kr = kr;
-  for (i = 0; i < 3; i++) {
-    printf ("Testing a key with system %d, type %d:\t", _kr->system,
-        _kr->key_type);
-    len = sizeof (buf2);
-    if ((errnum =
-     kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
-             find_prng ("yarrow"),
-             find_hash ("md5"))) != CRYPT_OK) {
-      printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    len = sizeof (buf3);
-    if ((errnum = kr_decrypt_key (kr, buf2, buf3, &len)) != CRYPT_OK) {
-      printf ("decrypt error, %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    if (len != 16 || memcmp (buf3, buf, 16)) {
-      printf ("kr_decrypt_key failed, %i, %lu\n", i, len);
-      exit (-1);
-    }
-    printf ("kr_encrypt_key passed, ");
-
-    len = sizeof (buf2);
-    if ((errnum =
-     kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
-               find_prng ("yarrow"))) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("kr_sign_hash: ");
-    if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("%s, ", stat ? "passed" : "failed");
-    buf[15] ^= 1;
-    if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("%s\n", (!stat) ? "passed" : "failed");
-    buf[15] ^= 1;
-
-    len = sizeof (buf);
-    if ((errnum =
-     kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
-             &len)) != CRYPT_OK) {
-      printf ("kr_fingerprint failed, %i, %lu\n", i, len);
-      exit (-1);
-    }
-    printf ("Fingerprint:  ");
-    for (j = 0; j < 20; j++) {
-      printf ("%02x", buf[j]);
-      if (j < 19)
-    printf (":");
-    }
-    printf ("\n\n");
-
-    _kr = _kr->next;
-  }
-
-/* Test encrypting/decrypting to a public key */
-/* first dump the other two keys */
-  kr_del (&kr, kr->ID);
-  kr_del (&kr, kr->ID);
-  kr_display (kr);
-
-  /* now export it as public and private */
-  len = sizeof (buf);
-  if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-    printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check boundaries */
-  memset (buf + len, 0, sizeof (buf) - len);
-
-  len = sizeof (buf2);
-  if ((errnum = kr_export (kr, kr->ID, PK_PRIVATE, buf2, &len)) != CRYPT_OK) {
-    printf ("Error exporting key  %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check boundaries */
-  memset (buf2 + len, 0, sizeof (buf2) - len);
-
-  /* delete the key and import the public */
-  kr_clear (&kr);
-  kr_init (&kr);
-  kr_display (kr);
-  if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-    printf ("Error importing key %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_display (kr);
-
-  /* now encrypt a buffer */
-  for (i = 0; i < 16; i++)
-    buf[i] = i;
-  len = sizeof (buf3);
-  if ((errnum =
-       kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng,
-               find_prng ("yarrow"),
-               find_hash ("md5"))) != CRYPT_OK) {
-    printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now delete the key and import the private one */
-  kr_clear (&kr);
-  kr_init (&kr);
-  kr_display (kr);
-  if ((errnum = kr_import (kr, buf2, len)) != CRYPT_OK) {
-    printf ("Error importing key %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_display (kr);
-
-  /* now decrypt */
-  len = sizeof (buf2);
-  if ((errnum = kr_decrypt_key (kr, buf3, buf2, &len)) != CRYPT_OK) {
-    printf ("decrypt error, %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  printf ("KR encrypt to public, decrypt with private: ");
-  if (len == 16 && !memcmp (buf2, buf, 16)) {
-    printf ("passed\n");
-  } else {
-    printf ("failed\n");
-  }
-
-  kr_clear (&kr);
-}
-#endif
-
-void
-test_errs (void)
-{
-#define ERR(x)  printf("%25s => %s\n", #x, error_to_string(x));
-
-  ERR (CRYPT_OK);
-  ERR (CRYPT_ERROR);
-
-  ERR (CRYPT_INVALID_KEYSIZE);
-  ERR (CRYPT_INVALID_ROUNDS);
-  ERR (CRYPT_FAIL_TESTVECTOR);
-
-  ERR (CRYPT_BUFFER_OVERFLOW);
-  ERR (CRYPT_INVALID_PACKET);
-
-  ERR (CRYPT_INVALID_PRNGSIZE);
-  ERR (CRYPT_ERROR_READPRNG);
-
-  ERR (CRYPT_INVALID_CIPHER);
-  ERR (CRYPT_INVALID_HASH);
-  ERR (CRYPT_INVALID_PRNG);
-
-  ERR (CRYPT_MEM);
-
-  ERR (CRYPT_PK_TYPE_MISMATCH);
-  ERR (CRYPT_PK_NOT_PRIVATE);
-
-  ERR (CRYPT_INVALID_ARG);
-  ERR (CRYPT_FILE_NOTFOUND);
-
-  ERR (CRYPT_PK_INVALID_TYPE);
-  ERR (CRYPT_PK_INVALID_SYSTEM);
-  ERR (CRYPT_PK_DUP);
-  ERR (CRYPT_PK_NOT_FOUND);
-  ERR (CRYPT_PK_INVALID_SIZE);
-
-  ERR (CRYPT_INVALID_PRIME_SIZE);
-}
-
-
-void dsa_tests(void)
-{
-   unsigned char msg[16], out[1024], out2[1024];
-   unsigned long x, y;
-   int err, stat1, stat2;
-   dsa_key key, key2;
-
-   /* make a random key */
-   if ((err = dsa_make_key(&prng, find_prng("yarrow"), 20, 128, &key)) != CRYPT_OK) {
-      printf("Error making DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("DSA Key Made\n");
-
-   /* verify it */
-   if ((err = dsa_verify_key(&key, &stat1)) != CRYPT_OK) {
-      printf("Error verifying DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("DSA key verification: %s\n", stat1 == 1 ? "passed" : "failed");
-   if (stat1 == 0) exit(-1);     
-
-   /* sign the message */
-   x = sizeof(out);
-   if ((err = dsa_sign_hash(msg, sizeof(msg), out, &x, &prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
-      printf("Error signing with DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("DSA 160/1024 signature is %lu bytes long\n", x);
-
-   /* verify it once */
-   if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key)) != CRYPT_OK) {
-      printf("Error verifying with DSA key 1: %s\n", error_to_string(err));
-      exit(-1);
-   }
-
-   /* Modify and verify again */
-   msg[0] ^= 1;
-   if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key)) != CRYPT_OK) {
-      printf("Error verifying with DSA key 2: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   msg[0] ^= 1;
-   printf("DSA Verification: %d, %d, %s\n", stat1, stat2, (stat1 == 1 && stat2 == 0) ? "passed" : "failed");
-   if (!(stat1 == 1 && stat2 == 0)) exit(-1);
-
-   /* test exporting it */
-   x = sizeof(out2);
-   if ((err = dsa_export(out2, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
-      printf("Error export PK_PRIVATE DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("Exported PK_PRIVATE DSA key in %lu bytes\n", x);
-   if ((err = dsa_import(out2, x, &key2)) != CRYPT_OK) {
-      printf("Error importing PK_PRIVATE DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   /* verify a signature with it */
-   if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)) != CRYPT_OK) {
-      printf("Error verifying with DSA key 3: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("PRIVATE Import Test: %s\n", stat1 == 1 ? "passed" : "failed");
-   if (stat1 == 0) exit(-1);
-   dsa_free(&key2);
-
-   /* export as public now */
-   x = sizeof(out2);
-   if ((err = dsa_export(out2, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
-      printf("Error export PK_PUBLIC DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("Exported PK_PUBLIC DSA key in %lu bytes\n", x);
-   if ((err = dsa_import(out2, x, &key2)) != CRYPT_OK) {
-      printf("Error importing PK_PUBLIC DSA key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   /* verify a signature with it */
-   if ((err = dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)) != CRYPT_OK) {
-      printf("Error verifying with DSA key 4: %s\n", error_to_string(err));
-      exit(-1);
-   }
-   printf("PUBLIC Import Test: %s\n", stat1 == 1 ? "passed" : "failed");
-   if (stat1 == 0) exit(-1);
-
-   dsa_free(&key2);
-   dsa_free(&key);
-}
-
-#ifdef PKCS_1
-void pkcs1_test(void)
-{
-   unsigned char buf[3][128];
-   int err, res1, res2, res3, prng_idx, hash_idx;
-   unsigned long x, y, l1, l2, l3, i1, i2;
-
-   /* get hash/prng  */
-   hash_idx = find_hash("sha1");
-   prng_idx = find_prng("yarrow");
-
-   /* do many tests */
-   for (x = 0; x < 10000; x++) {
-      zeromem(buf, sizeof(buf));
-
-      /* make a dummy message (of random length) */
-      l3 = (rand() & 31) + 8;
-      for (y = 0; y < l3; y++) buf[0][y] = rand() & 255;
-
-      /* encode it */
-      l1 = sizeof(buf[1]);
-      if ((err = pkcs_1_oaep_encode(buf[0], l3, NULL, 0, 1024, hash_idx, prng_idx, &prng, buf[1], &l1)) != CRYPT_OK) {
-         printf("OAEP encode: %s\n", error_to_string(err));
-         exit(-1);
-      }
-
-      /* decode it */
-      l2 = sizeof(buf[2]);
-      if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2)) != CRYPT_OK) {
-         printf("OAEP decode: %s\n", error_to_string(err));
-         exit(-1);
-      }
-
-      if (l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
-         printf("Outsize == %lu, should have been %lu, msg contents follow.\n", l2, l3);
-         printf("ORIGINAL:\n");
-         for (x = 0; x < l3; x++) {
-             printf("%02x ", buf[0][x]);
-         }
-         printf("\nRESULT:\n");
-         for (x = 0; x < l2; x++) {
-             printf("%02x ", buf[2][x]);
-         }
-         printf("\n\n");
-         exit(-1);
-      }
-
-      /* test PSS */
-      l1 = sizeof(buf[1]);
-      if ((err = pkcs_1_pss_encode(buf[0], l3, l3>>2, hash_idx, prng_idx, &prng, 1024, buf[1], &l1)) != CRYPT_OK) {
-         printf("PSS encode: %s\n", error_to_string(err));
-         exit(-1); 
-      }
-      
-      if ((err = pkcs_1_pss_decode(buf[0], l3, buf[1], l1, l3>>2, hash_idx, 1024, &res1)) != CRYPT_OK) {
-         printf("PSS decode1: %s\n", error_to_string(err));
-         exit(-1); 
-      }
-      
-      buf[0][i1 = abs(rand()) % l3] ^= 1;
-      if ((err = pkcs_1_pss_decode(buf[0], l3, buf[1], l1, l3>>2, hash_idx, 1024, &res2)) != CRYPT_OK) {
-         printf("PSS decode2: %s\n", error_to_string(err));
-         exit(-1); 
-      }
-
-      buf[0][i1] ^= 1;
-      buf[1][i2 = abs(rand()) % l1] ^= 1;
-      if ((err = pkcs_1_pss_decode(buf[0], l3, buf[1], l1, l3>>2, hash_idx, 1024, &res3)) != CRYPT_OK) {
-         printf("PSS decode3: %s\n", error_to_string(err));
-         exit(-1); 
-      }
-
-      if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
-         printf("PSS failed: %d, %d, %d, %lu\n", res1, res2, res3, l3);
-         exit(-1);
-      }
-   }
-   printf("PKCS #1: Passed\n");
-}
-
-#endif /* PKCS_1 */
-
-int
-main (void)
-{
-#ifdef SONY_PS2
-  TIMER_Init ();
-#endif
-  srand(time(NULL));
-
-  register_all_algs ();
-   
-  if ((errnum = yarrow_start (&prng)) != CRYPT_OK) {
-    printf ("yarrow_start: %s\n", error_to_string (errnum));
-  }
-  if ((errnum = yarrow_add_entropy ((unsigned char *)"hello", 5, &prng)) != CRYPT_OK) {
-    printf ("yarrow_add_entropy: %s\n", error_to_string (errnum));
-  }
-  if ((errnum = yarrow_ready (&prng)) != CRYPT_OK) {
-    printf ("yarrow_ready: %s\n", error_to_string (errnum));
-  }
-
-  printf (crypt_build_settings);
-  test_errs ();
-
-#ifdef PKCS_1
-  pkcs1_test();
-  return 0;
-#endif
-
-
-#ifdef HMAC
-  printf ("HMAC: %s\n", hmac_test () == CRYPT_OK ? "passed" : "failed");
-  if (hmac_test() != CRYPT_OK) exit(EXIT_FAILURE);
-#endif
-
-#ifdef OMAC
-  printf ("OMAC: %s\n", omac_test () == CRYPT_OK ? "passed" : "failed");
-  if (omac_test() != CRYPT_OK) exit(EXIT_FAILURE);
-#endif
-
-#ifdef PMAC
-  printf ("PMAC: %s\n", pmac_test () == CRYPT_OK ? "passed" : "failed");
-  if (pmac_test() != CRYPT_OK) exit(EXIT_FAILURE);
-#endif
-
-#ifdef EAX_MODE
-  printf ("EAX : %s\n", eax_test () == CRYPT_OK ? "passed" : "failed");
-  if (eax_test() != CRYPT_OK) exit(EXIT_FAILURE);
-#endif
-
-#ifdef OCB_MODE
-  printf ("OCB : %s\n", ocb_test () == CRYPT_OK ? "passed" : "failed");
-  if (ocb_test() != CRYPT_OK) exit(EXIT_FAILURE);
-#endif
-
-  store_tests ();
-  cipher_tests ();
-  hash_tests ();
-
-  ecb_tests ();
-  cbc_tests ();
-  ctr_tests ();
-  ofb_tests ();
-  cfb_tests ();
-
-  rng_tests ();
-  test_prime();
-
-#ifdef KR
-  kr_test ();
-#endif
-  dsa_tests();
-  rsa_test ();
-  pad_test ();
-  ecc_tests ();
-  dh_tests ();
-
-
-  gf_tests ();
-  base64_test ();
-
-  time_ecb ();
-  time_hash ();
-
-#ifdef SONY_PS2
-  TIMER_Shutdown ();
-#endif
-
-  return 0;
-}

+ 20 - 0
demos/test/base64_test.c

@@ -0,0 +1,20 @@
+#include  "test.h"
+
+int base64_test(void)
+{
+   unsigned char in[64], out[256], tmp[64];
+   unsigned long x, l1, l2;
+   
+   for  (x = 0; x < 64; x++) {
+       yarrow_read(in, x, &test_yarrow);
+       l1 = sizeof(out);
+       DO(base64_encode(in, x, out, &l1));
+       l2 = sizeof(tmp);
+       DO(base64_decode(out, l1, tmp, &l2));
+       if (l2 != x || memcmp(tmp, in, x)) {
+           printf("base64  failed %lu %lu %lu", x, l1, l2);
+           return 1;
+       }
+   }
+   return 0;
+}

+ 20 - 0
demos/test/cipher_hash_test.c

@@ -0,0 +1,20 @@
+/* test the ciphers and hashes using their built-in self-tests */
+
+#include "test.h"
+
+int cipher_hash_test(void)
+{
+   int x;
+   
+   /* test ciphers */
+   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+      DO(cipher_descriptor[x].test());
+   }
+   
+   /* test hashes */
+   for (x = 0; hash_descriptor[x].name != NULL; x++) {
+      DO(hash_descriptor[x].test());
+   }
+   
+   return 0;
+}

+ 87 - 0
demos/test/dh_tests.c

@@ -0,0 +1,87 @@
+#include "test.h"
+
+int dh_tests (void)
+{
+  unsigned char buf[3][4096];
+  unsigned long x, y, z;
+  int           stat, stat2;
+  dh_key        usera, userb;
+
+  DO(dh_test());
+
+  /* make up two keys */
+  DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 96, &usera));
+  DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 96, &userb));
+
+  /* make the shared secret */
+  x = 4096;
+  DO(dh_shared_secret (&usera, &userb, buf[0], &x));
+
+  y = 4096;
+  DO(dh_shared_secret (&userb, &usera, buf[1], &y));
+  if (y != x) {
+    printf ("DH Shared keys are not same size.\n");
+    return 1;
+  }
+  if (memcmp (buf[0], buf[1], x)) {
+    printf ("DH Shared keys not same contents.\n");
+    return 1;
+  }
+
+  /* now export userb */
+  y = 4096;
+  DO(dh_export (buf[1], &y, PK_PUBLIC, &userb));
+	  dh_free (&userb);
+
+  /* import and make the shared secret again */
+  DO(dh_import (buf[1], y, &userb));
+  z = 4096;
+  DO(dh_shared_secret (&usera, &userb, buf[2], &z));
+
+  if (z != x) {
+    printf ("failed.  Size don't match?\n");
+    return 1;
+  }
+  if (memcmp (buf[0], buf[2], x)) {
+    printf ("Failed.  Content didn't match.\n");
+    return 1;
+  }
+  dh_free (&usera);
+  dh_free (&userb);
+
+/* test encrypt_key */
+  dh_make_key (&test_yarrow, find_prng ("yarrow"), 128, &usera);
+  for (x = 0; x < 16; x++) {
+    buf[0][x] = x;
+  }
+  y = sizeof (buf[1]);
+  DO(dh_encrypt_key (buf[0], 16, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("md5"), &usera));
+  zeromem (buf[0], sizeof (buf[0]));
+  x = sizeof (buf[0]);
+  DO(dh_decrypt_key (buf[1], y, buf[0], &x, &usera));
+  if (x != 16) {
+    printf ("Failed (length)\n");
+    return 1;
+  }
+  for (x = 0; x < 16; x++)
+    if (buf[0][x] != x) {
+      printf ("Failed (contents)\n");
+      return 1;
+    }
+
+/* test sign_hash */
+  for (x = 0; x < 16; x++) {
+     buf[0][x] = x;
+  }
+  x = sizeof (buf[1]);
+  DO(dh_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow		, find_prng ("yarrow"), &usera));
+  DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat, &usera));
+  buf[0][0] ^= 1;
+  DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
+  if (!(stat == 1 && stat2 == 0)) { 
+     printf("dh_sign/verify_hash %d %d", stat, stat2);
+     return 1;
+  }
+  dh_free (&usera);
+  return 0;
+}

+ 51 - 0
demos/test/dsa_test.c

@@ -0,0 +1,51 @@
+#include "test.h"
+
+int dsa_test(void)
+{
+   unsigned char msg[16], out[1024], out2[1024];
+   unsigned long x, y;
+   int err, stat1, stat2;
+   dsa_key key, key2;
+
+   /* make a random key */
+   DO(dsa_make_key(&test_yarrow, find_prng("yarrow"), 20, 128, &key));
+
+   /* verify it */
+   DO(dsa_verify_key(&key, &stat1));
+   if (stat1 == 0) { printf("dsa_verify_key "); return 1; }
+
+   /* sign the message */
+   x = sizeof(out);
+   DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &test_yarrow, find_prng("yarrow"), &key));
+
+   /* verify it once */
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key));
+
+   /* Modify and verify again */
+   msg[0] ^= 1;
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key));
+   msg[0] ^= 1;
+   if (!(stat1 == 1 && stat2 == 0)) { printf("dsa_verify %d %d", stat1, stat2); return 1; }
+
+   /* test exporting it */
+   x = sizeof(out2);
+   DO(dsa_export(out2, &x, PK_PRIVATE, &key));
+   DO(dsa_import(out2, x, &key2));
+
+   /* verify a signature with it */
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
+   if (stat1 == 0) { printf("dsa_verify (import private) %d ", stat1); return 1; }
+   dsa_free(&key2);
+
+   /* export as public now */
+   x = sizeof(out2);
+   DO(dsa_export(out2, &x, PK_PUBLIC, &key));
+   DO(dsa_import(out2, x, &key2));
+   /* verify a signature with it */
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
+   if (stat1 == 0) { printf("dsa_verify (import public) %d ", stat1); return 1; }
+   dsa_free(&key2);
+   dsa_free(&key);
+
+   return 0;
+}

+ 89 - 0
demos/test/ecc_test.c

@@ -0,0 +1,89 @@
+#include "test.h"
+
+int ecc_tests (void)
+{
+  unsigned char buf[4][4096];
+  unsigned long x, y, z;
+  int           stat, stat2;
+  ecc_key usera, userb;
+	
+  DO(ecc_test ());
+
+  /* make up two keys */
+  DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 24, &usera));
+  DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 24, &userb));
+
+  /* make the shared secret */
+  x = 4096;
+  DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
+
+  y = 4096;
+  DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
+
+  if (y != x) {
+    printf ("ecc Shared keys are not same size.");
+    return 1;
+  }
+
+  if (memcmp (buf[0], buf[1], x)) {
+    printf ("ecc Shared keys not same contents.");
+    return 1;
+  }
+
+  /* now export userb */
+  y = 4096;
+  DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
+  ecc_free (&userb);
+
+  /* import and make the shared secret again */
+  DO(ecc_import (buf[1], y, &userb));
+
+  z = 4096;
+  DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
+
+  if (z != x) {
+    printf ("failed.  Size don't match?");
+    return 1;
+  }
+  if (memcmp (buf[0], buf[2], x)) {
+    printf ("Failed.  Content didn't match.");
+    return 1;
+  }
+  ecc_free (&usera);
+  ecc_free (&userb);
+
+/* test encrypt_key */
+  ecc_make_key (&test_yarrow, find_prng ("yarrow"), 20, &usera);
+  for (x = 0; x < 32; x++) {
+    buf[0][x] = x;
+  }
+  y = sizeof (buf[1]);
+  DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("sha256"), &usera));
+  zeromem (buf[0], sizeof (buf[0]));
+  x = sizeof (buf[0]);
+  DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &usera));
+  if (x != 32) {
+    printf ("Failed (length)");
+    return 1;
+  }
+  for (x = 0; x < 32; x++)
+    if (buf[0][x] != x) {
+      printf ("Failed (contents)");
+      return 1;
+    }
+/* test sign_hash */
+  for (x = 0; x < 16; x++) {
+    buf[0][x] = x;
+  }
+  x = sizeof (buf[1]);
+  DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow, find_prng ("yarrow"), &usera));
+  DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &usera));
+  buf[0][0] ^= 1;
+  DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
+  if (!(stat == 1 && stat2 == 0)) { 
+    printf("ecc_verify_hash failed");
+    return 1;
+  }
+  ecc_free (&usera);
+  return 0;
+}

+ 12 - 0
demos/test/mac_test.c

@@ -0,0 +1,12 @@
+/* test pmac/omac/hmac */
+#include "test.h"
+
+int mac_test(void)
+{
+   DO(hmac_test());
+   DO(pmac_test());
+   DO(omac_test());
+   DO(eax_test());
+   DO(ocb_test());
+   return 0;
+}

+ 13 - 0
demos/test/makefile

@@ -0,0 +1,13 @@
+# make test harness, it is good.
+CFLAGS += -Wall -W -Os -I../../ -I./
+
+default: test
+
+OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \
+pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o 
+
+test: $(OBJECTS)
+	$(CC) $(OBJECTS) -ltomcrypt -o test
+	
+clean:
+	rm -f test *.o *.obj *.exe *~	

+ 14 - 0
demos/test/makefile.icc

@@ -0,0 +1,14 @@
+# make test harness, it is good.
+CFLAGS += -O3 -xN -ip -I../../ -I./
+CC=icc
+
+default: test
+
+OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \
+pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o 
+
+test: $(OBJECTS)
+	$(CC) $(OBJECTS) -ltomcrypt -o test
+	
+clean:
+	rm -f test *.o *~	

+ 14 - 0
demos/test/makefile.msvc

@@ -0,0 +1,14 @@
+# make test harness, it is good.
+CFLAGS = $(CFLAGS) /W3 /Ox -I../../ -I./
+
+default: test.exe
+
+OBJECTS = test.obj cipher_hash_test.obj mac_test.obj modes_test.obj \
+pkcs_1_test.obj store_test.obj rsa_test.obj ecc_test.obj dsa_test.c dh_tests.obj 
+
+
+test.exe: $(OBJECTS)
+	cl $(OBJECTS) tomcrypt.lib advapi32.lib 
+	
+clean:
+	rm -f test.exe *.obj *~	

+ 112 - 0
demos/test/modes_test.c

@@ -0,0 +1,112 @@
+/* test CFB/OFB/CBC modes */
+#include "test.h"
+
+int modes_test(void)
+{
+   unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16];
+   int x, cipher_idx;
+   symmetric_CBC cbc;
+   symmetric_CFB cfb;
+   symmetric_OFB ofb;
+   symmetric_CTR ctr;
+   unsigned long l;
+   
+   /* make a random pt, key and iv */
+   yarrow_read(pt,  64, &test_yarrow);
+   yarrow_read(key, 16, &test_yarrow);
+   yarrow_read(iv,  16, &test_yarrow);
+   
+   /* get idx of AES handy */
+   cipher_idx = find_cipher("aes");
+   if (cipher_idx == -1) {
+      printf("test requires AES");
+      return 1;
+   }
+   
+   /* test CBC mode */
+   /* encode the block */
+   DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+   l = sizeof(iv2);
+   DO(cbc_getiv(iv2, &l, &cbc));
+   if (l != 16 || memcmp(iv2, iv, 16)) {
+      printf("cbc_getiv failed");
+      return 1;
+   }
+   for (x = 0; x < 4; x++) {
+      DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc));
+   }
+   
+   /* decode the block */
+   DO(cbc_setiv(iv2, l, &cbc));
+   zeromem(tmp, sizeof(tmp));
+   for (x = 0; x < 4; x++) {
+      DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc));
+   }
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CBC failed");
+      return 1;
+   }
+   
+   /* test CFB mode */
+   /* encode the block */
+   DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb));
+   l = sizeof(iv2);
+   DO(cfb_getiv(iv2, &l, &cfb));
+   /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */
+   if (l != 16) {
+      printf("cfb_getiv failed");
+      return 1;
+   }
+   DO(cfb_encrypt(pt, ct, 64, &cfb));
+   
+   /* decode the block */
+   DO(cfb_setiv(iv, l, &cfb));
+   zeromem(tmp, sizeof(tmp));
+   DO(cfb_decrypt(ct, tmp, 64, &cfb));
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CFB failed");
+      return 1;
+   }
+   
+   /* test OFB mode */
+   /* encode the block */
+   DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb));
+   l = sizeof(iv2);
+   DO(ofb_getiv(iv2, &l, &ofb));
+   if (l != 16 || memcmp(iv2, iv, 16)) {
+      printf("ofb_getiv failed");
+      return 1;
+   }
+   DO(ofb_encrypt(pt, ct, 64, &ofb));
+   
+   /* decode the block */
+   DO(ofb_setiv(iv2, l, &ofb));
+   zeromem(tmp, sizeof(tmp));
+   DO(ofb_decrypt(ct, tmp, 64, &ofb));
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("OFB failed");
+      return 1;
+   }
+   
+   /* test CTR mode */
+   /* encode the block */
+   DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr));
+   l = sizeof(iv2);
+   DO(ctr_getiv(iv2, &l, &ctr));
+   if (l != 16 || memcmp(iv2, iv, 16)) {
+      printf("ctr_getiv failed");
+      return 1;
+   }
+   DO(ctr_encrypt(pt, ct, 64, &ctr));
+   
+   /* decode the block */
+   DO(ctr_setiv(iv2, l, &ctr));
+   zeromem(tmp, sizeof(tmp));
+   DO(ctr_decrypt(ct, tmp, 64, &ctr));
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CTR failed");
+      return 1;
+   }
+         
+   return 0;
+}

+ 103 - 0
demos/test/pkcs_1_test.c

@@ -0,0 +1,103 @@
+#include "test.h"
+
+int pkcs_1_test(void)
+{
+   unsigned char buf[3][128];
+   int res1, res2, res3, prng_idx, hash_idx;
+   unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen;
+   static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
+
+   /* get hash/prng  */
+   hash_idx = find_hash("sha1");
+   prng_idx = find_prng("yarrow");
+   
+   if (hash_idx == -1 || prng_idx == -1) {
+      printf("pkcs_1 tests require sha1/yarrow");
+      return 1;
+   }   
+
+   /* do many tests */
+   for (x = 0; x < 10000; x++) {
+      zeromem(buf, sizeof(buf));
+
+      /* make a dummy message (of random length) */
+      l3 = (rand() & 31) + 8;
+      for (y = 0; y < l3; y++) buf[0][y] = rand() & 255;
+
+      /* random modulus len (v1.5 must be multiple of 8 though arbitrary sizes seem to work) */
+      modlen = 800 + 8 * (abs(rand()) % 28);
+
+      /* PKCS v1.5 testing (encryption) */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &test_yarrow, prng_idx, buf[1], &l1));
+      DO(pkcs_1_v15_es_decode(buf[1], l1, modlen, buf[2], l3, &res1));
+      if (res1 != 1 || memcmp(buf[0], buf[2], l3)) {
+         printf("pkcs v1.5 encrypt failed %d, %lu, %lu ", res1, l1, l3);
+         return 1;
+      }
+
+      /* PKCS v1.5 testing (signatures) */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_v15_sa_encode(buf[0], l3, hash_idx, modlen, buf[1], &l1));
+      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res1));
+      buf[0][i1 = abs(rand()) % l3] ^= 1;
+      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res2));
+      buf[0][i1] ^= 1;
+      buf[1][i2 = abs(rand()) % l1] ^= 1;
+      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res3));
+
+      if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
+         printf("pkcs v1.5 sign failed %d %d %d ", res1, res2, res3);
+         return 1;
+      }
+
+      /* pick a random lparam len [0..16] */
+      lparamlen = abs(rand()) % 17;
+
+      /* pick a random saltlen 0..16 */
+      saltlen   = abs(rand()) % 17;
+
+      /* PKCS #1 v2.0 supports modlens not multiple of 8 */
+      modlen = 800 + (abs(rand()) % 224);
+
+      /* encode it */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &test_yarrow, prng_idx, hash_idx, buf[1], &l1));
+
+      /* decode it */
+      l2 = sizeof(buf[2]);
+      DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1));
+
+      if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
+         printf("Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
+         printf("ORIGINAL:\n");
+         for (x = 0; x < l3; x++) {
+             printf("%02x ", buf[0][x]);
+         }
+         printf("\nRESULT:\n");
+         for (x = 0; x < l2; x++) {
+             printf("%02x ", buf[2][x]);
+         }
+         printf("\n\n");
+         return 1;
+      }
+
+      /* test PSS */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &test_yarrow, prng_idx, hash_idx, modlen, buf[1], &l1));
+      DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1));
+      
+      buf[0][i1 = abs(rand()) % l3] ^= 1;
+      DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2));
+
+      buf[0][i1] ^= 1;
+      buf[1][i2 = abs(rand()) % l1] ^= 1;
+      DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3));
+
+      if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
+         printf("PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);
+         return 1;
+      }
+   }
+   return 0;
+}

+ 91 - 0
demos/test/rsa_test.c

@@ -0,0 +1,91 @@
+#include "test.h"
+
+int rsa_test(void)
+{
+   unsigned char in[1024], out[1024], tmp[1024];
+   rsa_key       key;
+   int           hash_idx, prng_idx, stat, stat2;
+   unsigned long len, len2;
+   static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
+      
+   hash_idx = find_hash("sha1");
+   prng_idx = find_prng("yarrow");
+   if (hash_idx == -1 || prng_idx == -1) {
+      printf("rsa_test requires SHA1 and yarrow");
+      return 1;
+   }
+   
+   /* make a random key/msg */
+   yarrow_read(in, 20, &test_yarrow);
+   
+   /* make a random key */
+   DO(rsa_make_key(&test_yarrow, prng_idx, 1024/8, 65537, &key));
+   
+   /* encrypt the key (without lparam) */
+   len  = sizeof(out);
+   len2 = sizeof(tmp);
+   DO(rsa_encrypt_key(in, 20, out, &len, NULL, 0, &test_yarrow, prng_idx, hash_idx, &key));
+   /* change a byte */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat2, &key));
+   /* change a byte back */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat, &key));
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_decrypt_key failed");
+      return 1;
+   }
+   if (len2 != 20 || memcmp(tmp, in, 20)) {
+      printf("rsa_decrypt_key mismatch len %lu", len2);
+      return 1;
+   }
+
+   /* encrypt the key (with lparam) */
+   len  = sizeof(out);
+   len2 = sizeof(tmp);
+   DO(rsa_encrypt_key(in, 20, out, &len, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &key));
+   /* change a byte */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat2, &key));
+   /* change a byte back */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat, &key));
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_decrypt_key failed");
+      return 1;
+   }
+   if (len2 != 20 || memcmp(tmp, in, 20)) {
+      printf("rsa_decrypt_key mismatch len %lu", len2);
+      return 1;
+   }
+
+   /* sign a message (unsalted, lower cholestorol and Atkins approved) now */
+   len = sizeof(out);
+   DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 0, &key));
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat, &key));
+   /* change a byte */
+   in[0] ^= 1;
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat2, &key));
+   
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_verify_hash (unsalted) failed, %d, %d", stat, stat2);
+      return 1;
+   }
+
+   /* sign a message (salted) now */
+   len = sizeof(out);
+   DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 8, &key));
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat, &key));
+   /* change a byte */
+   in[0] ^= 1;
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat2, &key));
+   
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_verify_hash (salted) failed, %d, %d", stat, stat2);
+      return 1;
+   }
+   
+   /* free the key and return */
+   rsa_free(&key);
+   return 0;
+}

+ 43 - 0
demos/test/store_test.c

@@ -0,0 +1,43 @@
+#include "test.h"
+
+int store_test(void)
+{
+  unsigned char buf[8];
+  unsigned long L;
+  ulong64 LL;
+
+  L = 0x12345678UL;
+  STORE32L (L, &buf[0]);
+  L = 0;
+  LOAD32L (L, &buf[0]);
+  if (L != 0x12345678UL) {
+    printf ("LOAD/STORE32 Little don't work");
+    return 1;
+  }
+  LL = CONST64 (0x01020304050607);
+  STORE64L (LL, &buf[0]);
+  LL = 0;
+  LOAD64L (LL, &buf[0])
+    if (LL != CONST64 (0x01020304050607)) {
+    printf ("LOAD/STORE64 Little don't work");
+    return 1;
+  }
+
+  L = 0x12345678UL;
+  STORE32H (L, &buf[0]);
+  L = 0;
+  LOAD32H (L, &buf[0]);
+  if (L != 0x12345678UL) {
+    printf ("LOAD/STORE32 High don't work, %08lx", L);
+    return 1;
+  }
+  LL = CONST64 (0x01020304050607);
+  STORE64H (LL, &buf[0]);
+  LL = 0;
+  LOAD64H (LL, &buf[0])
+    if (LL != CONST64 (0x01020304050607)) {
+    printf ("LOAD/STORE64 High don't work");
+    return 1;
+  }
+  return 0;
+}

+ 177 - 0
demos/test/test.c

@@ -0,0 +1,177 @@
+#include "test.h"
+
+test_entry tests[26];
+
+test_entry test_list[26] = { 
+
+/* test name          provides    requires             entry */
+{"store_test",             "a",         "",          store_test           },
+{"cipher_hash_test",       "b",        "a",          cipher_hash_test     },
+{"modes_test",             "c",        "b",          modes_test           },
+{"mac_test",               "d",        "c",          mac_test             },
+{"pkcs_1_test",            "e",        "b",          pkcs_1_test          },
+{"rsa_test",               "f",        "e",          rsa_test             },
+{"ecc_test",               "g",        "a",          ecc_tests            },
+{"dsa_test",               "h",        "a",          dsa_test             },
+{"dh_test",                "i",        "a",          dh_tests             },
+
+{NULL, NULL, NULL, NULL} 
+};
+
+prng_state test_yarrow;
+static int current_test;
+
+void run_cmd(int res, int line, char *file, char *cmd)
+{
+   if (res != CRYPT_OK) {
+      fprintf(stderr, "[%s]: %s (%d)\n%s:%d:%s\n", tests[current_test].name, error_to_string(res), res, file, line, cmd);
+      exit(EXIT_FAILURE);
+   }
+}
+
+void register_algs(void)
+{
+#ifdef RIJNDAEL
+  register_cipher (&aes_desc);
+#endif
+#ifdef BLOWFISH
+  register_cipher (&blowfish_desc);
+#endif
+#ifdef XTEA
+  register_cipher (&xtea_desc);
+#endif
+#ifdef RC5
+  register_cipher (&rc5_desc);
+#endif
+#ifdef RC6
+  register_cipher (&rc6_desc);
+#endif
+#ifdef SAFERP
+  register_cipher (&saferp_desc);
+#endif
+#ifdef TWOFISH
+  register_cipher (&twofish_desc);
+#endif
+#ifdef SAFER
+  register_cipher (&safer_k64_desc);
+  register_cipher (&safer_sk64_desc);
+  register_cipher (&safer_k128_desc);
+  register_cipher (&safer_sk128_desc);
+#endif
+#ifdef RC2
+  register_cipher (&rc2_desc);
+#endif
+#ifdef DES
+  register_cipher (&des_desc);
+  register_cipher (&des3_desc);
+#endif
+#ifdef CAST5
+  register_cipher (&cast5_desc);
+#endif
+#ifdef NOEKEON
+  register_cipher (&noekeon_desc);
+#endif
+#ifdef SKIPJACK
+  register_cipher (&skipjack_desc);
+#endif
+#ifdef TIGER
+  register_hash (&tiger_desc);
+#endif
+#ifdef MD2
+  register_hash (&md2_desc);
+#endif
+#ifdef MD4
+  register_hash (&md4_desc);
+#endif
+#ifdef MD5
+  register_hash (&md5_desc);
+#endif
+#ifdef SHA1
+  register_hash (&sha1_desc);
+#endif
+#ifdef SHA256
+  register_hash (&sha256_desc);
+#endif
+#ifdef SHA224
+  register_hash (&sha224_desc);
+#endif
+#ifdef SHA384
+  register_hash (&sha384_desc);
+#endif
+#ifdef SHA512
+  register_hash (&sha512_desc);
+#endif
+#ifdef RIPEMD128
+  register_hash (&rmd128_desc);
+#endif
+#ifdef RIPEMD160
+  register_hash (&rmd160_desc);
+#endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
+
+   if (register_prng(&yarrow_desc) == -1) {
+      printf("Error registering yarrow PRNG\n");
+      exit(-1);
+   }
+
+   if (register_prng(&sprng_desc) == -1) {
+      printf("Error registering sprng PRNG\n");
+      exit(-1);
+   }
+}
+
+/* sort tests based on their requirement/services.  Helps make sure dependencies are tested first */
+void sort(void)
+{
+   unsigned x, y, z, a, pidx[26];
+      
+   /* find out where things are provided */
+   zeromem(pidx, sizeof(pidx));   
+   z = 0;
+   do { 
+      y = 0;
+      for (x = 0; test_list[x].name != NULL; x++) {
+        if (test_list[x].entry == NULL) continue;
+        if (strlen(test_list[x].prov) == 0) {
+           y = 1;
+           tests[z++] = test_list[x]; test_list[x].entry = NULL;
+           pidx[test_list[x].prov[0]-'a'] = 1;
+           break;
+        } else {
+           for (a = 0; a < strlen(test_list[x].req); a++) {
+               if (pidx[test_list[x].req[a]-'a'] == 0) break;
+           }
+           if (a == strlen(test_list[x].req)) {
+              y = 1;
+              tests[z++] = test_list[x]; test_list[x].entry = NULL;
+              pidx[test_list[x].prov[0]-'a'] = 1;
+              break;
+           }
+        }
+      }
+   } while (y == 1);
+}
+   
+int main(void)
+{
+   printf("Built with\n%s\n", crypt_build_settings);
+
+   srand(time(NULL));
+   sort();
+   register_algs();
+      
+   // start dummy yarrow for internal use 
+   DO(yarrow_start(&test_yarrow));
+   DO(yarrow_add_entropy("test", 4, &test_yarrow));
+   DO(yarrow_ready(&test_yarrow));
+
+   // do tests
+   for (current_test = 0; tests[current_test].name != NULL; current_test++) {
+       printf("[%-20s]: ", tests[current_test].name); fflush(stdout);
+       printf("\t%s\n", tests[current_test].entry()==0?"passed":"failed"); 
+   }
+   
+   return 0;
+}

+ 29 - 0
demos/test/test.h

@@ -0,0 +1,29 @@
+#ifndef __TEST_H_
+#define __TEST_H_
+
+#include "mycrypt.h"
+
+typedef struct {
+    char *name, *prov, *req;
+    int  (*entry)(void);
+} test_entry;
+
+extern prng_state test_yarrow;
+
+void run_cmd(int res, int line, char *file, char *cmd);
+#define DO(x) run_cmd((x), __LINE__, __FILE__, #x)
+
+
+
+/* TESTS */
+int cipher_hash_test(void);
+int modes_test(void);
+int mac_test(void);
+int pkcs_1_test(void);
+int store_test(void);
+int rsa_test(void);
+int ecc_tests(void);
+int dsa_test(void);
+int dh_tests(void);
+
+#endif

BIN
doc/crypt.pdf


+ 3 - 0
ecb_decrypt.c

@@ -19,9 +19,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb)
    _ARGCHK(ct != NULL);
    _ARGCHK(ecb != NULL);
 
+   /* valid cipher? */
    if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
        return err;
    }
+   _ARGCHK(cipher_descriptor[ecb->cipher].ecb_decrypt != NULL);
+   
    cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
    return CRYPT_OK;
 }

+ 0 - 26
strings.c → error_to_string.c

@@ -9,7 +9,6 @@
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
 
-/* Future releases will make use of this */
 #include "mycrypt.h"
 
 static const char *err_2_str[] =
@@ -50,16 +49,6 @@ static const char *err_2_str[] =
 
 };
 
-#ifdef MPI
-static const struct {
-    int mpi_code, ltc_code;
-} mpi_to_ltc_codes[] = {
-   { MP_OKAY ,  CRYPT_OK},
-   { MP_MEM  ,  CRYPT_MEM},
-   { MP_VAL  ,  CRYPT_INVALID_ARG},
-};
-#endif
-
 const char *error_to_string(int err)
 {
    if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
@@ -69,18 +58,3 @@ const char *error_to_string(int err)
    }   
 }
 
-#ifdef MPI
-/* convert a MPI error to a LTC error (Possibly the most powerful function ever!  Oh wait... no) */
-int mpi_to_ltc_error(int err)
-{
-   int x;
-
-   for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
-       if (err == mpi_to_ltc_codes[x].mpi_code) { 
-          return mpi_to_ltc_codes[x].ltc_code;
-       }
-   }
-   return CRYPT_ERROR;
-}
-#endif
-

+ 0 - 305
gf.c

@@ -1,305 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-/* polynomial basis GF(2^w) routines */
-#include "mycrypt.h"
-
-#ifdef GF
-
-#define FORLOOP for (i = 0; i < LSIZE; i++) 
-
-/* c = a + b */
-void gf_add(gf_intp a, gf_intp b, gf_intp c)
-{
-   int i;
-   FORLOOP c[i] = a[i]^b[i];
-}
-
-/* b = a */
-void gf_copy(gf_intp a, gf_intp b)
-{
-   int i;
-   FORLOOP b[i] = a[i];
-}
-
-/* a = 0 */
-void gf_zero(gf_intp a)
-{
-   int i;
-   FORLOOP a[i] = 0;
-}
-
-/* is a zero? */
-int gf_iszero(gf_intp a)
-{
-   int i;
-   FORLOOP if (a[i]) {
-      return 0;
-   }
-   return 1;
-}
-
-/* is a one? */
-int gf_isone(gf_intp a)
-{ 
-   int i;
-   for (i = 1; i < LSIZE; i++) {
-       if (a[i]) {
-          return 0;
-       }
-   }
-   return a[0] == 1;
-}
-
-/* b = a << 1*/
-void gf_shl(gf_intp a, gf_intp b)
-{
-   int i;
-   gf_int tmp;
-
-   gf_copy(a, tmp);
-   for (i = LSIZE-1; i > 0; i--) 
-       b[i] = ((tmp[i]<<1)|((tmp[i-1]&0xFFFFFFFFUL)>>31))&0xFFFFFFFFUL;
-   b[0] = (tmp[0] << 1)&0xFFFFFFFFUL;
-   gf_zero(tmp);
-}
-
-/* b = a >> 1 */
-void gf_shr(gf_intp a, gf_intp b)
-{
-   int i;
-   gf_int tmp;
-
-   gf_copy(a, tmp);
-   for (i = 0; i < LSIZE-1; i++)
-       b[i] = (((tmp[i]&0xFFFFFFFFUL)>>1)|(tmp[i+1]<<31))&0xFFFFFFFFUL;
-   b[LSIZE-1] = (tmp[LSIZE-1]&0xFFFFFFFFUL)>>1;
-   gf_zero(tmp);
-}
-
-/* returns -1 if its zero, otherwise degree of a */
-int gf_deg(gf_intp a)
-{
-   int i, ii;
-   unsigned long t;
-
-   ii = -1;
-   for (i = LSIZE-1; i >= 0; i--)
-       if (a[i]) {
-          for (t = a[i], ii = 0; t; t >>= 1, ++ii);
-          break;
-       }
-   if (i == -1) i = 0;
-   return (i<<5)+ii;
-}
-
-/* c = ab */
-void gf_mul(gf_intp a, gf_intp b, gf_intp c)
-{
-   gf_int ta, tb;
-   int i, n;
-
-   gf_copy(a, ta);
-   gf_copy(b, tb);
-   gf_zero(c);
-   n = gf_deg(ta)+1;
-   for (i = 0; i < n; i++) {
-       if (ta[i>>5]&(1<<(i&31)))
-          gf_add(c, tb, c);
-       gf_shl(tb, tb);
-   }
-   gf_zero(ta);
-   gf_zero(tb);
-}
-
-/* q = a/b, r = a%b */
-void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r)
-{
-   gf_int ta, tb, shifts[LSIZE*32];
-   int i, magb, mag;
-
-   mag  = gf_deg(a);
-   magb = gf_deg(b);
-
-   /* special cases */
-   if (magb > mag) {
-      gf_copy(a, r);
-      gf_zero(q);
-      return;
-   }
-   if (magb == -1) {
-      return;
-   }
-
-   /* copy locally */
-   gf_copy(a, ta);
-   gf_copy(b, tb);
-   gf_zero(q);
-
-   /* make shifted versions of "b" */
-   gf_copy(tb, shifts[0]);
-   for (i = 1; i <= (mag-magb); i++) 
-       gf_shl(shifts[i-1], shifts[i]);
-
-   while (mag >= magb) {
-       i = (mag - magb);
-       q[i>>5] |= (1<<(i&31));
-       gf_add(ta, shifts[i], ta);
-       mag = gf_deg(ta);
-   }
-   gf_copy(ta, r);
-   gf_zero(ta);
-   gf_zero(tb);
-   zeromem(shifts, sizeof(shifts));
-}
-
-/* b = a mod m */
-void gf_mod(gf_intp a, gf_intp m, gf_intp b)
-{
-   gf_int tmp;
-   gf_div(a,m,tmp,b);
-   gf_zero(tmp);
-}
-
-/* c = ab (mod m) */
-void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c)
-{
-   gf_int tmp;
-   gf_mul(a, b, tmp);
-   gf_mod(tmp, m, c);
-   gf_zero(tmp);
-}
-
-/* B = 1/A mod M */
-void gf_invmod(gf_intp A, gf_intp M, gf_intp B)
-{
-  gf_int m, n, p0, p1, p2, r, q, tmp;
-
-  /* put all variables in known setup state */
-  gf_zero(p0);
-  gf_zero(p2);
-  gf_copy(M, m);
-  gf_copy(A, n);
-  p0[0] = 1;
-  gf_div(m, n, p1, r);
-  gf_copy(p1, q);
-
-  /* loop until r == 0 */
-  while (!gf_iszero(r)) {
-     gf_copy(n, m);
-     gf_copy(r, n);
-     gf_div(m, n, q, r);
-     gf_mul(q, p1, tmp);
-     gf_add(tmp, p0, p2);
-     gf_copy(p1, p0);
-     gf_copy(p2, p1);
-  }
-  gf_copy(p0, B);
-  gf_zero(p0);
-}
-
-/* find a square root modulo a prime.  Note the number of 
- * elements is 2^k - 1, so we must square k-2 times to get the
- * square root.. 
- */
-void gf_sqrt(gf_intp a, gf_intp M, gf_intp b)
-{
-   int k;
-   k = gf_deg(M)-2;
-   gf_copy(a, b);
-   while (k--)
-      gf_mulmod(b, b, M, b);
-}
-
-/* c = gcd(A,B) */
-void gf_gcd(gf_intp A, gf_intp B, gf_intp c)
-{
-   gf_int a, b, r;
-   int n;
-
-   gf_add(A, B, r);
-   n = gf_deg(r);
-   if (gf_deg(A) > n) {
-      gf_copy(A, a);
-      gf_copy(B, b);
-   } else {
-      gf_copy(A, b);
-      gf_copy(B, a);
-   }
-
-   do {
-      gf_mod(a, b, r);
-      gf_copy(b, a);
-      gf_copy(r, b);
-   } while (!gf_iszero(r));
-   gf_copy(a, c);
-   gf_zero(a);
-   gf_zero(b);
-}
-
-/* returns non-zero if 'a' is irreducible */
-int gf_is_prime(gf_intp a)
-{
-   gf_int u, tmp;
-   int m, n;
-
-   gf_zero(u);
-   u[0] = 2;			/* u(x) = x */
-   m = gf_deg(a);
-   for (n = 0; n < (m/2); n++) { 
-       gf_mulmod(u, u, a, u);   /* u(x) = u(x)^2 mod a(x) */
-       gf_copy(u, tmp);
-       tmp[0] ^= 2;		/* tmp(x) = u(x) - x */
-       gf_gcd(tmp, a, tmp);     /* tmp(x) = gcd(a(x), u(x) - x) */
-       if (!gf_isone(tmp)) {
-          return 0;
-       }
-   }
-   return 1;
-}  
-
-/* returns bytes required to store a gf_int */
-int gf_size(gf_intp a)
-{
-   int n;
-
-   n = gf_deg(a);
-   if (n == -1) {
-      return 4;
-   }
-   n = n + (32 - (n&31));
-   return n/8;
-}
-
-/* store a gf_int */
-void gf_toraw(gf_intp a, unsigned char *dst)
-{
-   int x, n;
-   n = gf_size(a)/4;
-   for (x = 0; x < n; x++) {
-       STORE32L(a[x], dst);
-       dst += 4;
-   }
-}
-
-/* read a gf_int (len == in bytes) */
-void gf_readraw(gf_intp a, unsigned char *str, int len)
-{
-   int x;
-   gf_zero(a);
-   for (x = 0; x < len/4; x++) {
-       LOAD32L(a[x], str);
-       str += 4;
-   }
-}
-
-#endif
-
-

+ 0 - 862
keyring.c

@@ -1,862 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-/* Provides keyring functionality for libtomcrypt, Tom St Denis */
-#include <mycrypt.h>
-
-#ifdef KR
-
-static const unsigned char key_magic[4]  = { 0x12, 0x34, 0x56, 0x78 };
-static const unsigned char file_magic[4] = { 0x9A, 0xBC, 0xDE, 0xF0 };
-static const unsigned char sign_magic[4] = { 0x87, 0x56, 0x43, 0x21 };
-static const unsigned char enc_magic[4]  = { 0x0F, 0xED, 0xCB, 0xA9 };
-
-static const unsigned long crc_table[256] = {
-  0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
-  0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
-  0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
-  0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
-  0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
-  0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
-  0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
-  0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
-  0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
-  0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
-  0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
-  0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
-  0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
-  0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
-  0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
-  0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
-  0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
-  0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
-  0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
-  0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
-  0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
-  0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
-  0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
-  0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
-  0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
-  0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
-  0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
-  0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
-  0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
-  0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
-  0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
-  0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
-  0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
-  0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
-  0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
-  0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
-  0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
-  0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
-  0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
-  0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
-  0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
-  0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
-  0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
-  0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
-  0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
-  0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
-  0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
-  0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
-  0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
-  0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
-  0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
-  0x2d02ef8dUL
-};
-
-#define DO1(buf) crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf)  DO1(buf); DO1(buf);
-#define DO4(buf)  DO2(buf); DO2(buf);
-#define DO8(buf)  DO4(buf); DO4(buf);
-
-static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len)
-{
-  //_ARGCHK(buf != NULL  && len == 0);
-  crc = crc ^ 0xffffffffL;
-  while (len >= 8) {
-      DO8 (buf);
-      len -= 8;
-  }
-  
-  if (len > 0) {
-    do {
-	   DO1 (buf);
-    } while (--len > 0);
-  }    
-  return crc ^ 0xffffffffUL;
-}
-
-int kr_init(pk_key **pk)
-{
-   _ARGCHK(pk != NULL);
-
-   *pk = XCALLOC(1, sizeof(pk_key));
-   if (*pk == NULL) {
-      return CRYPT_MEM;
-   }
-   (*pk)->system = NON_KEY;
-   return CRYPT_OK;
-}
-
-unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description)
-{
-   unsigned long crc;
-   _ARGCHK(name != NULL);
-   _ARGCHK(email != NULL);
-   _ARGCHK(description != NULL);
-   crc = crc32(0UL, NULL, 0UL);
-   crc = crc32(crc, name,  (unsigned long)MIN(MAXLEN, strlen((char *)name)));
-   crc = crc32(crc, email, (unsigned long)MIN(MAXLEN, strlen((char *)email)));
-   return crc32(crc, description, (unsigned long)MIN(MAXLEN, strlen((char *)description)));
-}
-
-pk_key *kr_find(pk_key *pk, unsigned long ID)
-{
-   _ARGCHK(pk != NULL);
-
-   while (pk != NULL) {
-        if (pk->system != NON_KEY && pk->ID == ID) {
-           return pk;
-        }
-        pk = pk->next;
-   }
-   return NULL;
-}
-
-pk_key *kr_find_name(pk_key *pk, const char *name)
-{
-   _ARGCHK(pk != NULL);
-   _ARGCHK(name != NULL);
-
-   while (pk != NULL) {
-        if (pk->system != NON_KEY && strncmp((char *)pk->name, (char *)name, sizeof(pk->name)-1) == 0) {
-           return pk;
-        }
-        pk = pk->next;
-   }
-   return NULL;
-}
- 
-
-int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name, 
-           const unsigned char *email, const unsigned char *description, const _pk_key *key)
-{
-   _ARGCHK(pk != NULL);
-   _ARGCHK(name != NULL);
-   _ARGCHK(email != NULL);
-   _ARGCHK(description != NULL);
-   _ARGCHK(key != NULL);
-
-   /* check parameters */
-   if (key_type != PK_PRIVATE && key_type != PK_PRIVATE_OPTIMIZED && key_type != PK_PUBLIC) {
-      return CRYPT_PK_INVALID_TYPE;
-   }
- 
-   if (sys != RSA_KEY && sys != DH_KEY && sys != ECC_KEY) {
-      return CRYPT_PK_INVALID_SYSTEM;
-   }
-
-   /* see if its a dupe  */
-   if (kr_find(pk, kr_crc(name, email, description)) != NULL) {
-      return CRYPT_PK_DUP;
-   }
-   
-   /* find spot in key ring */
-   while (pk->system != NON_KEY) {
-         if (pk->next == NULL) {
-            return CRYPT_ERROR;
-         }
-         pk = pk->next;
-   }
-
-   /* now we have a spot make a next spot */
-   pk->next = XCALLOC(1, sizeof(pk_key));
-   if (pk->next == NULL) {
-      return CRYPT_MEM;
-   }
-   pk->next->system = NON_KEY;
-
-   /* now add this new data to this ring spot */
-   pk->key_type = key_type;
-   pk->system   = sys;
-   strncpy((char *)pk->name, (char *)name, sizeof(pk->name)-1);
-   strncpy((char *)pk->email, (char *)email, sizeof(pk->email)-1);
-   strncpy((char *)pk->description, (char *)description, sizeof(pk->description)-1);
-   pk->ID       = kr_crc(pk->name, pk->email, pk->description);
-
-   /* clear the memory area */
-   zeromem(&(pk->key), sizeof(pk->key));
-
-   /* copy the key */
-   switch (sys) {
-         case RSA_KEY:
-              memcpy(&(pk->key.rsa), &(key->rsa), sizeof(key->rsa));
-              break;
-         case DH_KEY:
-              memcpy(&(pk->key.dh), &(key->dh), sizeof(key->dh));
-              break;
-         case ECC_KEY:
-              memcpy(&(pk->key.ecc), &(key->ecc), sizeof(key->ecc));
-              break;
-   }
-   return CRYPT_OK;
-}
-
-int kr_del(pk_key **_pk, unsigned long ID)
-{
-   pk_key *ppk, *pk;
-
-   _ARGCHK(_pk != NULL);
-
-   pk  = *_pk;
-   ppk = NULL;
-   while (pk->system != NON_KEY && pk->ID != ID) {
-        ppk = pk;
-        pk  = pk->next;
-        if (pk == NULL) {
-           return CRYPT_PK_NOT_FOUND;
-        }
-   }
-
-   switch (pk->system) {
-        case RSA_KEY:
-            rsa_free(&(pk->key.rsa));
-            break;
-        case DH_KEY:
-            dh_free(&(pk->key.dh));
-            break;
-        case ECC_KEY:
-            ecc_free(&(pk->key.ecc));
-            break;
-   }
-
-   if (ppk == NULL) {       /* the first element matches the ID */
-      ppk = pk->next;       /* get the 2nd element */
-      XFREE(pk);             /* free the first */
-      *_pk = ppk;           /* make the first element the second */
-   } else {                 /* (not) first element matches the ID */
-      ppk->next = pk->next; /* make the previous'es next point to the current next */
-      XFREE(pk);             /* free the element */
-   }
-   return CRYPT_OK;
-}
-
-int kr_clear(pk_key **pk)
-{
-   int err;
-   _ARGCHK(pk != NULL);
-
-   while ((*pk)->system != NON_KEY) {
-       if ((err = kr_del(pk, (*pk)->ID)) != CRYPT_OK) { 
-          return err;
-       }
-   }       
-   XFREE(*pk);
-   *pk = NULL;
-   return CRYPT_OK;
-}
-
-static unsigned long _write(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr)
-{
-#ifdef NO_FILE
-   return 0;
-#else
-   _ARGCHK(buf != NULL);
-   _ARGCHK(f   != NULL);
-   if (ctr != NULL) {
-      if (ctr_encrypt(buf, buf, len, ctr) != CRYPT_OK) {
-         return 0;
-      }
-   }
-   return (unsigned long)fwrite(buf, 1, (size_t)len, f);
-#endif
-}
-
-static unsigned long _read(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr)
-{
-#ifdef NO_FILE
-    return 0;
-#else
-   unsigned long y;
-   _ARGCHK(buf != NULL);
-   _ARGCHK(f   != NULL);
-   y = (unsigned long)fread(buf, 1, (size_t)len, f);
-   if (ctr != NULL) {
-      if (ctr_decrypt(buf, buf, y, ctr) != CRYPT_OK) {
-         return 0;
-      }
-   }
-   return y;
-#endif
-}
-
-int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen)
-{
-   unsigned char buf[8192], *obuf;
-   pk_key *ppk;
-   unsigned long len;
-   int err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* find the desired key */
-   ppk = kr_find(pk, ID);
-   if (ppk == NULL) {
-      return CRYPT_PK_NOT_FOUND;
-   }
-
-   if (ppk->key_type == PK_PUBLIC && key_type != PK_PUBLIC) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-
-   /* this makes PK_PRIVATE an alias for PK_PRIVATE_OPTIMIZED type */
-   if (ppk->key_type == PK_PRIVATE_OPTIMIZED && key_type == PK_PRIVATE) {
-      key_type = PK_PRIVATE_OPTIMIZED;
-   }
-
-   /* now copy the header and various other details */
-   memcpy(buf, key_magic, 4);                              /* magic info */
-   buf[4] = key_type;                                      /* key type */
-   buf[5] = ppk->system;                                   /* system */
-   STORE32L(ppk->ID, buf+6);                               /* key ID */
-   memcpy(buf+10, ppk->name, MAXLEN);                      /* the name */
-   memcpy(buf+10+MAXLEN, ppk->email, MAXLEN);              /* the email */
-   memcpy(buf+10+MAXLEN+MAXLEN, ppk->description, MAXLEN); /* the description */
-   
-   /* export key */
-   len = sizeof(buf) - (6 + 4 + MAXLEN*3);
-   obuf = buf+6+4+MAXLEN*3;
-   switch (ppk->system) {
-       case RSA_KEY:
-           if ((err = rsa_export(obuf, &len, key_type, &(ppk->key.rsa))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-       case DH_KEY:
-           if ((err = dh_export(obuf, &len, key_type, &(ppk->key.dh))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-       case ECC_KEY:
-           if ((err = ecc_export(obuf, &len, key_type, &(ppk->key.ecc))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-   }
-
-   /* get the entire length of the packet */
-   len += 6 + 4 + 3*MAXLEN;
-
-   if (*outlen < len) {
-      #ifdef CLEAN_STACK
-          zeromem(buf, sizeof(buf));
-      #endif
-      return CRYPT_BUFFER_OVERFLOW;
-   } else {
-      *outlen = len;
-      memcpy(out, buf, len);
-      #ifdef CLEAN_STACK
-          zeromem(buf, sizeof(buf));
-      #endif
-      return CRYPT_OK;
-   }
-}
-
-int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen)
-{
-   _pk_key key;
-   int sys, key_type, err;
-   unsigned long ID;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(in != NULL);
-
-   if (inlen < 10) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   if (memcmp(in, key_magic, 4) != 0) {
-      return CRYPT_INVALID_PACKET;
-   }
-   key_type = in[4];                                 /* get type */
-   sys      = in[5];                                 /* get system */
-   LOAD32L(ID,in+6);                                 /* the ID */
-
-   if (ID != kr_crc(in+10, in+10+MAXLEN, in+10+MAXLEN+MAXLEN)) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   zeromem(&key, sizeof(key));
-   
-   /* size of remaining packet */
-   inlen -= 10 + 3*MAXLEN;
-   
-   switch (sys) {
-        case RSA_KEY:
-            if ((err = rsa_import(in+10+3*MAXLEN, inlen, &(key.rsa))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-        case DH_KEY:
-            if ((err = dh_import(in+10+3*MAXLEN, inlen, &(key.dh))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-        case ECC_KEY:
-            if ((err = ecc_import(in+10+3*MAXLEN, inlen, &(key.ecc))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-   }
-   return kr_add(pk, key_type, sys, 
-                 in+10,                           /* the name */
-                 in+10+MAXLEN,                    /* email address */
-                 in+10+MAXLEN+MAXLEN,             /* description */
-                 &key);
-}
-
-
-int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr)
-{
-   unsigned char buf[8192], blen[4];
-   unsigned long len;
-   int res, err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(in != NULL);
-
-   /* init keyring */
-   if ((err = kr_init(pk)) != CRYPT_OK) { 
-      return err; 
-   }
-
-   /* read in magic bytes */
-   if (_read(buf, 6, in, ctr) != 6)           { goto done2; }
-
-   if (memcmp(buf, file_magic, 4) != 0) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   len = (unsigned long)buf[4] | ((unsigned long)buf[5] << 8);
-   if (len > CRYPT) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* while there are lengths to read... */
-   while (_read(blen, 4, in, ctr) == 4) {
-      /* get length */
-      LOAD32L(len, blen);
-
-      if (len > (unsigned long)sizeof(buf)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      if (_read(buf, len, in, ctr) != len)           { goto done2; }
-      if ((err = kr_import(*pk, buf, len)) != CRYPT_OK) { 
-         return err; 
-      }
-   }
-
-   res = CRYPT_OK;
-   goto done;
-done2:
-   res = CRYPT_ERROR;
-done:
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
-   return res;
-}
-
-int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr)
-{
-   unsigned char buf[8192], blen[4];
-   unsigned long len;
-   int res, err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(out != NULL);
-
-   /* write out magic bytes */
-   memcpy(buf, file_magic, 4);
-   buf[4] = (unsigned char)(CRYPT&255);
-   buf[5] = (unsigned char)((CRYPT>>8)&255);
-   if (_write(buf, 6, out, ctr) != 6)           { goto done2; }
-
-   while (pk->system != NON_KEY) {
-         len = sizeof(buf);
-         if ((err = kr_export(pk, pk->ID, pk->key_type, buf, &len)) != CRYPT_OK) { 
-            return err;
-         }
-          
-         STORE32L(len, blen);
-         if (_write(blen, 4, out, ctr) != 4)    { goto done2; }
-         if (_write(buf, len, out, ctr) != len) { goto done2; }
-
-         pk = pk->next;
-   }
-         
-   res = CRYPT_OK;
-   goto done;
-done2:
-   res = CRYPT_ERROR;
-done:
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
-   return res;
-}
-
-int kr_make_key(pk_key *pk, prng_state *prng, int wprng, 
-                int sys, int keysize, const unsigned char *name,
-                const unsigned char *email, const unsigned char *description)
-{
-   _pk_key key;
-   int key_type, err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(name != NULL);
-   _ARGCHK(email != NULL);
-   _ARGCHK(description != NULL);
-
-   /* valid PRNG? */
-   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* make the key first */
-   zeromem(&key, sizeof(key));
-   switch (sys) {
-      case RSA_KEY: 
-          if ((err = rsa_make_key(prng, wprng, keysize, 65537, &(key.rsa))) != CRYPT_OK) {
-             return err;
-          }
-          key_type = key.rsa.type;
-          break;
-      case DH_KEY: 
-          if ((err = dh_make_key(prng, wprng, keysize, &(key.dh))) != CRYPT_OK) {
-             return err;
-          }
-          key_type = key.dh.type;
-          break;
-      case ECC_KEY: 
-          if ((err = ecc_make_key(prng, wprng, keysize, &(key.ecc))) != CRYPT_OK) {
-             return err;
-          }
-          key_type = key.ecc.type;
-          break;
-      default:
-          return CRYPT_PK_INVALID_SYSTEM;
-   }
-
-   /* now add the key */
-   if ((err = kr_add(pk, key_type, sys, name, email, description, &key)) != CRYPT_OK) {
-      return err;
-   }
-
-#ifdef CLEAN_STACK
-   zeromem(&key, sizeof(key));
-#endif
-   return CRYPT_OK;
-}
-
-int kr_encrypt_key(pk_key *pk, unsigned long ID, 
-                   const unsigned char *in, unsigned long inlen,
-                   unsigned char *out, unsigned long *outlen,
-                   prng_state *prng, int wprng, int hash)
-{
-   unsigned char buf[8192];
-   unsigned long len;
-   pk_key *kr;
-   int err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* find the key */
-   kr = kr_find(pk, ID);
-   if (kr == NULL) {
-      return CRYPT_PK_NOT_FOUND;
-   }
-
-   /* store the header */
-   memcpy(buf, enc_magic, 4);
-
-   /* now store the ID */
-   STORE32L(kr->ID,buf+4);
-
-   /* now encrypt it */
-   len = sizeof(buf)-12;
-   switch (kr->system) {
-        case RSA_KEY:
-            if ((err = rsa_encrypt_key(in, inlen, buf+12, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-        case DH_KEY:
-            if ((err = dh_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-        case ECC_KEY:
-            if ((err = ecc_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-    }
-    STORE32L(len,buf+8);
-    len += 12;
-
-    if (len > *outlen) {
-       #ifdef CLEAN_STACK
-           zeromem(buf, sizeof(buf));
-       #endif
-       return CRYPT_BUFFER_OVERFLOW;
-    } else {
-       memcpy(out, buf, len);
-       #ifdef CLEAN_STACK
-           zeromem(buf, sizeof(buf));
-       #endif
-       *outlen = len;
-       return CRYPT_OK;
-    }
-}
-
-int kr_decrypt_key(pk_key *pk, const unsigned char *in,
-                   unsigned char *out, unsigned long *outlen)
-{
-   unsigned char buf[8192];
-   unsigned long pklen, len, ID;
-   pk_key *kr;
-   int err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* check magic header */
-   if (memcmp(in, enc_magic, 4)) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* now try to find key */
-   LOAD32L(ID,in+4);
-   kr = kr_find(pk, ID);
-   if (kr == NULL) {
-      return CRYPT_PK_NOT_FOUND;
-   }
-
-   /* is it public? */
-   if (kr->key_type == PK_PUBLIC) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-
-   /* now try and decrypt it */
-   LOAD32L(pklen,in+8);
-   len = sizeof(buf);
-   switch (kr->system) {
-       case RSA_KEY:
-           if ((err = rsa_decrypt_key(in+12, pklen, buf, &len, &(kr->key.rsa))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-       case DH_KEY:
-           if ((err = dh_decrypt_key(in+12, pklen, buf, &len, &(kr->key.dh))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-       case ECC_KEY:
-           if ((err = ecc_decrypt_key(in+12, pklen, buf, &len, &(kr->key.ecc))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-   }
-
-    if (len > *outlen) {
-       #ifdef CLEAN_STACK
-           zeromem(buf, sizeof(buf));
-       #endif
-       return CRYPT_BUFFER_OVERFLOW;
-    } else {
-       memcpy(out, buf, len);
-       #ifdef CLEAN_STACK
-           zeromem(buf, sizeof(buf));
-       #endif
-       *outlen = len;
-       return CRYPT_OK;
-    }
-}
-
-int kr_sign_hash(pk_key *pk, unsigned long ID, 
-                 const unsigned char *in, unsigned long inlen,
-                 unsigned char *out, unsigned long *outlen,
-                 prng_state *prng, int wprng)
-{
-   unsigned char buf[8192];
-   unsigned long len;
-   pk_key *kr;
-   int err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* find the key */
-   kr = kr_find(pk, ID);
-   if (kr == NULL) {
-      return CRYPT_PK_NOT_FOUND;
-   }
-
-   /* is it public? */
-   if (kr->key_type == PK_PUBLIC) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-
-   /* store the header */
-   memcpy(buf, sign_magic, 4);
-
-   /* now store the ID */
-   STORE32L(kr->ID,buf+4);
-
-   /* now sign it */
-   len = sizeof(buf)-16;
-   switch (kr->system) {
-        case RSA_KEY:
-            if ((err = rsa_sign_hash(in, inlen, buf+16, &len, &(kr->key.rsa))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-        case DH_KEY:
-            if ((err = dh_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-        case ECC_KEY:
-            if ((err = ecc_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) {
-               return err;
-            }
-            break;
-    }
-    STORE32L(inlen,buf+8);
-    STORE32L(len,buf+12);
-    len += 16;
-
-    if (len > *outlen) {
-       #ifdef CLEAN_STACK
-           zeromem(buf, sizeof(buf));
-       #endif
-       return CRYPT_BUFFER_OVERFLOW;
-    } else {
-       memcpy(out, buf, len);
-       #ifdef CLEAN_STACK
-           zeromem(buf, sizeof(buf));
-       #endif
-       *outlen = len;
-       return CRYPT_OK;
-    }
-}
-
-int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *hash, 
-                   unsigned long hashlen, int *stat)
-{
-   unsigned long inlen, pklen, ID;
-   pk_key *kr;
-   int err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(in != NULL);
-   _ARGCHK(hash != NULL);
-   _ARGCHK(stat != NULL);
-
-   /* default to not match */
-   *stat = 0;
-
-   /* check magic header */
-   if (memcmp(in, sign_magic, 4)) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* now try to find key */
-   LOAD32L(ID,in+4);
-   kr = kr_find(pk, ID);
-   if (kr == NULL) {
-      return CRYPT_PK_NOT_FOUND;
-   }
-
-   /* now try and verify it */
-   LOAD32L(inlen,in+8);         /* this is the length of the original inlen */
-   LOAD32L(pklen,in+12);        /* size of the PK packet */
-   if (inlen != hashlen) {      /* size doesn't match means the signature is invalid */
-      return CRYPT_OK;
-   }
-
-   switch (kr->system) {
-       case RSA_KEY:
-           if ((err = rsa_verify_hash(in+16, pklen, hash, stat, &(kr->key.rsa))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-       case DH_KEY:
-           if ((err = dh_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-       case ECC_KEY:
-           if ((err = ecc_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) {
-              return err;
-           }
-           break;
-   }
-   return CRYPT_OK;
-}
-
-int kr_fingerprint(pk_key *pk, unsigned long ID, int hash,
-                   unsigned char *out, unsigned long *outlen)
-{
-   unsigned char buf[8192];
-   unsigned long len;
-   int err;
-
-   _ARGCHK(pk != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* valid hash? */
-   if ((err = hash_is_valid(hash)) != CRYPT_OK) {
-      return err;
-   }
-
-   len = (unsigned long)sizeof(buf);
-   if ((err = kr_export(pk, ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-      return err;
-   }
-   
-   /* now hash it */
-   if ((err = hash_memory(hash, buf, len, out, outlen)) != CRYPT_OK) {
-      return err;
-   }
-
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
-   return CRYPT_OK;
-}
-
-#endif
-
-

+ 0 - 0
tommath.h → ltc_tommath.h


+ 42 - 60
makefile

@@ -9,9 +9,8 @@
 # a build. This is easy to remedy though, for those that have problems.
 
 # The version
-VERSION=0.95
+VERSION=0.96
 
-#ch1-01-1
 # Compiler and Linker Names
 #CC=gcc
 #LD=ld
@@ -19,9 +18,7 @@ VERSION=0.95
 # Archiver [makes .a files]
 #AR=ar
 #ARFLAGS=r
-#ch1-01-1
 
-#ch1-01-3
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow 
 # -Werror
@@ -29,8 +26,8 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow
 # optimize for SPEED
 #CFLAGS += -O3 -funroll-loops
 
-#add -fomit-frame-pointer.  v3.2 is buggy for certain platforms!
-#CFLAGS += -fomit-frame-pointer
+#add -fomit-frame-pointer.  GCC v3.2 is buggy for certain platforms!
+CFLAGS += -fomit-frame-pointer
 
 # optimize for SIZE
 CFLAGS += -Os
@@ -43,7 +40,6 @@ CFLAGS += -Os
 
 #Output filenames for various targets.
 LIBNAME=libtomcrypt.a
-TEST=test
 HASH=hashsum
 CRYPT=encrypt
 SMALL=small
@@ -63,7 +59,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
 #Leave MPI built-in or force developer to link against libtommath?
 MPIOBJECT=mpi.o
 
-OBJECTS=keyring.o gf.o strings.o base64.o \
+OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
 \
 crypt.o                    crypt_find_cipher.o      crypt_find_hash_any.o      \
 crypt_hash_is_valid.o      crypt_register_hash.o    crypt_unregister_prng.o    \
@@ -79,12 +75,16 @@ rand_prime.o is_prime.o \
 \
 ecc.o  dh.o \
 \
-rsa.o rsa_exptmod.o  rsa_free.o  rsa_make_key.o \
+rsa_decrypt_key.o  rsa_encrypt_key.o  rsa_exptmod.o  rsa_free.o  rsa_make_key.o  \
+rsa_sign_hash.o  rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
+\
+dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  \
+dsa_verify_hash.o  dsa_verify_key.o \
 \
-dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  dsa_verify_hash.o  dsa_verify_key.o \
+aes.o aes_enc.o \
 \
-xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \
-rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
+blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
+rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
 \
 md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
 rmd128.o rmd160.o \
@@ -103,10 +103,10 @@ omac_done.o  omac_file.o  omac_init.o  omac_memory.o  omac_process.o  omac_test.
 pmac_done.o  pmac_file.o  pmac_init.o  pmac_memory.o  pmac_ntz.o  pmac_process.o  \
 pmac_shift_xor.o  pmac_test.o \
 \
-cbc_start.o cbc_encrypt.o cbc_decrypt.o \
-cfb_start.o cfb_encrypt.o cfb_decrypt.o \
-ofb_start.o ofb_encrypt.o ofb_decrypt.o \
-ctr_start.o ctr_encrypt.o ctr_decrypt.o \
+cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
+cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
+ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
+ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
 ecb_start.o ecb_encrypt.o ecb_decrypt.o \
 \
 hash_file.o  hash_filehandle.o  hash_memory.o \
@@ -115,6 +115,7 @@ hmac_done.o  hmac_file.o  hmac_init.o  hmac_memory.o  hmac_process.o  hmac_test.
 \
 pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o  \
 pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
+pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
 \
 pkcs_5_1.o pkcs_5_2.o \
 \
@@ -129,26 +130,27 @@ PROFS=demos/x86_prof.o
 TVS=demos/tv_gen.o
 
 #Files left over from making the crypt.pdf.
-LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind
+LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out
 
 #Compressed filenames
-COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
+COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
 
 #Header files used by libtomcrypt.
-HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
+HEADERS=ltc_tommath.h mycrypt_cfg.h \
 mycrypt_misc.h  mycrypt_prng.h mycrypt_cipher.h  mycrypt_hash.h \
 mycrypt_macros.h  mycrypt_pk.h mycrypt.h mycrypt_argchk.h \
 mycrypt_custom.h mycrypt_pkcs.h
 
 #The default rule for make builds the libtomcrypt library.
-default:library mycrypt.h mycrypt_cfg.h
+default:library
 
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.o: aes.c aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
+		
 #These are the rules to make certain object files.
-rsa.o: rsa.c rsa_sys.c
 ecc.o: ecc.c ecc_sys.c
 dh.o: dh.c dh_sys.c
-aes.o: aes.c aes_tab.c
-twofish.o: twofish.c twofish_tab.c
 sha512.o: sha512.c sha384.c
 sha256.o: sha256.c sha224.c
 
@@ -158,10 +160,6 @@ library: $(LIBNAME)
 $(LIBNAME): $(OBJECTS)
 	$(AR) $(ARFLAGS) $@ $(OBJECTS) 
 
-#This rule makes the test program included with libtomcrypt
-test: library $(TESTOBJECTS)
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN)
-
 #This rule makes the hash program included with libtomcrypt
 hashsum: library $(HASHOBJECTS)
 	$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@@ -180,34 +178,6 @@ x86_prof: library $(PROFS)
 tv_gen: library $(TVS)
 	$(CC) $(TVS) $(LIBNAME) -o $(TV)
 
-
-#make a profiled library (takes a while!!!)
-#
-# This will build the library with profile generation
-# then run the test demo and rebuild the library.
-# 
-# So far I've seen improvements in the MP math
-#
-# This works with GCC v3.3.x [tested with 3.3.3]
-profiled: $(TESTOBJECTS)
-	make CFLAGS="$(CFLAGS) -fprofile-arcs"
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST)
-	./test
-	rm -f *.a *.o test demos/test.o
-	make CFLAGS="$(CFLAGS) -fbranch-probabilities"
-
-
-#Profiling in GCC 3.4.x is a little diff.  
-#
-#Tested with GCC v3.4.0
-profiled34: $(TESTOBJECTS)
-	make CFLAGS="$(CFLAGS) -fprofile-generate"
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -lgcov -o $(TEST)
-	./test
-	rm -f *.a *.o test demos/test.o
-	make CFLAGS="$(CFLAGS) -fprofile-use"
-
-
 #This rule installs the library and the header files. This must be run
 #as root in order to have a high enough permission to write to the correct
 #directories and to set the owner and group to root.
@@ -217,7 +187,7 @@ install: library docs
 	install -d -g root -o root $(DESTDIR)$(DATAPATH)
 	install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH)
 	install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH)
-	install -g root -o root crypt.pdf $(DESTDIR)$(DATAPATH)
+	install -g root -o root doc/crypt.pdf $(DESTDIR)$(DATAPATH)
 
 #This rule cleans the source tree of all compiled code, not including the pdf
 #documentation.
@@ -225,21 +195,31 @@ clean:
 	rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
 	rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV)
 	rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \
-         *.gcda *.gcno demos/*.gcno demos/*.gcda *~
+         *.gcda *.gcno demos/*.gcno demos/*.gcda *~ doc/*
+	cd demos/test ; make clean   
 
 #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
 #from the clean command! This is because most people would like to keep the
 #nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
 #delete it if we are rebuilding it.
 docs: crypt.tex
-	rm -f crypt.pdf $(LEFTOVERS)
+	rm -f doc/crypt.pdf $(LEFTOVERS)
+	echo "hello" > crypt.ind
 	latex crypt > /dev/null
 	makeindex crypt > /dev/null
 	latex crypt > /dev/null
 	latex crypt > /dev/null
 	dvipdf crypt
+	mv -ivf crypt.pdf doc/crypt.pdf
 	rm -f $(LEFTOVERS)
-       
+
+docdvi: crypt.tex
+	echo hello > crypt.ind
+	latex crypt > /dev/null
+	latex crypt > /dev/null
+	makeindex crypt
+	latex crypt > /dev/null
+
 #beta
 beta: clean
 	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \
@@ -250,4 +230,6 @@ beta: clean
 zipup: clean docs
 	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
 	cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \
-	bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/*
+	bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/* ; \
+	gpg -b -a crypt-$(VERSION).tar.bz2 ; \
+   gpg -b -a crypt-$(VERSION).zip

+ 19 - 13
makefile.cygwin_dll

@@ -1,4 +1,4 @@
-
+#makefile for Cygwin [makes a .dll]
 
 default: ltc_dll
 
@@ -18,7 +18,7 @@ CFLAGS += -Os
 #Leave MPI built-in or force developer to link against libtommath?
 MPIOBJECT=mpi.o
 
-OBJECTS=keyring.o gf.o strings.o base64.o \
+OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
 \
 crypt.o                    crypt_find_cipher.o      crypt_find_hash_any.o      \
 crypt_hash_is_valid.o      crypt_register_hash.o    crypt_unregister_prng.o    \
@@ -34,12 +34,16 @@ rand_prime.o is_prime.o \
 \
 ecc.o  dh.o \
 \
-rsa.o rsa_exptmod.o  rsa_free.o  rsa_make_key.o \
+rsa_decrypt_key.o  rsa_encrypt_key.o  rsa_exptmod.o  rsa_free.o  rsa_make_key.o  \
+rsa_sign_hash.o  rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
+\
+dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  \
+dsa_verify_hash.o  dsa_verify_key.o \
 \
-dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  dsa_verify_hash.o  dsa_verify_key.o \
+aes.o aes_enc.o \
 \
-xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \
-rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
+blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
+rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
 \
 md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
 rmd128.o rmd160.o \
@@ -58,10 +62,10 @@ omac_done.o  omac_file.o  omac_init.o  omac_memory.o  omac_process.o  omac_test.
 pmac_done.o  pmac_file.o  pmac_init.o  pmac_memory.o  pmac_ntz.o  pmac_process.o  \
 pmac_shift_xor.o  pmac_test.o \
 \
-cbc_start.o cbc_encrypt.o cbc_decrypt.o \
-cfb_start.o cfb_encrypt.o cfb_decrypt.o \
-ofb_start.o ofb_encrypt.o ofb_decrypt.o \
-ctr_start.o ctr_encrypt.o ctr_decrypt.o \
+cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
+cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
+ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
+ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
 ecb_start.o ecb_encrypt.o ecb_decrypt.o \
 \
 hash_file.o  hash_filehandle.o  hash_memory.o \
@@ -70,15 +74,17 @@ hmac_done.o  hmac_file.o  hmac_init.o  hmac_memory.o  hmac_process.o  hmac_test.
 \
 pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o  \
 pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
+pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
 \
 pkcs_5_1.o pkcs_5_2.o \
 \
 burn_stack.o zeromem.o \
 $(MPIOBJECT)
 
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.o: aes.c aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
+
 ltc_dll: $(OBJECTS) $(MPIOBJECT)
 	gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32
 	ranlib libtomcrypt.dll.a
-
-test: ltc_dll
-	gcc $(CFLAGS) demos/test.c libtomcrypt.dll.a -Wl,--enable-auto-import -o test -s

+ 23 - 31
makefile.icc

@@ -24,6 +24,9 @@ CC=icc
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 CFLAGS += -c -I./ -DINTEL_CC
 
+#The default rule for make builds the libtomcrypt library.
+default:library
+
 # optimize for SPEED
 #
 # -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
@@ -47,7 +50,6 @@ CFLAGS += -O3 -xN -ip
 
 #Output filenames for various targets.
 LIBNAME=libtomcrypt.a
-TEST=test
 HASH=hashsum
 CRYPT=encrypt
 SMALL=small
@@ -67,7 +69,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
 #Leave MPI built-in or force developer to link against libtommath?
 MPIOBJECT=mpi.o
 
-OBJECTS=keyring.o gf.o strings.o base64.o \
+OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
 \
 crypt.o                    crypt_find_cipher.o      crypt_find_hash_any.o      \
 crypt_hash_is_valid.o      crypt_register_hash.o    crypt_unregister_prng.o    \
@@ -83,12 +85,16 @@ rand_prime.o is_prime.o \
 \
 ecc.o  dh.o \
 \
-rsa.o rsa_exptmod.o  rsa_free.o  rsa_make_key.o \
+rsa_decrypt_key.o  rsa_encrypt_key.o  rsa_exptmod.o  rsa_free.o  rsa_make_key.o  \
+rsa_sign_hash.o  rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
+\
+dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  \
+dsa_verify_hash.o  dsa_verify_key.o \
 \
-dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  dsa_verify_hash.o  dsa_verify_key.o \
+aes.o aes_enc.o \
 \
-xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \
-rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
+blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
+rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
 \
 md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
 rmd128.o rmd160.o \
@@ -107,10 +113,10 @@ omac_done.o  omac_file.o  omac_init.o  omac_memory.o  omac_process.o  omac_test.
 pmac_done.o  pmac_file.o  pmac_init.o  pmac_memory.o  pmac_ntz.o  pmac_process.o  \
 pmac_shift_xor.o  pmac_test.o \
 \
-cbc_start.o cbc_encrypt.o cbc_decrypt.o \
-cfb_start.o cfb_encrypt.o cfb_decrypt.o \
-ofb_start.o ofb_encrypt.o ofb_decrypt.o \
-ctr_start.o ctr_encrypt.o ctr_decrypt.o \
+cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
+cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
+ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
+ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
 ecb_start.o ecb_encrypt.o ecb_decrypt.o \
 \
 hash_file.o  hash_filehandle.o  hash_memory.o \
@@ -119,13 +125,18 @@ hmac_done.o  hmac_file.o  hmac_init.o  hmac_memory.o  hmac_process.o  hmac_test.
 \
 pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o  \
 pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
+pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
 \
 pkcs_5_1.o pkcs_5_2.o \
 \
 burn_stack.o zeromem.o \
 $(MPIOBJECT)
 
-TESTOBJECTS=demos/test.o
+
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.o: aes.c aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
+
 HASHOBJECTS=demos/hashsum.o
 CRYPTOBJECTS=demos/encrypt.o
 SMALLOBJECTS=demos/small.o
@@ -143,9 +154,6 @@ HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
 mycrypt_misc.h  mycrypt_prng.h mycrypt_cipher.h  mycrypt_hash.h \
 mycrypt_macros.h  mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h
 
-#The default rule for make builds the libtomcrypt library.
-default:library mycrypt.h mycrypt_cfg.h
-
 #These are the rules to make certain object files.
 rsa.o: rsa.c rsa_sys.c
 ecc.o: ecc.c ecc_sys.c
@@ -161,10 +169,6 @@ library: $(LIBNAME)
 $(LIBNAME): $(OBJECTS)
 	$(AR) $(ARFLAGS) $@ $(OBJECTS) 
 
-#This rule makes the test program included with libtomcrypt
-test: library $(TESTOBJECTS)
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN)
-
 #This rule makes the hash program included with libtomcrypt
 hashsum: library $(HASHOBJECTS)
 	$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@@ -183,19 +187,7 @@ x86_prof: library $(PROFS)
 tv_gen: library $(TVS)
 	$(CC) $(TVS) $(LIBNAME) -o $(TV)
 
-
-#make a profiled library (takes a while!!!)
-#
-# This will build the library with profile generation
-# then run the test demo and rebuild the library.
-# 
-# So far I've seen improvements in the MP math
-profiled:
-	make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen" test
-	./test
-	rm -f *.a *.o test demos/test.o
-	make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use"
-   
+  
 #This rule installs the library and the header files. This must be run
 #as root in order to have a high enough permission to write to the correct
 #directories and to set the owner and group to root.

+ 19 - 17
makefile.msvc

@@ -8,8 +8,7 @@ default: library
 # leave this blank and link against libtommath if you want better link resolution
 MPIOBJECT=mpi.obj
 
-#List of objects to compile.
-OBJECTS=keyring.obj gf.obj strings.obj base64.obj \
+OBJECTS=error_to_string.obj mpi_to_ltc_error.obj base64_encode.obj base64_decode.obj \
 \
 crypt.obj                    crypt_find_cipher.obj      crypt_find_hash_any.obj      \
 crypt_hash_is_valid.obj      crypt_register_hash.obj    crypt_unregister_prng.obj    \
@@ -25,12 +24,16 @@ rand_prime.obj is_prime.obj \
 \
 ecc.obj  dh.obj \
 \
-rsa.obj rsa_exptmod.obj  rsa_free.obj  rsa_make_key.obj \
+rsa_decrypt_key.obj  rsa_encrypt_key.obj  rsa_exptmod.obj  rsa_free.obj  rsa_make_key.obj  \
+rsa_sign_hash.obj  rsa_verify_hash.obj rsa_export.obj rsa_import.obj tim_exptmod.obj \
 \
-dsa_export.obj  dsa_free.obj  dsa_import.obj  dsa_make_key.obj  dsa_sign_hash.obj  dsa_verify_hash.obj  dsa_verify_key.obj \
+dsa_export.obj  dsa_free.obj  dsa_import.obj  dsa_make_key.obj  dsa_sign_hash.obj  \
+dsa_verify_hash.obj  dsa_verify_key.obj \
 \
-xtea.obj aes.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj \
-rc6.obj rc5.obj cast5.obj noekeon.obj blowfish.obj twofish.obj skipjack.obj \
+aes.obj aes_enc.obj \
+\
+blowfish.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj xtea.obj \
+rc6.obj rc5.obj cast5.obj noekeon.obj twofish.obj skipjack.obj \
 \
 md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \
 rmd128.obj rmd160.obj \
@@ -49,10 +52,10 @@ omac_done.obj  omac_file.obj  omac_init.obj  omac_memory.obj  omac_process.obj
 pmac_done.obj  pmac_file.obj  pmac_init.obj  pmac_memory.obj  pmac_ntz.obj  pmac_process.obj  \
 pmac_shift_xor.obj  pmac_test.obj \
 \
-cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj \
-cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj \
-ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj \
-ctr_start.obj ctr_encrypt.obj ctr_decrypt.obj \
+cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj cbc_getiv.obj cbc_setiv.obj \
+cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj cfb_getiv.obj cfb_setiv.obj \
+ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj ofb_getiv.obj ofb_setiv.obj \
+ctr_start.obj ctr_encrypt.obj ctr_decrypt.obj ctr_getiv.obj ctr_setiv.obj \
 ecb_start.obj ecb_encrypt.obj ecb_decrypt.obj \
 \
 hash_file.obj  hash_filehandle.obj  hash_memory.obj \
@@ -61,21 +64,20 @@ hmac_done.obj  hmac_file.obj  hmac_init.obj  hmac_memory.obj  hmac_process.obj
 \
 pkcs_1_mgf1.obj pkcs_1_oaep_encode.obj pkcs_1_oaep_decode.obj  \
 pkcs_1_pss_encode.obj pkcs_1_pss_decode.obj pkcs_1_i2osp.obj pkcs_1_os2ip.obj \
+pkcs_1_v15_es_encode.obj pkcs_1_v15_es_decode.obj pkcs_1_v15_sa_encode.obj pkcs_1_v15_sa_decode.obj \
 \
 pkcs_5_1.obj pkcs_5_2.obj \
 \
-burn_stack.obj zeromem.obj 	\
+burn_stack.obj zeromem.obj \
 $(MPIOBJECT)
 
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.obj: aes.c aes_tab.c
+	$(CC) $(CFLAGS) /DENCRYPT_ONLY /c aes.c /Foaes_enc.obj
+
 library: $(OBJECTS)
 	lib /out:tomcrypt.lib $(OBJECTS)
 	
-test.obj: demos/test.c
-	cl $(CFLAGS) /c demos/test.c
-
-test: library test.obj
-	cl test.obj tomcrypt.lib advapi32.lib	
-	
 x86_prof: demos/x86_prof.c library
 	cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib 
 

+ 7 - 0
md2.c

@@ -19,6 +19,13 @@ const struct _hash_descriptor md2_desc =
     7,
     16,
     16,
+
+    /* DER encoding */
+    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
+      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 
+      0x04, 0x10 },
+    18,
+
     &md2_init,
     &md2_process,
     &md2_done,

+ 5 - 0
md4.c

@@ -19,6 +19,11 @@ const struct _hash_descriptor md4_desc =
     6,
     16,
     64,
+ 
+    /* DER encoding (not yet supported) */
+    { 0x00 },
+    0,    
+
     &md4_init,
     &md4_process,
     &md4_done,

+ 62 - 0
md5.c

@@ -21,6 +21,13 @@ const struct _hash_descriptor md5_desc =
     3,
     16,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
+      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 
+      0x04, 0x10 },
+    18,
+
     &md5_init,
     &md5_process,
     &md5_done,
@@ -44,6 +51,35 @@ const struct _hash_descriptor md5_desc =
 #define II(a,b,c,d,M,s,t) \
     a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
 
+#ifdef SMALL_CODE
+
+static const unsigned char Worder[64] = {
+   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+   1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
+   5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
+   0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
+};
+
+static const unsigned char Rorder[64] = {
+   7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
+   5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
+   4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
+   6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
+};
+
+static const ulong32 Korder[64] = {
+0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
+0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
+0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
+0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
+0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
+0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
+0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
+0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
+};
+
+#endif   
+
 #ifdef CLEAN_STACK
 static void _md5_compress(hash_state *md, unsigned char *buf)
 #else
@@ -51,6 +87,9 @@ static void md5_compress(hash_state *md, unsigned char *buf)
 #endif
 {
     ulong32 i, W[16], a, b, c, d;
+#ifdef SMALL_CODE
+    ulong32 t;
+#endif
 
     /* copy the state into 512-bits into W[0..15] */
     for (i = 0; i < 16; i++) {
@@ -63,6 +102,28 @@ static void md5_compress(hash_state *md, unsigned char *buf)
     c = md->md5.state[2];
     d = md->md5.state[3];
 
+#ifdef SMALL_CODE
+    for (i = 0; i < 16; ++i) {
+        FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 32; ++i) {
+        GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 48; ++i) {
+        HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 64; ++i) {
+        II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+#else
     FF(a,b,c,d,W[0],7,0xd76aa478UL)
     FF(d,a,b,c,W[1],12,0xe8c7b756UL)
     FF(c,d,a,b,W[2],17,0x242070dbUL)
@@ -127,6 +188,7 @@ static void md5_compress(hash_state *md, unsigned char *buf)
     II(d,a,b,c,W[11],10,0xbd3af235UL)
     II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
     II(b,c,d,a,W[9],21,0xeb86d391UL)
+#endif
 
     md->md5.state[0] = md->md5.state[0] + a;
     md->md5.state[1] = md->md5.state[1] + b;

+ 46 - 0
modes_test.c

@@ -0,0 +1,46 @@
+/* test CFB/OFB/CBC modes */
+#include "test.h"
+
+int modes_test(void)
+{
+   unsigned char pt[64], ct[64], tmp[64], key[16], iv[16];
+   int x, cipher_idx;
+   symmetric_CBC cbc;
+   
+   /* make a random pt, key and iv */
+   yarrow_read(pt, 64,  &test_yarrow);
+   yarrow_read(key, 16, &test_yarrow);
+   yarrow_read(iv, 16,  &test_yarrow);
+   
+/* test CBC mode */
+   cipher_idx = find_cipher("aes");
+   if (cipher_idx == -1) {
+      printf("test requires AES");
+      return 1;
+   }
+   
+   
+   /* encode the block */
+   DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+   for (x = 0; x < 4; x++) {
+      DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc));
+   }
+   
+   /* decode the block */
+   DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+   for (x = 0; x < 4; x++) {
+      DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc));
+   }
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CBC failed");
+      return 1;
+   }
+   
+/*   
+   extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
+                     int keylen, int num_rounds, symmetric_CBC *cbc);
+extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc);
+extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc);
+*/
+
+}

Plik diff jest za duży
+ 112 - 112
mpi.c


+ 36 - 0
mpi_to_ltc_error.c

@@ -0,0 +1,36 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MPI
+static const struct {
+    int mpi_code, ltc_code;
+} mpi_to_ltc_codes[] = {
+   { MP_OKAY ,  CRYPT_OK},
+   { MP_MEM  ,  CRYPT_MEM},
+   { MP_VAL  ,  CRYPT_INVALID_ARG},
+};
+
+/* convert a MPI error to a LTC error (Possibly the most powerful function ever!  Oh wait... no) */
+int mpi_to_ltc_error(int err)
+{
+   int x;
+
+   for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
+       if (err == mpi_to_ltc_codes[x].mpi_code) { 
+          return mpi_to_ltc_codes[x].ltc_code;
+       }
+   }
+   return CRYPT_ERROR;
+}
+#endif
+

+ 2 - 4
mycrypt.h

@@ -16,8 +16,8 @@ extern "C" {
 #endif
 
 /* version */
-#define CRYPT   0x0095
-#define SCRYPT  "0.95"
+#define CRYPT   0x0096
+#define SCRYPT  "0.96"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE           128
@@ -68,9 +68,7 @@ enum {
 #include <mycrypt_hash.h>
 #include <mycrypt_prng.h>
 #include <mycrypt_pk.h>
-#include <mycrypt_gf.h>
 #include <mycrypt_misc.h>
-#include <mycrypt_kr.h>
 #include <mycrypt_argchk.h>
 #include <mycrypt_pkcs.h>
 

+ 18 - 0
mycrypt_cipher.h

@@ -261,12 +261,22 @@ extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk
 #define aes_test            rijndael_test
 #define aes_keysize         rijndael_keysize
 
+#define aes_enc_setup           rijndael_enc_setup
+#define aes_enc_ecb_encrypt     rijndael_enc_ecb_encrypt
+#define aes_enc_keysize         rijndael_enc_keysize
+
 extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
 extern void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
 extern int rijndael_test(void);
 extern int rijndael_keysize(int *desired_keysize);
+
+extern int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+extern void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
+extern int rijndael_enc_keysize(int *desired_keysize);
+
 extern const struct _cipher_descriptor rijndael_desc, aes_desc;
+extern const struct _cipher_descriptor rijndael_enc_desc, aes_enc_desc;
 #endif
 
 #ifdef XTEA
@@ -342,6 +352,8 @@ extern int cfb_start(int cipher, const unsigned char *IV, const unsigned char *k
                      int keylen, int num_rounds, symmetric_CFB *cfb);
 extern int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
 extern int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
+extern int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
+extern int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
 #endif
 
 #ifdef OFB
@@ -349,6 +361,8 @@ extern int ofb_start(int cipher, const unsigned char *IV, const unsigned char *k
                      int keylen, int num_rounds, symmetric_OFB *ofb);
 extern int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
 extern int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
+extern int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
+extern int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
 #endif
 
 #ifdef CBC
@@ -356,6 +370,8 @@ extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *k
                      int keylen, int num_rounds, symmetric_CBC *cbc);
 extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc);
 extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc);
+extern int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
+extern int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
 #endif
 
 #ifdef CTR
@@ -363,6 +379,8 @@ extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *k
                      int keylen, int num_rounds, symmetric_CTR *ctr);
 extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
 extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
+extern int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
+extern int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
 #endif
 
 

+ 32 - 1
mycrypt_custom.h

@@ -9,14 +9,27 @@
 	#error mycrypt_custom.h should be included before mycrypt.h
 #endif
 
+/* macros for various libc functions */
 #define XMALLOC malloc
 #define XREALLOC realloc
 #define XCALLOC calloc
 #define XFREE free
 #define XCLOCK clock
 #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
+
+/* Use small code where possible */
 #define SMALL_CODE
+
+/* Enable self-test test vector checking */
 #define LTC_TEST
+
+/* clean the stack of functions which put private information on stack */
+//#define CLEAN_STACK
+
+/* disable all file related functions */
+//#define NO_FILE
+
+/* various ciphers */
 #define BLOWFISH
 #define RC2
 #define RC5
@@ -26,15 +39,21 @@
 #define XTEA
 #define TWOFISH
 #define TWOFISH_TABLES
+//#define TWOFISH_ALL_TABLES
+//#define TWOFISH_SMALL
 #define DES
 #define CAST5
 #define NOEKEON
 #define SKIPJACK
+
+/* modes of operation */
 #define CFB
 #define OFB
 #define ECB
 #define CBC
 #define CTR
+
+/* hash functions */
 #define WHIRLPOOL
 #define SHA512
 #define SHA384
@@ -47,18 +66,30 @@
 #define MD2
 #define RIPEMD128
 #define RIPEMD160
+
+/* MAC functions */
 #define HMAC
 #define OMAC
 #define PMAC
+
+/* Encrypt + Authenticate Modes */
 #define EAX_MODE
 #define OCB_MODE
+
+/* Various tidbits of modern neatoness */
 #define BASE64
 #define YARROW
+// which descriptor of AES to use? 
+// 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full]
+#define YARROW_AES 0
 #define SPRNG
 #define RC4
 #define DEVRANDOM
 #define TRY_URANDOM_FIRST
+
+/* Public Key Neatoness */
 #define MRSA
+#define RSA_TIMING                   // enable RSA side channel timing prevention 
 #define MDSA
 #define MDH
 #define MECC
@@ -79,10 +110,10 @@
 #define ECC521
 #define MPI
 
+/* PKCS #1 and 5 stuff */
 #define PKCS_1
 #define PKCS_5
 
-
 #include <mycrypt.h>
 
 #endif

+ 0 - 32
mycrypt_gf.h

@@ -1,32 +0,0 @@
-
-/* ---- GF(2^w) polynomial basis ---- */
-#ifdef GF
-#define   LSIZE    32   /* handle upto 1024-bit GF numbers */
-
-typedef unsigned long gf_int[LSIZE];
-typedef unsigned long *gf_intp;
-
-extern void gf_copy(gf_intp a, gf_intp b);
-extern void gf_zero(gf_intp a);
-extern int gf_iszero(gf_intp a);
-extern int gf_isone(gf_intp a);
-extern int gf_deg(gf_intp a);
-
-extern void gf_shl(gf_intp a, gf_intp b);
-extern void gf_shr(gf_intp a, gf_intp b);
-extern void gf_add(gf_intp a, gf_intp b, gf_intp c);
-extern void gf_mul(gf_intp a, gf_intp b, gf_intp c);
-extern void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r);
-
-extern void gf_mod(gf_intp a, gf_intp m, gf_intp b);
-extern void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c);
-extern void gf_invmod(gf_intp A, gf_intp M, gf_intp B);
-extern void gf_sqrt(gf_intp a, gf_intp M, gf_intp b);
-extern void gf_gcd(gf_intp A, gf_intp B, gf_intp c);
-extern int gf_is_prime(gf_intp a);
-
-extern int gf_size(gf_intp a);
-extern void gf_toraw(gf_intp a, unsigned char *dst);
-extern void gf_readraw(gf_intp a, unsigned char *str, int len);
-
-#endif

+ 2 - 0
mycrypt_hash.h

@@ -116,6 +116,8 @@ extern struct _hash_descriptor {
     unsigned char ID;
     unsigned long hashsize;       /* digest output size in bytes  */
     unsigned long blocksize;      /* the block size the hash uses */
+    unsigned char DER[64];        /* DER encoded identifier */
+    unsigned long DERlen;         /* length of DER encoding */
     void (*init)(hash_state *);
     int (*process)(hash_state *, const unsigned char *, unsigned long);
     int (*done)(hash_state *, unsigned char *);

+ 39 - 31
mycrypt_pk.h

@@ -1,7 +1,7 @@
 /* ---- NUMBER THEORY ---- */
 #ifdef MPI
 
-#include "tommath.h"
+#include "ltc_tommath.h"
 
 /* in/out macros */
 #define OUTPUT_BIGNUM(num, out, y, z)                                                             \
@@ -86,7 +86,7 @@ extern int packet_valid_header(unsigned char *src, int section, int subsection);
 #define MAX_RSA_SIZE 4096
 
 /* Stack required for temps (plus padding) */
-#define RSA_STACK    (8 + (MAX_RSA_SIZE/8))
+// #define RSA_STACK    (8 + (MAX_RSA_SIZE/8))
 
 typedef struct Rsa_key {
     int type;
@@ -95,43 +95,51 @@ typedef struct Rsa_key {
 
 extern int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
 
-extern int rsa_exptmod(const unsigned char *in,  unsigned long inlen, 
-                             unsigned char *out, unsigned long *outlen, int which, 
-                             rsa_key *key);
+extern int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long *outlen, int which,
+                      prng_state    *prng, int           prng_idx,
+                      rsa_key *key);
 
-extern int rsa_pad(const unsigned char *in,  unsigned long inlen, 
-                         unsigned char *out, unsigned long *outlen, 
-                         int wprng, prng_state *prng);
+#ifdef RSA_TIMING
 
-extern int rsa_signpad(const unsigned char *in,  unsigned long inlen, 
-                             unsigned char *out, unsigned long *outlen);
+extern int tim_exptmod(prng_state *prng, int prng_idx, 
+                       mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m);
 
-extern int rsa_depad(const unsigned char *in,  unsigned long inlen, 
-                           unsigned char *out, unsigned long *outlen);
+#else
 
-extern int rsa_signdepad(const unsigned char *in,  unsigned long inlen,
-                               unsigned char *out, unsigned long *outlen);
+#define tim_exptmod(prng, prng_idx, c, e, d, n, m) mpi_to_ltc_error(mp_exptmod(c, d, n, m))
 
+#endif
 
 extern void rsa_free(rsa_key *key);
 
-extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
-                                 unsigned char *outkey, unsigned long *outlen,
-                                 prng_state *prng, int wprng, rsa_key *key);
-
-extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
-                                 unsigned char *outkey, unsigned long *keylen, 
-                                 rsa_key *key);
-
-extern int rsa_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                               unsigned char *out, unsigned long *outlen, 
-                               rsa_key *key);
-
-extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
-                           const unsigned char *hash, int *stat, rsa_key *key);
-
-extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
-extern int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
+int rsa_encrypt_key(const unsigned char *inkey,  unsigned long inlen,
+                          unsigned char *outkey, unsigned long *outlen,
+                    const unsigned char *lparam, unsigned long lparamlen,
+                    prng_state *prng, int prng_idx, int hash_idx, rsa_key *key);
+                                        
+int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
+                          unsigned char *outkey, unsigned long *keylen, 
+                    const unsigned char *lparam, unsigned long lparamlen,
+                          prng_state    *prng,   int           prng_idx,
+                          int            hash_idx, int *res,
+                          rsa_key       *key);
+
+int rsa_sign_hash(const unsigned char *msghash,  unsigned long  msghashlen, 
+                        unsigned char *sig,      unsigned long *siglen, 
+                        prng_state    *prng,     int            prng_idx,
+                        int            hash_idx, unsigned long  saltlen,
+                        rsa_key *key);
+
+int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
+                    const unsigned char *msghash,  unsigned long msghashlen,
+                          prng_state    *prng,     int           prng_idx,
+                          int            hash_idx, unsigned long saltlen,
+                          int           *stat,     rsa_key      *key);
+
+int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
+int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
+                        
 #endif
 
 /* ---- DH Routines ---- */

+ 34 - 7
mycrypt_pkcs.h

@@ -7,20 +7,25 @@ int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
                       int            hash_idx,
                       unsigned char *mask, unsigned long masklen);
 
+int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out);
+int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen);
+
+/* *** v2.0 padding */
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
-                             unsigned long modulus_bitlen, int hash_idx,
-                             int           prng_idx,    prng_state *prng,
+                             unsigned long modulus_bitlen, prng_state *prng,
+                             int           prng_idx,         int  hash_idx,
                              unsigned char *out,    unsigned long *outlen);
 
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
                              unsigned long modulus_bitlen, int hash_idx,
-                             unsigned char *out,    unsigned long *outlen);
+                             unsigned char *out,    unsigned long *outlen,
+                             int           *res);
 
 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
-                            unsigned long saltlen,  int           hash_idx,
-                            int           prng_idx, prng_state   *prng,
+                            unsigned long saltlen,  prng_state   *prng,     
+                            int           prng_idx, int           hash_idx,
                             unsigned long modulus_bitlen,
                             unsigned char *out,     unsigned long *outlen);
 
@@ -29,8 +34,30 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
                             unsigned long saltlen,  int           hash_idx,
                             unsigned long modulus_bitlen, int    *res);
 
-int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out);
-int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen);
+/* *** v1.5 padding */
+/* encryption padding */
+int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
+                               unsigned long  modulus_bitlen, 
+                               prng_state    *prng,   int           prng_idx,
+                               unsigned char *out,    unsigned long *outlen);
+
+/* note "outlen" is fixed, you have to tell this decoder how big
+ * the original message was.  Unlike the OAEP decoder it cannot auto-detect it.
+ */
+int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
+                               unsigned long modulus_bitlen,
+                               unsigned char *out,  unsigned long outlen,
+                               int           *res);
+
+/* signature padding */
+int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
+                               int            hash_idx, unsigned long modulus_bitlen,
+                               unsigned char *out,      unsigned long *outlen);
+
+int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
+                         const unsigned char *sig,     unsigned long siglen,
+                               int           hash_idx, unsigned long modulus_bitlen, 
+                               int          *res);
 
 
 #endif /* PKCS_1 */

+ 5 - 0
ocb_decrypt.c

@@ -22,9 +22,14 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != NULL);
    _ARGCHK(ct  != NULL);
+
+   /* check if valid cipher */
    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
       return err;
    }
+   _ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL);
+   
+   /* check length */
    if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
       return CRYPT_INVALID_ARG;
    }

+ 30 - 0
ofb_getiv.c

@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef OFB
+
+int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(ofb != NULL);
+   if ((unsigned long)ofb->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, ofb->IV, ofb->blocklen);
+   *len = ofb->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif

+ 38 - 0
ofb_setiv.c

@@ -0,0 +1,38 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef OFB
+
+int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
+{
+   int err;
+
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(ofb != NULL);
+
+   if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
+       return err;
+   }
+
+   if (len != (unsigned long)ofb->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* force next block */
+   ofb->padlen = 0;
+   cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
+   return CRYPT_OK;
+}
+
+#endif 
+

+ 14 - 6
pkcs_1_oaep_decode.c

@@ -15,9 +15,10 @@
 #ifdef PKCS_1
 
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
-                        const unsigned char *lparam, unsigned long lparamlen,
-                              unsigned long modulus_bitlen, int hash_idx,
-                              unsigned char *out,    unsigned long *outlen)
+                       const unsigned char *lparam, unsigned long lparamlen,
+                             unsigned long modulus_bitlen, int hash_idx,
+                             unsigned char *out,    unsigned long *outlen,
+                             int           *res)
 {
    unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
    unsigned long hLen, x, y, modulus_len;
@@ -26,6 +27,10 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    _ARGCHK(msg    != NULL);
    _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
+   _ARGCHK(res    != NULL);
+
+   /* default to invalid packet */
+   *res = 0;
    
    /* test valid hash */
    if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { 
@@ -49,7 +54,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
 
    /* must have leading 0x00 byte */
    if (msg[0] != 0x00) {
-      return CRYPT_INVALID_PACKET;
+      return CRYPT_OK;
    }
 
    /* now read the masked seed */
@@ -99,7 +104,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
 
    /* compare the lhash'es */
    if (memcmp(seed, DB, hLen) != 0) {
-      return CRYPT_INVALID_PACKET;
+      return CRYPT_OK;
    }
 
    /* now zeroes before a 0x01 */
@@ -109,7 +114,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
 
    /* error out if wasn't 0x01 */
    if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
-      return CRYPT_INVALID_PACKET;
+      return CRYPT_OK;
    }
 
    /* rest is the message (and skip 0x01) */
@@ -129,6 +134,9 @@ int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
    zeromem(mask, sizeof(mask));
 #endif
 
+   /* valid packet */
+   *res = 1;
+
    return CRYPT_OK;
 }
 

+ 4 - 4
pkcs_1_oaep_encode.c

@@ -15,10 +15,10 @@
 #ifdef PKCS_1
 
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
-                        const unsigned char *lparam, unsigned long lparamlen,
-                              unsigned long modulus_bitlen, int hash_idx,
-                              int           prng_idx,    prng_state *prng,
-                              unsigned char *out,    unsigned long *outlen)
+                       const unsigned char *lparam, unsigned long lparamlen,
+                             unsigned long modulus_bitlen, prng_state *prng,
+                             int           prng_idx,         int  hash_idx,
+                             unsigned char *out,    unsigned long *outlen)
 {
    unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
    unsigned long hLen, x, y, modulus_len;

+ 4 - 1
pkcs_1_pss_decode.c

@@ -60,7 +60,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
    }
 
    /* check the MSB */
-   if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - modulus_bitlen))) != 0) {
+   if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
       return CRYPT_OK;
    }
 
@@ -73,6 +73,9 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
    for (y = 0; y < (modulus_len - hLen - 1); y++) {
       DB[y] ^= mask[y];
    }
+   
+   /* now clear the first byte [make sure smaller than modulus] */
+   DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
 
    /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
 

+ 3 - 3
pkcs_1_pss_encode.c

@@ -15,8 +15,8 @@
 #ifdef PKCS_1
 
 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
-                            unsigned long saltlen,  int           hash_idx,
-                            int           prng_idx, prng_state   *prng,
+                            unsigned long saltlen,  prng_state   *prng,     
+                            int           prng_idx, int           hash_idx,
                             unsigned long modulus_bitlen,
                             unsigned char *out,     unsigned long *outlen)
 {
@@ -104,7 +104,7 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
    out[y] = 0xBC;
 
    /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
-   out[0] &= 0xFF >> ((modulus_len<<3) - modulus_bitlen);
+   out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
 
    /* store output size */
    *outlen = modulus_len;

+ 61 - 0
pkcs_1_v15_es_decode.c

@@ -0,0 +1,61 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* PKCS #1 v1.5 Encryption Padding -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
+                               unsigned long modulus_bitlen,
+                               unsigned char *out,  unsigned long outlen,
+                               int           *res)
+{
+   unsigned long x, modulus_bytelen;
+
+   _ARGCHK(msg != NULL);
+   _ARGCHK(out != NULL);
+   _ARGCHK(res != NULL);
+   
+   /* default to failed */
+   *res = 0;
+
+   /* must be at least 12 bytes long */
+   if (msglen < 12) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+
+   /* should start with 0x00 0x02 */
+   if (msg[0] != 0x00 || msg[1] != 0x02) {
+      return CRYPT_OK;
+   }
+   
+   /* skip over PS */
+   x = 2 + (modulus_bytelen - outlen - 3);
+
+   /* should be 0x00 */
+   if (msg[x++] != 0x00) {
+      return CRYPT_OK;
+   }
+
+   /* the message is left */
+   if (x + outlen > modulus_bytelen) {
+      return CRYPT_PK_INVALID_SIZE;
+   }
+   memcpy(out, msg + x, outlen);
+   *res = 1;
+   return CRYPT_OK;
+}
+
+#endif 
+

+ 55 - 0
pkcs_1_v15_es_encode.c

@@ -0,0 +1,55 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* v1.5 Encryption Padding for PKCS #1 -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
+                               unsigned long  modulus_bitlen, 
+                               prng_state    *prng,   int           prng_idx,
+                               unsigned char *out,    unsigned long *outlen)
+{ 
+   unsigned long modulus_bytelen, x, y;
+
+   _ARGCHK(msg    != NULL);
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+
+   /* get modulus len */
+   modulus_bytelen = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
+   if (modulus_bytelen < 12) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* verify length */
+   if (msglen > (modulus_bytelen - 11) || *outlen < modulus_bytelen) {
+      return CRYPT_PK_INVALID_SIZE;
+   }
+
+   /* 0x00 0x02 PS 0x00 M */
+   x = 0;
+   out[x++] = 0x00;
+   out[x++] = 0x02;
+   y = modulus_bytelen - msglen - 3;
+   if (prng_descriptor[prng_idx].read(out+x, y, prng) != y) {
+      return CRYPT_ERROR_READPRNG;
+   }
+   x += y;
+   out[x++] = 0x00;
+   memcpy(out+x, msg, msglen);
+   *outlen = modulus_bytelen;
+
+   return CRYPT_OK;
+}
+
+#endif /* PKCS_1 */

+ 77 - 0
pkcs_1_v15_sa_decode.c

@@ -0,0 +1,77 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* PKCS #1 v1.5 Signature Padding -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
+                         const unsigned char *sig,     unsigned long siglen,
+                               int           hash_idx, unsigned long modulus_bitlen, 
+                               int          *res)
+{
+   unsigned long x, y, modulus_bytelen, derlen;
+   int err;
+   
+   _ARGCHK(msghash != NULL);
+   _ARGCHK(sig     != NULL);
+   _ARGCHK(res     != NULL);
+
+   /* default to invalid */
+   *res = 0;
+
+   /* valid hash ? */
+   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* get derlen */
+   derlen = hash_descriptor[hash_idx].DERlen;
+
+   /* get modulus len */
+   modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+
+   /* valid sizes? */
+   if ((msghashlen + 3 + derlen > modulus_bytelen) || (siglen != modulus_bytelen)) {
+      return CRYPT_PK_INVALID_SIZE;
+   }
+
+   /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
+   x = 0;
+   if (sig[x++] != 0x00 || sig[x++] != 0x01) {
+      return CRYPT_OK;
+   }
+
+   /* now follows (modulus_bytelen - 3 - derlen - msghashlen) 0xFF bytes */
+   for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
+     if (sig[x++] != 0xFF) {
+        return CRYPT_OK;
+     }
+   }
+
+   if (sig[x++] != 0x00) {
+      return CRYPT_OK;
+   }
+
+   for (y = 0; y < derlen; y++) {
+      if (sig[x++] != hash_descriptor[hash_idx].DER[y]) {
+         return CRYPT_OK;
+      }
+   }
+
+   if (memcmp(msghash, sig+x, msghashlen) == 0) {
+      *res = 1;
+   }
+   return CRYPT_OK;
+}
+
+#endif 

+ 71 - 0
pkcs_1_v15_sa_encode.c

@@ -0,0 +1,71 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* PKCS #1 v1.5 Signature Padding -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
+                               int            hash_idx, unsigned long modulus_bitlen,
+                               unsigned char *out,      unsigned long *outlen)
+{
+  unsigned long derlen, modulus_bytelen, x, y;
+  int err;
+
+  _ARGCHK(msghash != NULL)
+  _ARGCHK(out     != NULL);
+  _ARGCHK(outlen  != NULL);
+
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+
+  /* hack, to detect any hash without a DER OID */
+  if (hash_descriptor[hash_idx].DERlen == 0) {
+     return CRYPT_INVALID_ARG; 
+  }
+
+  /* get modulus len */
+  modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+
+  /* get der len ok?  Forgive my lame German accent.... */
+  derlen = hash_descriptor[hash_idx].DERlen;
+
+  /* valid sizes? */
+  if (msghashlen + 3 + derlen > modulus_bytelen) {
+     return CRYPT_PK_INVALID_SIZE;
+  }
+
+  if (*outlen < modulus_bytelen) {
+     return CRYPT_BUFFER_OVERFLOW;
+  }
+
+  /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
+  x = 0;
+  out[x++] = 0x00;
+  out[x++] = 0x01;
+  for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
+     out[x++] = 0xFF;
+  }
+  out[x++] = 0x00;
+  for (y = 0; y < derlen; y++) {
+     out[x++] = hash_descriptor[hash_idx].DER[y];
+  }
+  for (y = 0; y < msghashlen; y++) {
+     out[x++] = msghash[y];
+  }
+
+  *outlen = modulus_bytelen;
+  return CRYPT_OK;
+}
+
+#endif /* PKCS_1 */

+ 1 - 5
rand_prime.c

@@ -54,11 +54,7 @@ int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
    /* New prime generation makes the code even more cryptoish-insane.  Do you know what this means!!!
       -- Gir:  Yeah, oh wait, er, no.
     */
-   if ((err = mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng)) != MP_OKAY) {
-      return mpi_to_ltc_error(err);
-   }
-
-   return CRYPT_OK;
+   return mpi_to_ltc_error(mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng));
 }
       
 #endif

+ 5 - 0
rmd128.c

@@ -24,6 +24,11 @@ const struct _hash_descriptor rmd128_desc =
     8,
     16,
     64,
+
+    /* DER identifier (not supported) */
+    { 0x00 },
+    0,
+
     &rmd128_init,
     &rmd128_process,
     &rmd128_done,

+ 6 - 0
rmd160.c

@@ -24,6 +24,12 @@ const struct _hash_descriptor rmd160_desc =
     9,
     20,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 
+      0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 },
+    15,
+
     &rmd160_init,
     &rmd160_process,
     &rmd160_done,

+ 0 - 273
rsa.c

@@ -1,273 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-/* RSA Code by Tom St Denis */
-#include "mycrypt.h"
-
-#ifdef MRSA
-
-int rsa_signpad(const unsigned char *in,  unsigned long inlen,
-                      unsigned char *out, unsigned long *outlen)
-{
-   unsigned long x, y;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-
-   if (*outlen < (3 * inlen)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   /* check inlen */
-   if (inlen > MAX_RSA_SIZE/8) {
-      return CRYPT_PK_INVALID_SIZE;
-   }
-
-   for (y = x = 0; x < inlen; x++)
-       out[y++] = (unsigned char)0xFF;
-   for (x = 0; x < inlen; x++)
-       out[y++] = in[x];
-   for (x = 0; x < inlen; x++)
-       out[y++] = (unsigned char)0xFF;
-   *outlen = 3 * inlen;
-   return CRYPT_OK;
-}
-
-int rsa_pad(const unsigned char *in,  unsigned long inlen,
-                  unsigned char *out, unsigned long *outlen,
-                  int wprng, prng_state *prng)
-{
-   unsigned char buf[3*(MAX_RSA_SIZE/8)];
-   unsigned long x;
-   int err;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-
-   /* is output big enough? */
-   if (*outlen < (3 * inlen)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   /* get random padding required */
-   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* check inlen */
-   if (inlen > (MAX_RSA_SIZE/8)) {
-      return CRYPT_PK_INVALID_SIZE;
-   }
-
-   if (prng_descriptor[wprng].read(buf, inlen*2-2, prng) != (inlen*2 - 2))  {
-       return CRYPT_ERROR_READPRNG;
-   }
-
-   /* pad it like a sandwhich
-    *
-    * Looks like 0xFF R1 M R2 0xFF
-    *
-    * Where R1/R2 are random and exactly equal to the length of M minus one byte.
-    */
-   for (x = 0; x < inlen-1; x++) {
-       out[x+1] = buf[x];
-   }
-
-   for (x = 0; x < inlen; x++) {
-       out[x+inlen] = in[x];
-   }
-
-   for (x = 0; x < inlen-1; x++) {
-       out[x+inlen+inlen] = buf[x+inlen-1];
-   }
-
-   /* last and first bytes are 0xFF */
-   out[0] = out[inlen+inlen+inlen-1] = (unsigned char)0xFF;
-
-   /* clear up and return */
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
-   *outlen = inlen*3;
-   return CRYPT_OK;
-}
-
-int rsa_signdepad(const unsigned char *in,  unsigned long inlen,
-                        unsigned char *out, unsigned long *outlen)
-{
-   unsigned long x;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-
-   if (*outlen < inlen/3) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   /* check padding bytes */
-   for (x = 0; x < inlen/3; x++) {
-       if (in[x] != (unsigned char)0xFF || in[x+(inlen/3)+(inlen/3)] != (unsigned char)0xFF) {
-          return CRYPT_INVALID_PACKET;
-       }
-   }
-   for (x = 0; x < inlen/3; x++) {
-       out[x] = in[x+(inlen/3)];
-   }
-   *outlen = inlen/3;
-   return CRYPT_OK;
-}
-
-int rsa_depad(const unsigned char *in,  unsigned long inlen,
-                    unsigned char *out, unsigned long *outlen)
-{
-   unsigned long x;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-
-   if (*outlen < inlen/3) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-   for (x = 0; x < inlen/3; x++) {
-       out[x] = in[x+(inlen/3)];
-   }
-   *outlen = inlen/3;
-   return CRYPT_OK;
-}
-
-int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
-{
-   unsigned long y, z; 
-   int err;
-
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-   _ARGCHK(key    != NULL);
-   
-   /* can we store the static header?  */
-   if (*outlen < (PACKET_SIZE + 1)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }   
-
-   /* type valid? */
-   if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
-        (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
-      return CRYPT_PK_INVALID_TYPE;
-   }
-
-   /* start at offset y=PACKET_SIZE */
-   y = PACKET_SIZE;
-
-   /* output key type */
-   out[y++] = type;
-
-   /* output modulus */
-   OUTPUT_BIGNUM(&key->N, out, y, z);
-
-   /* output public key */
-   OUTPUT_BIGNUM(&key->e, out, y, z);
-
-   if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
-      OUTPUT_BIGNUM(&key->d, out, y, z);
-   }
-
-   if (type == PK_PRIVATE_OPTIMIZED) {
-      OUTPUT_BIGNUM(&key->dQ, out, y, z);
-      OUTPUT_BIGNUM(&key->dP, out, y, z);
-      OUTPUT_BIGNUM(&key->pQ, out, y, z);
-      OUTPUT_BIGNUM(&key->qP, out, y, z);
-      OUTPUT_BIGNUM(&key->p, out, y, z);
-      OUTPUT_BIGNUM(&key->q, out, y, z);
-   }
-
-   /* store packet header */
-   packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
-
-   /* copy to the user buffer */
-   *outlen = y;
-
-   /* clear stack and return */
-   return CRYPT_OK;
-}
-
-int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
-{
-   unsigned long x, y;
-   int err;
-
-   _ARGCHK(in  != NULL);
-   _ARGCHK(key != NULL);
-
-   /* check length */
-   if (inlen < (1+PACKET_SIZE)) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* test packet header */
-   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* init key */
-   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
-                     &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) {
-      return mpi_to_ltc_error(err);
-   }
-
-   /* get key type */
-   y = PACKET_SIZE;
-   key->type = (int)in[y++];
-
-   /* load the modulus  */
-   INPUT_BIGNUM(&key->N, in, x, y, inlen);
-
-   /* load public exponent */
-   INPUT_BIGNUM(&key->e, in, x, y, inlen);
-
-   /* get private exponent */
-   if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
-      INPUT_BIGNUM(&key->d, in, x, y, inlen);
-   }
-
-   /* get CRT private data if required */
-   if (key->type == PK_PRIVATE_OPTIMIZED) {
-      INPUT_BIGNUM(&key->dQ, in, x, y, inlen);
-      INPUT_BIGNUM(&key->dP, in, x, y, inlen);
-      INPUT_BIGNUM(&key->pQ, in, x, y, inlen);
-      INPUT_BIGNUM(&key->qP, in, x, y, inlen);
-      INPUT_BIGNUM(&key->p, in, x, y, inlen);
-      INPUT_BIGNUM(&key->q, in, x, y, inlen);
-   }
-
-   /* free up ram not required */
-   if (key->type != PK_PRIVATE_OPTIMIZED) {
-      mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
-   }
-   if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
-      mp_clear(&key->d);
-   }
-
-   return CRYPT_OK;
-error:
-   mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
-                  &key->pQ, &key->qP, &key->p, &key->q, NULL);
-   return err;
-}
-
-#include "rsa_sys.c"
-
-#endif /* RSA */
-
-

+ 61 - 0
rsa_decrypt_key.c

@@ -0,0 +1,61 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* decrypt then OAEP depad  */
+int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
+                          unsigned char *outkey, unsigned long *keylen, 
+                    const unsigned char *lparam, unsigned long lparamlen,
+                          prng_state    *prng,   int           prng_idx,
+                          int            hash_idx, int *res,
+                          rsa_key       *key)
+{
+  unsigned long modulus_bitlen, modulus_bytelen, x;
+  int           err;
+  
+  _ARGCHK(outkey != NULL);
+  _ARGCHK(keylen != NULL);
+  _ARGCHK(key    != NULL);
+  _ARGCHK(res    != NULL);
+  
+  /* valid hash ? */
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen != inlen) {
+     return CRYPT_INVALID_PACKET;
+  }
+
+  /* rsa decode the packet */
+  x = *keylen;
+  if ((err = rsa_exptmod(in, inlen, outkey, &x, PK_PRIVATE, prng, prng_idx, key)) != CRYPT_OK) {
+     return err;
+  }
+
+  /* now OAEP decode the packet */
+  return pkcs_1_oaep_decode(outkey, x, lparam, lparamlen, modulus_bitlen, hash_idx,
+                            outkey, keylen, res);
+}
+
+#endif /* MRSA */
+
+
+
+

+ 59 - 0
rsa_encrypt_key.c

@@ -0,0 +1,59 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* OAEP pad then encrypt */
+int rsa_encrypt_key(const unsigned char *inkey,  unsigned long inlen,
+                          unsigned char *outkey, unsigned long *outlen,
+                    const unsigned char *lparam, unsigned long lparamlen,
+                    prng_state *prng, int prng_idx, int hash_idx, rsa_key *key)
+{
+  unsigned long modulus_bitlen, modulus_bytelen, x;
+  int           err;
+  
+  _ARGCHK(inkey  != NULL);
+  _ARGCHK(outkey != NULL);
+  _ARGCHK(outlen != NULL);
+  _ARGCHK(key    != NULL);
+  
+  /* valid prng and hash ? */
+  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+     return err;
+  }
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen > *outlen) {
+     return CRYPT_BUFFER_OVERFLOW;
+  }
+      
+  /* OAEP pad the key */
+  x = *outlen;
+  if ((err = pkcs_1_oaep_encode(inkey, inlen, lparam, 
+                                lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, 
+                                outkey, &x)) != CRYPT_OK) {
+     return err;
+  }                                
+
+  /* rsa exptmod the OAEP pad */
+  return rsa_exptmod(outkey, x, outkey, outlen, PK_PUBLIC, prng, prng_idx, key);
+}
+
+#endif /* MRSA */

+ 72 - 0
rsa_export.c

@@ -0,0 +1,72 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
+{
+   unsigned long y, z; 
+   int err;
+
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+   _ARGCHK(key    != NULL);
+   
+   /* can we store the static header?  */
+   if (*outlen < (PACKET_SIZE + 1)) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }   
+
+   /* type valid? */
+   if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
+        (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+
+   /* start at offset y=PACKET_SIZE */
+   y = PACKET_SIZE;
+
+   /* output key type */
+   out[y++] = type;
+
+   /* output modulus */
+   OUTPUT_BIGNUM(&key->N, out, y, z);
+
+   /* output public key */
+   OUTPUT_BIGNUM(&key->e, out, y, z);
+
+   if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
+      OUTPUT_BIGNUM(&key->d, out, y, z);
+   }
+
+   if (type == PK_PRIVATE_OPTIMIZED) {
+      OUTPUT_BIGNUM(&key->dQ, out, y, z);
+      OUTPUT_BIGNUM(&key->dP, out, y, z);
+      OUTPUT_BIGNUM(&key->pQ, out, y, z);
+      OUTPUT_BIGNUM(&key->qP, out, y, z);
+      OUTPUT_BIGNUM(&key->p, out, y, z);
+      OUTPUT_BIGNUM(&key->q, out, y, z);
+   }
+
+   /* store packet header */
+   packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
+
+   /* copy to the user buffer */
+   *outlen = y;
+
+   /* clear stack and return */
+   return CRYPT_OK;
+}
+
+#endif /* MRSA */
+

+ 19 - 9
rsa_exptmod.c

@@ -14,18 +14,23 @@
 
 #ifdef MRSA
 
-int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
-                      unsigned char *out, unsigned long *outlen, int which,
+int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long *outlen, int which,
+                      prng_state    *prng, int           prng_idx,
                       rsa_key *key)
 {
-   mp_int tmp, tmpa, tmpb;
+   mp_int        tmp, tmpa, tmpb;
    unsigned long x;
-   int err;
+   int           err;
 
    _ARGCHK(in     != NULL);
    _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(key    != NULL);
+   
+   if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+      return err;
+   }
 
    if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
       return CRYPT_PK_NOT_PRIVATE;
@@ -49,10 +54,10 @@ int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
    /* are we using the private exponent and is the key optimized? */
    if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
       /* tmpa = tmp^dP mod p */
-      if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != MP_OKAY)    { goto error; }
+      if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->dP, &key->p, &tmpa)) != MP_OKAY)    { goto error; }
 
       /* tmpb = tmp^dQ mod q */
-      if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != MP_OKAY)    { goto error; }
+      if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e,  &key->dQ, &key->q, &tmpb)) != MP_OKAY)    { goto error; }
 
       /* tmp = tmpa*qP + tmpb*pQ mod N */
       if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY)                { goto error; }
@@ -60,11 +65,15 @@ int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
       if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY)        { goto error; }
    } else {
       /* exptmod it */
-      if ((err = mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp)) != MP_OKAY) { goto error; }
+      if (which == PK_PRIVATE) {
+         if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->d, &key->N, &tmp)) != MP_OKAY) { goto error; }
+      } else {
+         if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != MP_OKAY) { goto error; }
+      }
    }
 
    /* read it back */
-   x = (unsigned long)mp_unsigned_bin_size(&tmp);
+   x = (unsigned long)mp_unsigned_bin_size(&key->N);
    if (x > *outlen) {
       err = CRYPT_BUFFER_OVERFLOW;
       goto done;
@@ -72,7 +81,8 @@ int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
    *outlen = x;
 
    /* convert it */
-   if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY)                    { goto error; }
+   zeromem(out, x);
+   if ((err = mp_to_unsigned_bin(&tmp, out+(x-mp_unsigned_bin_size(&tmp)))) != MP_OKAY) { goto error; }
 
    /* clean up and return */
    err = CRYPT_OK;

+ 81 - 0
rsa_import.c

@@ -0,0 +1,81 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
+{
+   unsigned long x, y;
+   int err;
+
+   _ARGCHK(in  != NULL);
+   _ARGCHK(key != NULL);
+
+   /* check length */
+   if (inlen < (1+PACKET_SIZE)) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* test packet header */
+   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* init key */
+   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
+                     &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
+   }
+
+   /* get key type */
+   y = PACKET_SIZE;
+   key->type = (int)in[y++];
+
+   /* load the modulus  */
+   INPUT_BIGNUM(&key->N, in, x, y, inlen);
+
+   /* load public exponent */
+   INPUT_BIGNUM(&key->e, in, x, y, inlen);
+
+   /* get private exponent */
+   if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
+      INPUT_BIGNUM(&key->d, in, x, y, inlen);
+   }
+
+   /* get CRT private data if required */
+   if (key->type == PK_PRIVATE_OPTIMIZED) {
+      INPUT_BIGNUM(&key->dQ, in, x, y, inlen);
+      INPUT_BIGNUM(&key->dP, in, x, y, inlen);
+      INPUT_BIGNUM(&key->pQ, in, x, y, inlen);
+      INPUT_BIGNUM(&key->qP, in, x, y, inlen);
+      INPUT_BIGNUM(&key->p, in, x, y, inlen);
+      INPUT_BIGNUM(&key->q, in, x, y, inlen);
+   }
+
+   /* free up ram not required */
+   if (key->type != PK_PRIVATE_OPTIMIZED) {
+      mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
+   }
+   if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
+      mp_clear(&key->d);
+   }
+
+   return CRYPT_OK;
+error:
+   mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
+                  &key->pQ, &key->qP, &key->p, &key->q, NULL);
+   return err;
+}
+
+#endif /* MRSA */
+

+ 1 - 1
rsa_make_key.c

@@ -17,7 +17,7 @@
 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 {
    mp_int p, q, tmp1, tmp2, tmp3;
-   int err;
+   int    err;
 
    _ARGCHK(key != NULL);
 

+ 59 - 0
rsa_sign_hash.c

@@ -0,0 +1,59 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* PSS pad then sign */
+int rsa_sign_hash(const unsigned char *msghash,  unsigned long  msghashlen, 
+                        unsigned char *sig,      unsigned long *siglen, 
+                        prng_state    *prng,     int            prng_idx,
+                        int            hash_idx, unsigned long  saltlen,
+                        rsa_key *key)
+{
+   unsigned long modulus_bitlen, modulus_bytelen, x;
+   int           err;
+   
+  _ARGCHK(msghash  != NULL);
+  _ARGCHK(sig      != NULL);
+  _ARGCHK(siglen   != NULL);
+  _ARGCHK(key      != NULL);
+  
+  /* valid prng and hash ? */
+  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+     return err;
+  }
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen > *siglen) {
+     return CRYPT_BUFFER_OVERFLOW;
+  }
+      
+  /* PSS pad the key */
+  x = *siglen;
+  if ((err = pkcs_1_pss_encode(msghash, msghashlen, saltlen, prng, prng_idx,
+                               hash_idx, modulus_bitlen, sig, &x)) != CRYPT_OK) {
+     return err;
+  }
+
+  /* RSA encode it */
+  return rsa_exptmod(sig, x, sig, siglen, PK_PRIVATE, prng, prng_idx, key);
+}
+
+#endif /* MRSA */

+ 0 - 274
rsa_sys.c

@@ -1,274 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-/* these are smaller routines written by Clay Culver.  They do the same function as the rsa_encrypt/decrypt 
- * except that they are used to RSA encrypt/decrypt a single value and not a packet.
- */
-int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
-                    unsigned char *outkey, unsigned long *outlen,
-                    prng_state *prng, int wprng, rsa_key *key)
-{
-   unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
-   unsigned long x, y, rsa_size;
-   int err;
-
-   _ARGCHK(inkey  != NULL);
-   _ARGCHK(outkey != NULL);
-   _ARGCHK(outlen != NULL);
-   _ARGCHK(key    != NULL);
-   
-   /* only allow keys from 64 to 256 bits */
-   if (inlen < 8 || inlen > 32) {
-      return CRYPT_INVALID_ARG;
-   }
-
-   /* are the parameters valid? */
-   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
-      return err; 
-   }
-
-   /* rsa_pad the symmetric key */
-   y = (unsigned long)sizeof(rsa_in); 
-   if ((err = rsa_pad(inkey, inlen, rsa_in, &y, wprng, prng)) != CRYPT_OK) {
-      return CRYPT_ERROR;
-   }
-   
-   /* rsa encrypt it */
-   rsa_size = (unsigned long)sizeof(rsa_out);
-   if ((err = rsa_exptmod(rsa_in, y, rsa_out, &rsa_size, PK_PUBLIC, key)) != CRYPT_OK) {
-      return CRYPT_ERROR;
-   }
-
-   /* check size */
-   if (*outlen < (PACKET_SIZE+4+rsa_size)) { 
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   /* store header */
-   packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
-
-   /* now lets make the header */
-   y = PACKET_SIZE;
-   
-   /* store the size of the RSA value */
-   STORE32L(rsa_size, (outkey+y));
-   y += 4;
-
-   /* store the rsa value */
-   for (x = 0; x < rsa_size; x++, y++) {
-       outkey[y] = rsa_out[x];
-   }
-
-   *outlen = y;
-#ifdef CLEAN_STACK
-   /* clean up */
-   zeromem(rsa_in, sizeof(rsa_in));
-   zeromem(rsa_out, sizeof(rsa_out));
-#endif
-
-   return CRYPT_OK;
-}
-
-int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
-                          unsigned char *outkey, unsigned long *keylen, 
-                          rsa_key *key)
-{
-   unsigned char sym_key[MAXBLOCKSIZE], rsa_out[RSA_STACK];
-   unsigned long x, y, z, i, rsa_size;
-   int err;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(outkey != NULL);
-   _ARGCHK(keylen != NULL);
-   _ARGCHK(key    != NULL);
-
-   /* right key type? */
-   if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-
-   if (inlen < PACKET_SIZE+4) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      inlen -= PACKET_SIZE+4;
-   }
-
-   /* check the header */
-   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* grab length of the rsa key */
-   y = PACKET_SIZE;
-   LOAD32L(rsa_size, (in+y));
-   if (inlen < rsa_size) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      inlen -= rsa_size;
-   }
-   y += 4;
-
-   /* decrypt it */
-   x = (unsigned long)sizeof(rsa_out);
-   if ((err = rsa_exptmod(in+y, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) {
-      return err;
-   }
-   y += rsa_size;
-
-   /* depad it */
-   z = (unsigned long)sizeof(sym_key);
-   if ((err = rsa_depad(rsa_out, x, sym_key, &z)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* check size */
-   if (*keylen < z) { 
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   for (i = 0; i < z; i++) {
-     outkey[i] = sym_key[i];
-   }
-   
-#ifdef CLEAN_STACK
-   /* clean up */
-   zeromem(sym_key, sizeof(sym_key));
-   zeromem(rsa_out, sizeof(rsa_out));
-#endif
-   *keylen = z;
-   return CRYPT_OK;
-}
-
-int rsa_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                        unsigned char *out, unsigned long *outlen, 
-                        rsa_key *key)
-{
-   unsigned long rsa_size, x, y;
-   unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
-   int err;
-
-   _ARGCHK(in     != NULL);
-   _ARGCHK(out    != NULL);
-   _ARGCHK(outlen != NULL);
-   _ARGCHK(key    != NULL);
-   
-   /* reject nonsense sizes */
-   if (inlen > (512/3) || inlen < 16) {
-      return CRYPT_INVALID_ARG;
-   }
-
-   /* type of key? */
-   if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-
-   /* pad it */
-   x = (unsigned long)sizeof(rsa_out);
-   if ((err = rsa_signpad(in, inlen, rsa_out, &x)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* sign it */
-   rsa_size = (unsigned long)sizeof(rsa_in);
-   if ((err = rsa_exptmod(rsa_out, x, rsa_in, &rsa_size, PK_PRIVATE, key)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* check size */
-   if (*outlen < (PACKET_SIZE+4+rsa_size)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   /* now lets output the message */
-   y = PACKET_SIZE;
-
-   /* output the len */
-   STORE32L(rsa_size, (out+y));
-   y += 4;
-
-   /* store the signature */
-   for (x = 0; x < rsa_size; x++, y++) {
-       out[y] = rsa_in[x];
-   }
-
-   /* store header */
-   packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED);
-
-#ifdef CLEAN_STACK
-   /* clean up */
-   zeromem(rsa_in, sizeof(rsa_in));
-   zeromem(rsa_out, sizeof(rsa_out));
-#endif
-   *outlen = y;
-   return CRYPT_OK;
-}
-
-int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
-                    const unsigned char *md, int *stat, rsa_key *key)
-{
-   unsigned long rsa_size, x, y, z;
-   unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
-   int err;
-
-   _ARGCHK(sig  != NULL);
-   _ARGCHK(md   != NULL);
-   _ARGCHK(stat != NULL);
-   _ARGCHK(key  != NULL);
-
-   /* always be incorrect by default */
-   *stat = 0;
-   
-   if (siglen < PACKET_SIZE+4) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      siglen -= PACKET_SIZE+4;
-   }
-
-   /* verify header */
-   if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* get the len */
-   y = PACKET_SIZE;
-   LOAD32L(rsa_size, (sig+y));
-   if (siglen < rsa_size) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      siglen -= rsa_size;
-   }
-   y += 4;
-
-   /* exptmod it */
-   x = (unsigned long)sizeof(rsa_out);
-   if ((err = rsa_exptmod(sig+y, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) {
-      return err;
-   }
-   y += rsa_size;
-
-   /* depad it */
-   z = (unsigned long)sizeof(rsa_in);
-   if ((err = rsa_signdepad(rsa_out, x, rsa_in, &z)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* check? */
-   if (memcmp(rsa_in, md, (size_t)z) == 0) {
-      *stat = 1;
-   }
-
-#ifdef CLEAN_STACK
-   zeromem(rsa_in, sizeof(rsa_in));
-   zeromem(rsa_out, sizeof(rsa_out));
-#endif
-   return CRYPT_OK;
-}
-

+ 69 - 0
rsa_verify_hash.c

@@ -0,0 +1,69 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* design then PSS depad */
+int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
+                    const unsigned char *msghash,  unsigned long msghashlen,
+                          prng_state    *prng,     int           prng_idx,
+                          int            hash_idx, unsigned long saltlen,
+                          int           *stat,     rsa_key      *key)
+{
+   unsigned long modulus_bitlen, modulus_bytelen, x;
+   int           err;
+   unsigned char *tmpbuf;
+   
+  _ARGCHK(msghash  != NULL);
+  _ARGCHK(sig      != NULL);
+  _ARGCHK(stat     != NULL);
+  _ARGCHK(key      != NULL);
+  
+  /* valid hash ? */
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+
+  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen != siglen) {
+     return CRYPT_INVALID_PACKET;
+  }
+  
+  /* allocate temp buffer for decoded sig */
+  tmpbuf = XCALLOC(1, modulus_bytelen + 1);
+  if (tmpbuf == NULL) {
+     return CRYPT_MEM;
+  }
+      
+  /* RSA decode it  */
+  x = siglen;
+  if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, prng, prng_idx, key)) != CRYPT_OK) {
+     XFREE(tmpbuf);
+     return err;
+  }
+  
+  /* PSS decode it */
+  err = pkcs_1_pss_decode(msghash, msghashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
+  XFREE(tmpbuf);
+  return err;
+}
+
+#endif /* MRSA */

+ 30 - 0
sha1.c

@@ -20,6 +20,12 @@ const struct _hash_descriptor sha1_desc =
     2,
     20,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 
+      0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 },
+    15,
+
     &sha1_init,
     &sha1_process,
     &sha1_done,
@@ -38,6 +44,9 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
 #endif
 {
     ulong32 a,b,c,d,e,W[80],i;
+#ifdef SMALL_CODE
+    ulong32 t;
+#endif
 
     /* copy the state into 512-bits into W[0..15] */
     for (i = 0; i < 16; i++) {
@@ -63,6 +72,26 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
     #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
     #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
  
+#ifdef SMALL_CODE
+ 
+    for (i = 0; i < 20; ) {
+       FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 40; ) {
+       FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 60; ) {
+       FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 80; ) {
+       FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+#else
+
     for (i = 0; i < 20; ) {
        FF0(a,b,c,d,e,i++);
        FF0(e,a,b,c,d,i++);
@@ -97,6 +126,7 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
        FF3(c,d,e,a,b,i++);
        FF3(b,c,d,e,a,i++);
     }
+#endif
 
     #undef FF0
     #undef FF1

+ 5 - 0
sha224.c

@@ -16,6 +16,11 @@ const struct _hash_descriptor sha224_desc =
     10,
     28,
     64,
+
+    /* DER identifier (not supported) */
+    { 0x00 },
+    0,
+
     &sha224_init,
     &sha256_process,
     &sha224_done,

+ 20 - 13
sha256.c

@@ -22,12 +22,20 @@ const struct _hash_descriptor sha256_desc =
     0,
     32,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 
+      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 
+      0x00, 0x04, 0x20 },
+    19,
+    
     &sha256_init,
     &sha256_process,
     &sha256_done,
     &sha256_test
 };
 
+#ifdef SMALL_CODE
 /* the K array */
 static const unsigned long K[64] = {
     0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
@@ -44,6 +52,7 @@ static const unsigned long K[64] = {
     0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
     0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
 };
+#endif
 
 /* Various logical functions */
 #define Ch(x,y,z)       (z ^ (x & (y ^ z)))
@@ -63,6 +72,9 @@ static void sha256_compress(hash_state * md, unsigned char *buf)
 #endif
 {
     ulong32 S[8], W[64], t0, t1;
+#ifdef SMALL_CODE
+    ulong32 t;
+#endif
     int i;
 
     /* copy state into S */
@@ -82,22 +94,17 @@ static void sha256_compress(hash_state * md, unsigned char *buf)
 
     /* Compress */
 #ifdef SMALL_CODE   
-#define RND(a,b,c,d,e,f,g,h,i)                    \
+#define RND(a,b,c,d,e,f,g,h,i)                         \
      t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
-     t1 = Sigma0(a) + Maj(a, b, c);                  \
-     d += t0;                                        \
+     t1 = Sigma0(a) + Maj(a, b, c);                    \
+     d += t0;                                          \
      h  = t0 + t1;
 
-     for (i = 0; i < 64; i += 8) {
-         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
-         RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
-         RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
-         RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
-         RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
-         RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
-         RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
-         RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
-     }  
+     for (i = 0; i < 64; ++i) {
+         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
+         t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; 
+         S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
+	  }  
 #else 
 #define RND(a,b,c,d,e,f,g,h,i,ki)                    \
      t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \

+ 7 - 0
sha384.c

@@ -17,6 +17,13 @@ const struct _hash_descriptor sha384_desc =
     4,
     48,
     128,
+
+    /* DER identifier */
+    { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 
+      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 
+      0x00, 0x04, 0x30 },
+    19,
+
     &sha384_init,
     &sha512_process,
     &sha384_done,

+ 7 - 0
sha512.c

@@ -21,6 +21,13 @@ const struct _hash_descriptor sha512_desc =
     5,
     64,
     128,
+
+    /* DER identifier */
+    { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 
+      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 
+      0x00, 0x04, 0x40 },
+    19,
+
     &sha512_init,
     &sha512_process,
     &sha512_done,

+ 7 - 0
tiger.c

@@ -19,6 +19,13 @@ const struct _hash_descriptor tiger_desc =
     1,
     24,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 
+      0x01, 0x04, 0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 
+      0x00, 0x04, 0x18 },
+    19,
+
     &tiger_init,
     &tiger_process,
     &tiger_done,

+ 77 - 0
tim_exptmod.c

@@ -0,0 +1,77 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+/* RSA Code by Tom St Denis */
+#include "mycrypt.h"
+
+#ifdef RSA_TIMING
+
+/* decrypts c into m */
+int tim_exptmod(prng_state *prng, int prng_idx, 
+                mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m)
+{
+   int           err;
+   mp_int        r, tmp, tmp2;
+   unsigned char *rtmp;
+   unsigned long rlen;
+
+   _ARGCHK(c != NULL);
+   _ARGCHK(e != NULL);
+   _ARGCHK(d != NULL);
+   _ARGCHK(n != NULL);
+   _ARGCHK(m != NULL);
+
+   if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* pick random r */ 
+   rtmp = XMALLOC(MAX_RSA_SIZE/8);
+   if (rtmp == NULL) {
+      return CRYPT_MEM;
+   }
+
+
+   rlen = mp_unsigned_bin_size(n);
+   if (prng_descriptor[prng_idx].read(rtmp, rlen, prng) != rlen) {
+      XFREE(rtmp);
+      return CRYPT_ERROR_READPRNG;
+   }
+
+   if ((err = mp_init_multi(&r, &tmp, &tmp2, NULL)) != MP_OKAY) {
+      XFREE(rtmp);
+      return mpi_to_ltc_error(err);
+   }
+
+   /* read in r */
+   if ((err = mp_read_unsigned_bin(&r, rtmp, rlen)) != MP_OKAY)              { goto __ERR; }
+
+   /* compute tmp = r^e */
+   if ((err = mp_exptmod(&r, e, n, &tmp)) != MP_OKAY)                        { goto __ERR; }
+
+   /* multiply C into the mix */
+   if ((err = mp_mulmod(c, &tmp, n, &tmp)) != MP_OKAY)                       { goto __ERR; }
+
+   /* raise to d */
+   if ((err = mp_exptmod(&tmp, d, n, &tmp)) != MP_OKAY)                      { goto __ERR; }
+   
+   /* invert r and multiply */
+   if ((err = mp_invmod(&r, n, &tmp2)) != MP_OKAY)                           { goto __ERR; }
+
+   /* multiply and we are totally set */
+   if ((err = mp_mulmod(&tmp, &tmp2, n, m)) != MP_OKAY)                      { goto __ERR; }
+
+__ERR:  mp_clear_multi(&r, &tmp, &tmp2, NULL);
+   XFREE(rtmp);
+   return mpi_to_ltc_error(err);
+}
+
+#endif 

+ 6 - 1
whirl.c

@@ -21,6 +21,11 @@ const struct _hash_descriptor whirlpool_desc =
     11,
     64,
     64,
+
+    /* DER encoding (not yet supported) */
+    { 0x00 },
+    0,
+
     &whirlpool_init,
     &whirlpool_process,
     &whirlpool_done,
@@ -34,7 +39,7 @@ const struct _hash_descriptor whirlpool_desc =
 #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
 
 /* shortcut macro to perform three functions at once */
-#define theta_pi_gamma(a, i)               \
+#define theta_pi_gamma(a, i)             \
     SB0(GB(a, i-0, 7)) ^                 \
     SB1(GB(a, i-1, 6)) ^                 \
     SB2(GB(a, i-2, 5)) ^                 \

+ 20 - 3
yarrow.c

@@ -30,7 +30,15 @@ int yarrow_start(prng_state *prng)
 
    /* these are the default hash/cipher combo used */
 #ifdef RIJNDAEL
+#if    YARROW_AES==0
+   prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
+#elif  YARROW_AES==1
+   prng->yarrow.cipher = register_cipher(&aes_enc_desc);
+#elif  YARROW_AES==2
    prng->yarrow.cipher = register_cipher(&rijndael_desc);
+#elif  YARROW_AES==3
+   prng->yarrow.cipher = register_cipher(&aes_desc);
+#endif
 #elif defined(BLOWFISH)
    prng->yarrow.cipher = register_cipher(&blowfish_desc);
 #elif defined(TWOFISH)
@@ -78,6 +86,8 @@ int yarrow_start(prng_state *prng)
    prng->yarrow.hash   = register_hash(&md4_desc);
 #elif defined(MD2)
    prng->yarrow.hash   = register_hash(&md2_desc);
+#elif defined(WHIRLPOOL)
+   prng->yarrow.hash   = register_hash(&whirlpool_desc);
 #else
    #error YARROW needs at least one HASH
 #endif
@@ -107,13 +117,20 @@ int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *
    hash_descriptor[prng->yarrow.hash].init(&md);
 
    /* hash the current pool */
-   hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize);
+   if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, 
+                                                        hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
+      return err;
+   }
 
    /* add the new entropy */
-   hash_descriptor[prng->yarrow.hash].process(&md, buf, len);
+   if ((err = hash_descriptor[prng->yarrow.hash].process(&md, buf, len)) != CRYPT_OK) {
+      return err;
+   }
 
    /* store result */
-   hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool);
+   if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
+      return err;
+   }
 
    return CRYPT_OK;
 }

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików