浏览代码

add required private API

Steffen Jaeckel 6 年之前
父节点
当前提交
5e30d3512f
共有 2 个文件被更改,包括 109 次插入52 次删除
  1. 98 52
      src/ciphers/blowfish.c
  2. 11 0
      src/headers/tomcrypt_private.h

+ 98 - 52
src/ciphers/blowfish.c

@@ -303,9 +303,9 @@ static const ulong32 ORIG_S[4][256] = {
 
 static void s_blowfish_encipher(ulong32 *L, ulong32 *R, const symmetric_key *skey)
 {
-   int r;
+   int rounds;
 
-   ulong32 _L, _R;
+   ulong32 l, r;
 #ifndef __GNUC__
    const ulong32 *S1, *S2, *S3, *S4;
 
@@ -315,23 +315,34 @@ static void s_blowfish_encipher(ulong32 *L, ulong32 *R, const symmetric_key *ske
    S4 = skey->blowfish.S[3];
 #endif
 
-   _L = *L;
-   _R = *R;
+   l = *L;
+   r = *R;
 
    /* do 16 rounds */
-   for (r = 0; r < 16; ) {
-      _L ^= skey->blowfish.K[r++];  _R ^= F(_L);
-      _R ^= skey->blowfish.K[r++];  _L ^= F(_R);
-      _L ^= skey->blowfish.K[r++];  _R ^= F(_L);
-      _R ^= skey->blowfish.K[r++];  _L ^= F(_R);
+   for (rounds = 0; rounds < 16; ) {
+      l ^= skey->blowfish.K[rounds++];  r ^= F(l);
+      r ^= skey->blowfish.K[rounds++];  l ^= F(r);
+      l ^= skey->blowfish.K[rounds++];  r ^= F(l);
+      r ^= skey->blowfish.K[rounds++];  l ^= F(r);
    }
 
    /* last keying */
-   _R ^= skey->blowfish.K[17];
-   _L ^= skey->blowfish.K[16];
+   l ^= skey->blowfish.K[16];
+   r ^= skey->blowfish.K[17];
+
+   *L = r;
+   *R = l;
+}
 
-   *L = _L;
-   *R = _R;
+void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey)
+{
+   unsigned long i;
+   ulong32 *d = data;
+
+   for (i = 0; i < blocks; ++i) {
+      s_blowfish_encipher(d, d + 1, skey);
+      d += 2;
+   }
 }
 
 static ulong32 s_blowfish_stream2word(const unsigned char *d, int dlen, int *cur)
@@ -352,70 +363,60 @@ static ulong32 s_blowfish_stream2word(const unsigned char *d, int dlen, int *cur
 }
 
  /**
-    Initialize the Blowfish block cipher
+    Expand the Blowfish internal state
     @param key The symmetric key you wish to pass
     @param keylen The key length in bytes
+    @param data The additional data you wish to pass (can be NULL)
+    @param datalen The additional data length in bytes
     @param num_rounds The number of rounds desired (0 for default)
     @param skey The key in as scheduled by this function.
     @return CRYPT_OK if successful
  */
-int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
-                   symmetric_key *skey)
+int blowfish_expand(const unsigned char *key, int keylen,
+                    const unsigned char *data, int datalen,
+                    symmetric_key *skey)
 {
-   ulong32 x, z, A, B[2];
-   int y;
+   ulong32 x, y, A, B[2];
+   int i;
 
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(skey != NULL);
 
-   /* check key length */
-   if (keylen < 8 || keylen > 56) {
-      return CRYPT_INVALID_KEYSIZE;
-   }
-
-   /* check rounds */
-   if (num_rounds != 0 && num_rounds != 16) {
-      return CRYPT_INVALID_ROUNDS;
-   }
-
    /* load in key bytes (Supplied by David Hopwood) */
-   y = 0;
-   for (x = y = 0; x < 18; x++) {
-       A = s_blowfish_stream2word(key, keylen, &y);
-       skey->blowfish.K[x] = ORIG_P[x] ^ A;
-   }
-
-   /* copy sboxes */
-   for (x = 0; x < 4; x++) {
-       for (y = 0; y < 256; y++) {
-           skey->blowfish.S[x][y] = ORIG_S[x][y];
-       }
+   i = 0;
+   for (x = 0; x < 18; x++) {
+       A = s_blowfish_stream2word(key, keylen, &i);
+       skey->blowfish.K[x] ^= A;
    }
 
-   /* encrypt K array */
-   for (x = 0; x < 2; x++) {
-       B[x] = 0;
-   }
 
+   i = 0;
+   B[0] = 0;
+   B[1] = 0;
    for (x = 0; x < 18; x += 2) {
-
+      if (data != NULL) {
+         B[0] ^= s_blowfish_stream2word(data, datalen, &i);
+         B[1] ^= s_blowfish_stream2word(data, datalen, &i);
+      }
       /* encrypt it */
       s_blowfish_encipher(&B[0], &B[1], skey);
       /* copy it */
-      skey->blowfish.K[x] = B[1];
-      skey->blowfish.K[x+1] = B[1] = B[0];
-      B[0] = skey->blowfish.K[x];
+      skey->blowfish.K[x] = B[0];
+      skey->blowfish.K[x+1] = B[1];
    }
 
    /* encrypt S array */
    for (x = 0; x < 4; x++) {
        for (y = 0; y < 256; y += 2) {
+          if (data != NULL) {
+             B[0] ^= s_blowfish_stream2word(data, datalen, &i);
+             B[1] ^= s_blowfish_stream2word(data, datalen, &i);
+          }
           /* encrypt it */
           s_blowfish_encipher(&B[0], &B[1], skey);
           /* copy it */
-          skey->blowfish.S[x][y] = B[1];
-          skey->blowfish.S[x][y+1] = B[1] = B[0];
-          B[0] = skey->blowfish.S[x][y];
+          skey->blowfish.S[x][y] = B[0];
+          skey->blowfish.S[x][y+1] = B[1];
        }
    }
 
@@ -426,6 +427,49 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
    return CRYPT_OK;
 }
 
+/**
+   Initialize the Blowfish block cipher
+   @param key The symmetric key you wish to pass
+   @param keylen The key length in bytes
+   @param num_rounds The number of rounds desired (0 for default)
+   @param skey The key in as scheduled by this function.
+   @return CRYPT_OK if successful
+*/
+int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
+                  symmetric_key *skey)
+{
+   /* check key length */
+   if (keylen < 8 || keylen > 56) {
+      return CRYPT_INVALID_KEYSIZE;
+   }
+   /* check rounds */
+   if (num_rounds != 0 && num_rounds != 16) {
+      return CRYPT_INVALID_ROUNDS;
+   }
+
+   return blowfish_setup_with_data(key, keylen, NULL, 0, skey);
+}
+
+/**
+   Alternative initialize of the Blowfish block cipher
+   @param key The symmetric key you wish to pass
+   @param keylen The key length in bytes
+   @param data The additional data you wish to pass (can be NULL)
+   @param datalen The additional data length in bytes
+   @param num_rounds The number of rounds desired (0 for default)
+   @param skey The key in as scheduled by this function.
+   @return CRYPT_OK if successful
+*/
+
+int blowfish_setup_with_data(const unsigned char *key, int keylen,
+                             const unsigned char *data, int datalen,
+                             symmetric_key *skey)
+{
+   XMEMCPY(skey->blowfish.K, ORIG_P, sizeof(ORIG_P));
+   XMEMCPY(skey->blowfish.S, ORIG_S, sizeof(ORIG_S));
+   return blowfish_expand(key, keylen, data, datalen, skey);
+}
+
 /**
   Encrypts a block of text with Blowfish
   @param pt The input plaintext (8 bytes)
@@ -452,8 +496,8 @@ int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symme
    s_blowfish_encipher(&L, &R, skey);
 
    /* store */
-   STORE32H(R, &ct[0]);
-   STORE32H(L, &ct[4]);
+   STORE32H(L, &ct[0]);
+   STORE32H(R, &ct[4]);
 
    return CRYPT_OK;
 }
@@ -584,6 +628,8 @@ int blowfish_test(void)
       for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key);
       for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
    }
+
+
    return CRYPT_OK;
  #endif
 }

+ 11 - 0
src/headers/tomcrypt_private.h

@@ -72,6 +72,17 @@ typedef struct
  * Internal functions
  */
 
+
+/* tomcrypt_cipher.h */
+
+void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
+int blowfish_expand(const unsigned char *key, int keylen,
+                    const unsigned char *data, int datalen,
+                    symmetric_key *skey);
+int blowfish_setup_with_data(const unsigned char *key, int keylen,
+                             const unsigned char *data, int datalen,
+                             symmetric_key *skey);
+
 /* tomcrypt_hash.h */
 
 /* a simple macro for making hash "process" functions */