Ok I found the problem.
CBC>>initialVector: aByteArray "Ferguson and Schneier recommend this on page 72 of 'Practical Cryptography'." cipher encryptBlock: aByteArray. super initialVector: aByteArray
Since encrypt and decrypt use initialVector this adds an additional encrypt into every pass. Deleting this method fixes the problem. I understand the intent here so we should either remove initialVector from encrypt and decrypt and set vector directly (adding the destroy method from the superclass initialVector method) or remove this method.
What do you think?
Oh, great catch Ron. I had used the Refactory to abstract BlockCipherMode>>'vector', I didn't noticed this result.
#initialVector: is somewhat of a misnomer for encrypting block to block because it's supposed to be for the *initial* block.
So I posted a fix to Core that adds BlockCipherMode>>#vector:, which simply sets the vector (still avoiding leakage), while #initialVector: still encrypts the IV per Schneiers recommendation.
The CBC test had to be adjusted to account for this (i.e., we cannot compare ciphertexts after a key-change). You should also adjust your Rfc tests to account for the same (i.e., it seems to be a more a test of Rijndael, I would reset the #vector: to the unencrypted value in the spec right after setting the initialVector:).
Thanks! Chris