Discussion:
Help with CFB8, Skipping Bytes
Ray Kelly
2013-01-18 13:39:20 UTC
Permalink
I am working on a project using bouncycastle in c#.  Speed is crucial to what I am doing (every millisecond counts).   I have a CFB8 stream
using AesFastEngine/No Padding.   I have specific chunks that I do not care about
decrypting.  I would like to know if there is any way to not decrypt a
chunk of data in the middle of my stream.  So for instance:

100 bytes comes in, decrypt it
20,000 bytes comes in, do NOT decrypt it
100 bytes comes in, decrypt it

In
this scenario now, the 3rd chunk does not decode properly unless I
decode the 2nd chunk.   I am pretty sure this is proper behavior, but I
am wondering if there is any way to code around this or get the cipher
back on track again.   Thanks for your help!

Ray
Chris Hacking
2013-01-18 15:02:41 UTC
Permalink
I believe this depends on the mode of operation. some modes, like CTR,
should be able to skip ahead, while I believe that others (like CBC) cannot.
In effect, each previous block acts an initialization vector for the next
one.



Incidentally, if you're using hardware that supports crypto in silicon (the
latest generation of CPUs, for example), you'll get much better speed than
any software implementation can give you, especially in a managed language
(a C/C++ implementation might use inline assembly to call the
hardware-accelerated functionality, but C# can't do that).



From: Ray Kelly [mailto:vbisbest-/***@public.gmane.org]
Sent: Friday, 18 Jan 2013 5:39 AM
To: dev-crypto-csharp-***@public.gmane.org
Subject: [dev-crypto-csharp] Help with CFB8, Skipping Bytes



I am working on a project using bouncycastle in c#. Speed is crucial to
what I am doing (every millisecond counts). I have a CFB8 stream using
AesFastEngine/No Padding. I have specific chunks that I do not care about
decrypting. I would like to know if there is any way to not decrypt a chunk
of data in the middle of my stream. So for instance:

100 bytes comes in, decrypt it
20,000 bytes comes in, do NOT decrypt it
100 bytes comes in, decrypt it

In this scenario now, the 3rd chunk does not decode properly unless I decode
the 2nd chunk. I am pretty sure this is proper behavior, but I am
wondering if there is any way to code around this or get the cipher back on
track again. Thanks for your help!

Ray
Moschny, Torsten
2013-01-18 17:44:15 UTC
Permalink
That's correct. If you look at the workflow
(http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29)
you'll realize that you can't skip intermediate blocks when decrypting.

Regards,
Torsten
I believe this depends on the mode of operation… some modes, like CTR,
should be able to skip ahead, while I believe that others (like CBC)
cannot. In effect, each previous block acts an initialization vector for
the next one.
Incidentally, if you’re using hardware that supports crypto in silicon
(the latest generation of CPUs, for example), you’ll get much better
speed than any software implementation can give you, especially in a
managed language (a C/C++ implementation might use inline assembly to
call the hardware-accelerated functionality, but C# can’t do that).
*Sent:* Friday, 18 Jan 2013 5:39 AM
*Subject:* [dev-crypto-csharp] Help with CFB8, Skipping Bytes
I am working on a project using bouncycastle in c#. Speed is crucial to
what I am doing (every millisecond counts). I have a CFB8 stream using
AesFastEngine/No Padding. I have specific chunks that I do not care
about decrypting. I would like to know if there is any way to not
100 bytes comes in, decrypt it
20,000 bytes comes in, do NOT decrypt it
100 bytes comes in, decrypt it
In this scenario now, the 3rd chunk does not decode properly unless I
decode the 2nd chunk. I am pretty sure this is proper behavior, but I
am wondering if there is any way to code around this or get the cipher
back on track again. Thanks for your help!
Ray
Peter Dettman
2013-01-19 06:03:00 UTC
Permalink
Actually, I think this can be made to work (for decryption) because the
decryption only depends on a small amount of the preceding ciphertext.

Quoting from "Applied Cryptography" 9.6 (Error Propagation):

"With CFB mode, an error in the plaintext affects all subsequent
ciphertext and reverses itself at
decryption. An error in the ciphertext is more interesting. The first
effect of a single-bit error in the
ciphertext is to cause a single error in the plaintext. After that, the
error enters the shift register,
where it causes ciphertext to be garbled until it falls off the other
end of the register. In 8-bit CFB
mode, 9 bytes of decrypted plaintext are garbled by a single-bit error
in the ciphertext. After that, the
system recovers and all subsequent ciphertext is decrypted correctly. In
general, in n-bit CFB a
single ciphertext error will affect the decryption of the current and
following m/n-1 blocks, where m
is the block size.
One subtle problem with this kind of error propagation is that if
Mallory knows the plaintext of a
transmission, he can toggle bits in a given block and make it decrypt to
whatever he wants. The next
block will decrypt to garbage, but the damage may already be done. And
he can change the final bits
of a message without detection.
CFB is self-recovering with respect to synchronization errors as well.
The error enters the shift
register, where it garbles 8 bytes of data until it falls off the other
end. CFB is an example of block
cipher being used as a self-synchronizing stream cipher (at the block
level)."

So, short version, for CFB8 you need to skip to a few bytes (8?) before
the intended offset (in the ciphertext), read and discard up to the real
offset, then the stream should have self-synchronized and following
decryption should be correct. If the skip is smaller than that window
you'd just read and discard it.

If you are using the CipherStream class, it shouldn't be too hard to
extend it and override the CanSeek/Seek methods.

Pete.
I am working on a project using bouncycastle in c#. Speed is crucial
to what I am doing (every millisecond counts). I have a CFB8 stream
using AesFastEngine/No Padding. I have specific chunks that I do not
care about decrypting. I would like to know if there is any way to
100 bytes comes in, decrypt it
20,000 bytes comes in, do NOT decrypt it
100 bytes comes in, decrypt it
In this scenario now, the 3rd chunk does not decode properly unless I
decode the 2nd chunk. I am pretty sure this is proper behavior, but
I am wondering if there is any way to code around this or get the
cipher back on track again. Thanks for your help!
Ray
Loading...