Make the CBC mode od AES accept lengths that aren't multiples of 16.
authorRichard Levitte <levitte@openssl.org>
Tue, 12 Nov 2002 11:00:25 +0000 (11:00 +0000)
committerRichard Levitte <levitte@openssl.org>
Tue, 12 Nov 2002 11:00:25 +0000 (11:00 +0000)
PR: 330

crypto/aes/aes_cbc.c

index 3dfd7aba2a1900d454ebfbd39d78bd9b7f6a9897..bf1a808cf0e1ea168cba4403ae7819e92ee5c77a 100644 (file)
@@ -62,11 +62,10 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
        unsigned char tmp[16];
 
        assert(in && out && key && ivec);
        unsigned char tmp[16];
 
        assert(in && out && key && ivec);
-       assert(length % AES_BLOCK_SIZE == 0);
        assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
 
        assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
 
-       if (AES_ENCRYPT == enc)
-               while (len > 0) {
+       if (AES_ENCRYPT == enc) {
+               while (len >= AES_BLOCK_SIZE) {
                        for(n=0; n < 16; ++n)
                                tmp[n] = in[n] ^ ivec[n];
                        AES_encrypt(tmp, out, key);
                        for(n=0; n < 16; ++n)
                                tmp[n] = in[n] ^ ivec[n];
                        AES_encrypt(tmp, out, key);
@@ -75,8 +74,17 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        in += 16;
                        out += 16;
                }
                        in += 16;
                        out += 16;
                }
-       else
-               while (len > 0) {
+               if (len) {
+                       for(n=0; n < len; ++n)
+                               tmp[n] = in[n] ^ ivec[n];
+                       for(n=len; n < AES_BLOCK_SIZE; ++n)
+                               tmp[n] = ivec[n];
+                       AES_encrypt(tmp, tmp, key);
+                       memcpy(out, tmp, len);
+                       memcpy(ivec, tmp, 16);
+               }                       
+       } else {
+               while (len >= AES_BLOCK_SIZE) {
                        memcpy(tmp, in, 16);
                        AES_decrypt(in, out, key);
                        for(n=0; n < 16; ++n)
                        memcpy(tmp, in, 16);
                        AES_decrypt(in, out, key);
                        for(n=0; n < 16; ++n)
@@ -86,4 +94,12 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
                        in += 16;
                        out += 16;
                }
                        in += 16;
                        out += 16;
                }
+               if (len) {
+                       memcpy(tmp, in, 16);
+                       AES_decrypt(tmp, tmp, key);
+                       for(n=0; n < len; ++n)
+                               out[n] ^= ivec[n];
+                       memcpy(ivec, tmp, 16);
+               }                       
+       }
 }
 }