Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Crypt-Rijndael CPAN distribution.

Report information
The Basics
Id: 86385
Status: open
Priority: 0/
Queue: Crypt-Rijndael

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.11
Fixed in: (no value)



Subject: Decryption error when splitting data over blocks
Decrypting doesn't appear to work properly when ->decrypt is called multiple times on small blocks, as opposed to once overall. Setup using a randomly-generated key: eval: my $r = Crypt::Rijndael->new( pack('H*', 'af5a82cd7471cf035c50f1aa353d0209'), Crypt::Rijndael::MODE_CFB ); Set an IV and encrypt some plaintext: eval: $r->set_iv( pack( 'H*', '7a2362b5e9f8aa3b2bc9ba10eaf0fe32' ) ); eval: my $plaintext = "E" x 64; 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' eval: my $ciphertext = $r->encrypt( $plaintext ); "Z \x1f1;\xca\xee\x95f\xad\xf6\x88K\x8c\t\x053\xb4\n]\xfe\x9b\xf1HD\eb%\xd0\xc97\xf7\x84\xd8\x13\xa9\x81\xd5\xaex\xc5\x9a:e\xc2\x8c\xfc\xdf_\x03i\x85\xcf\xc0\xc2t\x99\x9a\x80\xce\x9c\xaa$\x8a" Reset the IV and decrypt it in one go: eval: $r->set_iv( pack( 'H*', '7a2362b5e9f8aa3b2bc9ba10eaf0fe32' ) ); eval: $r->decrypt( $ciphertext ) 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' Reset the IV and decrypt it this time in two individual blocks: eval: $r->set_iv( pack( 'H*', '7a2362b5e9f8aa3b2bc9ba10eaf0fe32' ) ); eval: $r->decrypt( substr $ciphertext, 0, 16 ) 'EEEEEEEEEEEEEEEE' eval: $r->decrypt( substr $ciphertext, 16, 16 ) ",\xd1P)\x80\x14Z\x98g\xf3\xd1\xe8\xde\x00{\xb7" I believe this comes down to the fact that in _rijndael.c's block_encrypt() and block_decrypt(), you reset the block state to the IV on every call, thus restarting every ->decrypt method from the IV, rather than saving state from the previous call. I would suggest that to fix it, the object's stored IV should be updated from the latest state of the block, so that multiple small ->decrypt calls can work correctly. This is vital for me as I am processing a multi-gigabyte file in blocks, as it is downloaded, and I can't buffer the entire thing in RAM first before calling a single ->decrypt operation on the whole thing. -- Paul Evans
On Mon Jun 24 10:14:17 2013, PEVANS wrote: Show quoted text
> Decrypting doesn't appear to work properly when ->decrypt is called > multiple times on small blocks, as opposed to once overall.
Actually I have now realised this error also affects ->encrypt as well, I just didn't encounter it personally because the encryption on upload was done all in one go. -- Paul Evans
Noted. I can apply any patches that you create. It's all in Github: https://github.com/briandfoy/crypt-rijndael Note that I didn't write the module. I've just been caring for it in the absence of a real maintainer.
On Mon Jun 24 10:14:17 2013, PEVANS wrote: Show quoted text
> Decrypting doesn't appear to work properly when ->decrypt is called > multiple times on small blocks, as opposed to once overall. > > Setup using a randomly-generated key: > > eval: my $r = Crypt::Rijndael->new( pack('H*', > 'af5a82cd7471cf035c50f1aa353d0209'), Crypt::Rijndael::MODE_CFB ); > > Set an IV and encrypt some plaintext: > > eval: $r->set_iv( pack( 'H*', '7a2362b5e9f8aa3b2bc9ba10eaf0fe32' ) ); > > eval: my $plaintext = "E" x 64; > 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' > > eval: my $ciphertext = $r->encrypt( $plaintext ); > "Z > \x1f1;\xca\xee\x95f\xad\xf6\x88K\x8c\t\x053\xb4\n]\xfe\x9b\xf1HD\eb%\xd0\xc97\xf7\x84\xd8\x13\xa9\x81\xd5\xaex\xc5\x9a:e\xc2\x8c\xfc\xdf_\x03i\x85\xcf\xc0\xc2t\x99\x9a\x80\xce\x9c\xaa$\x8a" > > Reset the IV and decrypt it in one go: > > eval: $r->set_iv( pack( 'H*', '7a2362b5e9f8aa3b2bc9ba10eaf0fe32' ) ); > > eval: $r->decrypt( $ciphertext ) > 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' > > Reset the IV and decrypt it this time in two individual blocks: > > eval: $r->set_iv( pack( 'H*', '7a2362b5e9f8aa3b2bc9ba10eaf0fe32' ) ); > > eval: $r->decrypt( substr $ciphertext, 0, 16 ) > 'EEEEEEEEEEEEEEEE' > > eval: $r->decrypt( substr $ciphertext, 16, 16 ) > ",\xd1P)\x80\x14Z\x98g\xf3\xd1\xe8\xde\x00{\xb7" > > > I believe this comes down to the fact that in _rijndael.c's > block_encrypt() and block_decrypt(), you reset the block state to the > IV on every call, thus restarting every ->decrypt method from the IV, > rather than saving state from the previous call. > > I would suggest that to fix it, the object's stored IV should be > updated from the latest state of the block, so that multiple small > ->decrypt calls can work correctly. > > This is vital for me as I am processing a multi-gigabyte file in > blocks, as it is downloaded, and I can't buffer the entire thing in > RAM first before calling a single ->decrypt operation on the whole > thing.
The module does not specify which of these two possible behaviors it is supposed to exhibit, both are useful IMO. Some things may be depending on the current behavior, so I'm leaning towards not changing the default for now, though adding it as an option would be useful. Leon