kern/132351: rijndael CBC mode encryption incorrect
Rajesh Patel
RajeshMPatel at yahoo.com
Thu Mar 5 18:20:02 PST 2009
>Number: 132351
>Category: kern
>Synopsis: rijndael CBC mode encryption incorrect
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Mar 06 02:20:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Rajesh Patel
>Release: 5.0
>Organization:
>Environment:
Windows XP professional - 32 bit
>Description:
The function has bug in CBC mode encryption
int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
BYTE *input, int inputLen, BYTE *outBuffer) {
Original code
for (i = numBlocks - 1; i > 0; i--) {
#if 1 /*STRICT_ALIGN*/
AF_BCOPY(outBuffer, block, 16);
========>
((word32*)block)[0] ^= ((word32*)iv)[0];
((word32*)block)[1] ^= ((word32*)iv)[1];
((word32*)block)[2] ^= ((word32*)iv)[2];
((word32*)block)[3] ^= ((word32*)iv)[3];
#else
((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0];
((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1];
((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2];
((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3];
#endif
outBuffer += 16;
rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
input += 16;
}
This keeps using the same iv. As a result, the initial block is encrypted multiple times. input should be copied over iv inside the for loop.
>How-To-Repeat:
>Fix:
Code with Fix
for (i = numBlocks - 1; i > 0; i--) {
#if 1 /*STRICT_ALIGN*/
AF_BCOPY(outBuffer, block, 16);
/*needs this =======>*/ AF_BCOPY(input, iv, 16); /* Added by Rajesh */
((word32*)block)[0] ^= ((word32*)iv)[0];
((word32*)block)[1] ^= ((word32*)iv)[1];
((word32*)block)[2] ^= ((word32*)iv)[2];
((word32*)block)[3] ^= ((word32*)iv)[3];
#else
((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0];
((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1];
((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2];
((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3];
#endif
outBuffer += 16;
rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS);
input += 16;
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list