> "If encryption buffer size is not a multiple of the block size (in AES
that's always 16 bytes)..."
Have you tried other modes? For the stream cipher modes, CFB and OFB,
this statement is not true. It should only encrypt the number of
characters (or bits) of plain text presented.
Regards
-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of via RT
Sent: Tuesday, August 08, 2006 6:35 AM
To: [email protected]
Subject: [openssl.org #1371] Memory corruption ("buffer overrun") in AES
Cipher Block Chaining mode
If encryption buffer size is not a multiple of the block size (in AES
that's always 16 bytes) then the ENCRYPTION ONLY will write data outside
of the caller's buffer when it encrypts the last block.
See code below for problem and fix.
==================================
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
const unsigned long length, const AES_KEY *key,
unsigned char *ivec, const int enc) {
unsigned long n;
unsigned long len = length;
unsigned char tmp[AES_BLOCK_SIZE];
const unsigned char *iv = ivec;
assert(in && out && key && ivec);
assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
if (AES_ENCRYPT == enc) {
while (len >= AES_BLOCK_SIZE) {
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] = in[n] ^ iv[n];
AES_encrypt(out, out, key);
iv = out;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
#if 0 /* BUFFER OVERRUN - REMOVE CODE */
if (len) {
for(n=0; n < len; ++n)
out[n] = in[n] ^ iv[n];
for(n=len; n < AES_BLOCK_SIZE; ++n)
out[n] = iv[n];
AES_encrypt(out, out, key);
iv = out;
}
#else /* BUFFER OVERRUN - FIX FOLLOWS */
if (len)
{
memcpy(tmp, in, len);
memcpy(tmp + len, iv + len, AES_BLOCK_SIZE -
len);
for (n = 0; n < len; n++)
tmp[n] = in[n] ^ iv[n];
AES_encrypt(tmp, tmp, key);
memcpy(out, iv = tmp, len);
}
#endif /* BUFFER OVERRUN - END OF FIX */
memcpy(ivec,iv,AES_BLOCK_SIZE);
} else if (in != out) {
while (len >= AES_BLOCK_SIZE) {
AES_decrypt(in, out, key);
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] ^= iv[n];
iv = in;
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (len) {
AES_decrypt(in,tmp,key);
for(n=0; n < len; ++n)
out[n] = tmp[n] ^ iv[n];
iv = in;
}
memcpy(ivec,iv,AES_BLOCK_SIZE);
} else {
while (len >= AES_BLOCK_SIZE) {
memcpy(tmp, in, AES_BLOCK_SIZE);
AES_decrypt(in, out, key);
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] ^= ivec[n];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
len -= AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
}
if (len) {
memcpy(tmp, in, AES_BLOCK_SIZE);
AES_decrypt(tmp, out, key);
for(n=0; n < len; ++n)
out[n] ^= ivec[n];
for(n=len; n < AES_BLOCK_SIZE; ++n)
out[n] = tmp[n];
memcpy(ivec, tmp, AES_BLOCK_SIZE);
}
}
} ______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [EMAIL PROTECTED]
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [EMAIL PROTECTED]