From e2875d7da33dbe6054e899f1b0a1c1aa4d4f4939 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Wed, 16 Dec 1998 02:11:41 +0100
Subject: [PATCH] Removed GPG specifics.

Rev: src/symmetric/blowfish.c:1.2
Rev: src/symmetric/include/blowfish.h:1.4
---
 blowfish.c         | 110 +++++++++++++++++++++++++++++----------------
 include/blowfish.h |  34 +++++++++++++-
 2 files changed, 104 insertions(+), 40 deletions(-)

diff --git a/blowfish.c b/blowfish.c
index ed4d3967..14eb683e 100644
--- a/blowfish.c
+++ b/blowfish.c
@@ -28,6 +28,10 @@
  * * const-ified it.
  */
 
+/*
+ * Hacked further by Niels Möller.
+ */
+
 /* Test values:
  * key	  "abcdefghijklmnopqrstuvwxyz";
  * plain  "BLOWFISH"
@@ -35,28 +39,25 @@
  *
  */
 
-#include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#include "util.h"
-#include "types.h"
 #include "blowfish.h"
 
+#if 0
 #define CIPHER_ALGO_BLOWFISH	 4  /* blowfish 128 bit key */
 #define CIPHER_ALGO_BLOWFISH160 42  /* blowfish 160 bit key (not in OpenPGP)*/
 
 #define FNCCAST_SETKEY(f)  (int(*)(void*, const byte*, unsigned))(f)
 #define FNCCAST_CRYPT(f)   (void(*)(void*, byte*, const byte*))(f)
 
-#define BLOWFISH_BLOCKSIZE 8
-
 static int  bf_setkey( BLOWFISH_context *c, const byte *key, unsigned keylen );
 static void encrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf );
 static void decrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf );
 
 static void selftest(void);
+#endif
 
 /* precomputed S boxes */
 static const u32 ks0[256] = {
@@ -250,30 +251,49 @@ static const u32 ps[BLOWFISH_ROUNDS+2] = {
 static inline u32
 function_F( BLOWFISH_context *bc, u32 x )
 {
-    u16 a, b, c, d;
+    unsigned a, b, c, d;
 
-  #ifdef BIG_ENDIAN_HOST
+/* FIXME: I don't quite like this hack. It assumes that the byteorder
+ * is plain big or little endian (and for instance not VAX-ish), and
+ * that u32 are exactly 32 bits large (while the autoconf stuff only
+ * guarantees that it is *at least* 32 bits).
+ *
+ * On the other hand, taking the address of x makes it difficult to
+ * place it in a register, which make me wonder if it will really make
+ * the code run any faster. */
+#if BIG_ENDIAN_HOST
+#warning BIG_ENDIAN hack used
     a = ((byte*)&x)[0];
     b = ((byte*)&x)[1];
     c = ((byte*)&x)[2];
     d = ((byte*)&x)[3];
-  #else
+#elif LITTLE_ENDIAN_HOST
+#warning LITTLE_ENDIAN hack used
     a = ((byte*)&x)[3];
     b = ((byte*)&x)[2];
     c = ((byte*)&x)[1];
     d = ((byte*)&x)[0];
-  #endif
-
-    return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
+#else
+    a = x >> 24;
+    b = (x >> 16) & 0xff;
+    c = (x >> 8) & 0xff;
+    d = x & 0xff;
+#endif
+    return (((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d]) & 0xffffffff;
 }
 #endif
 
-#ifdef BIG_ENDIAN_HOST
+#if BIG_ENDIAN_HOST
+  #warning BIG_ENDIAN hack used
   #define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]])	 \
 		   ^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
-#else
+#elif LITTLE_ENDIAN_HOST
+  #warning LITTLE_ENDIAN hack used
   #define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]])	 \
 		   ^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
+#else
+  #define F(x) (((( s0[x>>24] + s1[(x>>16) & 0xff]) \
+		  ^ s2[(x>>8) & 0xff]) + s3[x & 0xff]) & 0xffffffff)
 #endif
 #define R(l,r,i)  do { l ^= p[i]; r ^= F(l); } while(0)
 
@@ -411,8 +431,8 @@ decrypt(  BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
 #undef F
 #undef R
 
-static void
-encrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
+void
+bf_encrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
 {
     u32 d1, d2;
 
@@ -430,8 +450,8 @@ encrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
 }
 
 
-static void
-decrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
+void
+bf_decrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
 {
     u32 d1, d2;
 
@@ -449,8 +469,9 @@ decrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
 }
 
 
-static void
-selftest(void)
+/* Returns 1 on success, 0 on failure */
+int
+bf_selftest(void)
 {
     BLOWFISH_context c;
     byte plain[] = "BLOWFISH";
@@ -459,37 +480,45 @@ selftest(void)
     byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
     byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
 
-    bf_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
-    encrypt_block( &c, buffer, plain );
+    bf_set_key( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
+    bf_encrypt_block( &c, buffer, plain );
     if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
-	log_error("wrong blowfish encryption\n");
-    decrypt_block( &c, buffer, buffer );
+      /* log_error("wrong blowfish encryption\n"); */
+      return 0;
+    bf_decrypt_block( &c, buffer, buffer );
     if( memcmp( buffer, plain, 8 ) )
-	log_bug("blowfish failed\n");
+      /* log_bug("blowfish failed\n"); */
+      return 0;
 
-    bf_setkey( &c, key3, 8 );
-    encrypt_block( &c, buffer, plain3 );
+    bf_set_key( &c, key3, 8 );
+    bf_encrypt_block( &c, buffer, plain3 );
     if( memcmp( buffer, cipher3, 8 ) )
-	log_error("wrong blowfish encryption (3)\n");
-    decrypt_block( &c, buffer, buffer );
+      /* log_error("wrong blowfish encryption (3)\n"); */
+      return 0;
+    bf_decrypt_block( &c, buffer, buffer );
     if( memcmp( buffer, plain3, 8 ) )
-	log_bug("blowfish failed (3)\n");
+      /* log_bug("blowfish failed (3)\n"); */
+      return 0;
+    return 1;
 }
 
 
 
-static int
-bf_setkey( BLOWFISH_context *c, const byte *key, unsigned keylen )
+int
+bf_set_key( BLOWFISH_context *c, const byte *key, unsigned keylen )
 {
     int i, j;
     u32 data, datal, datar;
-    static int initialized;
+
+#if 0
+    static int initialized = 0;
 
     if( !initialized ) {
 	initialized = 1;
-	selftest();
+	assert(selftest());
     }
-
+#endif
+    
     for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
 	c->p[i] = ps[i];
     for(i=0; i < 256; i++ ) {
@@ -500,16 +529,21 @@ bf_setkey( BLOWFISH_context *c, const byte *key, unsigned keylen )
     }
 
     for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) {
-      #ifdef BIG_ENDIAN_HOST
+      #if BIG_ENDIAN_HOST
+        #werror BIG_ENDIAN hack used
 	((byte*)&data)[0] = key[j];
 	((byte*)&data)[1] = key[(j+1)%keylen];
 	((byte*)&data)[2] = key[(j+2)%keylen];
 	((byte*)&data)[3] = key[(j+3)%keylen];
-      #else
+      #elif LITTLE_ENDIAN_HOST
+	#werror LITTLE_ENDIAN hack used
 	((byte*)&data)[3] = key[j];
 	((byte*)&data)[2] = key[(j+1)%keylen];
 	((byte*)&data)[1] = key[(j+2)%keylen];
 	((byte*)&data)[0] = key[(j+3)%keylen];
+      #else
+	data = key[j] << 24 | key[(j+1) % keylen] <<16
+	  | key[(j+2)%keylen] << 8 | key[(j+3)%keylen];
       #endif
 	c->p[i] ^= data;
 	j = (j+4) % keylen;
@@ -556,7 +590,7 @@ bf_setkey( BLOWFISH_context *c, const byte *key, unsigned keylen )
     return 0;
 }
 
-
+#if 0
 /****************
  * Return some information about the algorithm.  We need algo here to
  * distinguish different flavors of the algorithm.
@@ -584,4 +618,4 @@ blowfish_get_info( int algo, size_t *keylen,
 	return "BLOWFISH160";
     return NULL;
 }
-
+#endif
diff --git a/include/blowfish.h b/include/blowfish.h
index dce69523..5b53a9ba 100644
--- a/include/blowfish.h
+++ b/include/blowfish.h
@@ -25,12 +25,32 @@
 #ifndef G10_BLOWFISH_H
 #define G10_BLOWFISH_H
 
-#include "types.h"
+#include "crypto_types.h"
 
+/* Use lsh types */
+typedef UINT8 byte;
+typedef UINT16 u16;
+typedef UINT32 u32;
+
+/* FIXME: A search&replace on the type names would be better, but I
+ * keep GPG names for now to make it easier to get smaller diffs. */
+
+#if 0
 #define CIPHER_ALGO_BLOWFISH     4  /* blowfish 128 bit key */
+#endif
 
+#define BLOWFISH_BLOCKSIZE 8
 #define BLOWFISH_ROUNDS 16
 
+/* Other key lengths are possible, but 128 bits is the default. */
+#define BLOWFISH_KEYSIZE 16
+
+/* Allow keys of size 64 <= bits <= 448 */
+#define BLOWFISH_MIN_KEYSIZE 8
+#define BLOWFISH_MAX_KEYSIZE 56
+
+#define G10ERR_WEAK_KEY 43
+
 typedef struct {
     u32 s0[256];
     u32 s1[256];
@@ -40,6 +60,15 @@ typedef struct {
 } BLOWFISH_context;
 
 
+/* Returns 0 if the key is ok */
+
+int  bf_set_key( BLOWFISH_context *c, const byte *key, unsigned keylen );
+void bf_encrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf );
+void bf_decrypt_block( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf );
+
+int bf_selftest(void);
+
+#if 0
 const char *
 blowfish_get_info( int algo, size_t *keylen,
 		   size_t *blocksize, size_t *contextsize,
@@ -47,5 +76,6 @@ blowfish_get_info( int algo, size_t *keylen,
 		   void (**encrypt)( void *c, byte *outbuf, const byte *inbuf ),
 		   void (**decrypt)( void *c, byte *outbuf, const byte *inbuf )
 		 );
-
+#endif
+		 
 #endif /*G10_BLOWFISH_H*/
-- 
GitLab