Working CFB1 and test vectors.
authorBen Laurie <ben@openssl.org>
Tue, 29 Jul 2003 10:56:56 +0000 (10:56 +0000)
committerBen Laurie <ben@openssl.org>
Tue, 29 Jul 2003 10:56:56 +0000 (10:56 +0000)
crypto/aes/aes_cfb.c
crypto/evp/c_allc.c
crypto/evp/evp_test.c
crypto/evp/evptests.txt

index dd99bc9acf42accdd8f9f24f4b2ed9588ed531a5..bd61aa8229a6c369724c13527c33144b6e24c757 100644 (file)
@@ -168,13 +168,15 @@ void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
     assert(in && out && key && ivec);
     if(enc)
        {
-       /* construct the new IV in the second half of ovec */
-       AES_encrypt(ivec,ovec+AES_BLOCK_SIZE,key);
+       /* construct the new IV */
+       AES_encrypt(ivec,ovec,key);
        /* encrypt the input */
        for(n=0 ; n < (nbits+7)/8 ; ++n)
-           out[n]=in[n]^ovec[n+AES_BLOCK_SIZE];
+           out[n]=in[n]^ovec[n];
        /* fill in the first half of the new IV with the current IV */
        memcpy(ovec,ivec,AES_BLOCK_SIZE);
+       /* and put the ciphertext in the second half */
+       memcpy(ovec+AES_BLOCK_SIZE,out,(nbits+7)/8);
        /* shift ovec left most of the bits... */
        memmove(ovec,ovec+nbits/8,AES_BLOCK_SIZE+(nbits%8 ? 1 : 0));
        /* now the remaining bits */
@@ -213,7 +215,7 @@ void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
     /* it is not necessary to cleanse ovec, since the IV is not secret */
     }
 
-/* N.B. This expects the input to be packed, LS bit first */
+/* N.B. This expects the input to be packed, MS bit first */
 void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
                      const unsigned long length, const AES_KEY *key,
                      unsigned char *ivec, int *num, const int enc)
@@ -223,11 +225,12 @@ void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
     assert(in && out && key && ivec && num);
     assert(*num == 0);
 
+    memset(out,0,(length+7)/8);
     for(n=0 ; n < length ; ++n)
        {
-       c[0]=!!(in[n/8]&(1 << (n%8)));
+       c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0;
        AES_cfbr_encrypt_block(c,d,1,key,ivec,enc);
-       out[n/8]=(out[n/8]&~(1 << (n%8)))|((d[0]&1) << (n%8));
+       out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8));
        }
     }
 
index 341a958fd4728b0816dbf0d826b473bef5aae751..3e22b7b424628160ba343983d0f1410d9f42e140 100644 (file)
@@ -150,6 +150,7 @@ void OpenSSL_add_all_ciphers(void)
        EVP_add_cipher(EVP_aes_128_ecb());
        EVP_add_cipher(EVP_aes_128_cbc());
        EVP_add_cipher(EVP_aes_128_cfb());
+       EVP_add_cipher(EVP_aes_128_cfb1());
        EVP_add_cipher(EVP_aes_128_ofb());
 #if 0
        EVP_add_cipher(EVP_aes_128_ctr());
index 28460173f7ef0a2220ddb31f150948b7e25b4ba2..7d256e695b89574a5401f7f442be523161aec878 100644 (file)
@@ -136,7 +136,7 @@ static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
                  const unsigned char *iv,int in,
                  const unsigned char *plaintext,int pn,
                  const unsigned char *ciphertext,int cn,
-                 int encdec)
+                 int encdec,int multiplier)
     {
     EVP_CIPHER_CTX ctx;
     unsigned char out[4096];
@@ -166,7 +166,7 @@ static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
            }
        EVP_CIPHER_CTX_set_padding(&ctx,0);
 
-       if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn))
+       if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn*multiplier))
            {
            fprintf(stderr,"Encrypt failed\n");
            test1_exit(6);
@@ -177,7 +177,7 @@ static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
            test1_exit(7);
            }
 
-       if(outl+outl2 != cn)
+       if(outl+outl2 != cn*multiplier)
            {
            fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n",
                    outl+outl2,cn);
@@ -202,7 +202,7 @@ static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
            }
        EVP_CIPHER_CTX_set_padding(&ctx,0);
 
-       if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn))
+       if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn*multiplier))
            {
            fprintf(stderr,"Decrypt failed\n");
            test1_exit(6);
@@ -213,7 +213,7 @@ static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn,
            test1_exit(7);
            }
 
-       if(outl+outl2 != cn)
+       if(outl+outl2 != cn*multiplier)
            {
            fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
                    outl+outl2,cn);
@@ -238,7 +238,7 @@ static int test_cipher(const char *cipher,const unsigned char *key,int kn,
                       const unsigned char *iv,int in,
                       const unsigned char *plaintext,int pn,
                       const unsigned char *ciphertext,int cn,
-                      int encdec)
+                      int encdec,int multiplier)
     {
     const EVP_CIPHER *c;
 
@@ -246,7 +246,7 @@ static int test_cipher(const char *cipher,const unsigned char *key,int kn,
     if(!c)
        return 0;
 
-    test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec);
+    test1(c,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec,multiplier);
 
     return 1;
     }
@@ -359,6 +359,7 @@ int main(int argc,char **argv)
        unsigned char *iv,*key,*plaintext,*ciphertext;
        int encdec;
        int kn,in,pn,cn;
+       int multiplier=1;
 
        if(!fgets((char *)line,sizeof line,f))
            break;
@@ -383,7 +384,15 @@ int main(int argc,char **argv)
        pn=convert(plaintext);
        cn=convert(ciphertext);
 
-       if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
+       if(strchr(cipher,'*'))
+           {
+           p=cipher;
+           sstrsep(&p,"*");
+           multiplier=atoi(sstrsep(&p,"*"));
+           }
+
+       if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec,
+                       multiplier)
           && !test_digest(cipher,plaintext,pn,ciphertext,cn))
            {
            fprintf(stderr,"Can't find %s\n",cipher);
index 80bd9c7765cba7c8117714cd48348af6b2bce048..169c6ec1ebf4db26a9e4779de062125c4687d114 100644 (file)
@@ -92,7 +92,54 @@ AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000
 AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
 AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
 AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
-# We don't support CFB{1,8}-AESxxx.{En,De}crypt
+
+# CFB1-AES128.Encrypt
+
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:000102030405060708090a0b0c0d0e0f:00:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:00020406080a0c0e10121416181a1c1e:80:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0004080c1014181c2024282c3034383d:80:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0008101820283038404850586068707b:00:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:00102030405060708090a0b0c0d0e0f6:80:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0020406080a0c0e10121416181a1c1ed:00:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:004080c1014181c2024282c3034383da:80:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:008101820283038404850586068707b4:80:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0102030405060708090a0b0c0d0e0f68:80:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:020406080a0c0e10121416181a1c1ed1:80:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:04080c1014181c2024282c3034383da2:00:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:08101820283038404850586068707b45:00:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:102030405060708090a0b0c0d0e0f68b:00:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:20406080a0c0e10121416181a1c1ed16:00:00:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:4080c1014181c2024282c3034383da2c:00:80:1
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:8101820283038404850586068707b459:80:80:1
+# all of the above packed into one...
+# in: 0110 1011 1100 0001 = 6bc1
+# out: 0110 1000 1011 0011 = 68b3
+AES-128-CFB1*8:2b7e151628aed2a6abf7158809cf4f3c:000102030405060708090a0b0c0d0e0f:6bc1:68b3:1
+
+# CFB1-AES128.Decrypt
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:000102030405060708090a0b0c0d0e0f:00:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:00020406080a0c0e10121416181a1c1e:80:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0004080c1014181c2024282c3034383d:80:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0008101820283038404850586068707b:00:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:00102030405060708090a0b0c0d0e0f6:80:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0020406080a0c0e10121416181a1c1ed:00:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:004080c1014181c2024282c3034383da:80:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:008101820283038404850586068707b4:80:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:0102030405060708090a0b0c0d0e0f68:80:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:020406080a0c0e10121416181a1c1ed1:80:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:04080c1014181c2024282c3034383da2:00:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:08101820283038404850586068707b45:00:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:102030405060708090a0b0c0d0e0f68b:00:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:20406080a0c0e10121416181a1c1ed16:00:00:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:4080c1014181c2024282c3034383da2c:00:80:0
+AES-128-CFB1:2b7e151628aed2a6abf7158809cf4f3c:8101820283038404850586068707b459:80:80:0
+# all of the above packed into one...
+# in: 0110 1000 1011 0011 = 68b3
+# out: 0110 1011 1100 0001 = 6bc1
+AES-128-CFB1*8:2b7e151628aed2a6abf7158809cf4f3c:000102030405060708090a0b0c0d0e0f:6bc1:68b3:0
+
+# TODO: CFB1-AES192 and 256
+
 # For all CFB128 encrypts and decrypts, the transformed sequence is
 #   AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
 # CFB128-AES128.Encrypt