traits icon indicating copy to clipboard operation
traits copied to clipboard

cipher: add unaligned bytes en/decryption without padding

Open kazuki0824 opened this issue 2 years ago • 5 comments

In many cases, plaintext and ciphertext input is not divisible by the block size, and padding is often used. In practical use, however, this is not always done, and the termination may be handled by, for example, XOR. This trait and fn proc_tail divides the input into aligned blocks and an unaligned part(tail), and then applies appropriate user-specified processing to the tail

TODO: Show the example usage here, and add the same things on the documentation comments for fn proc_tail

kazuki0824 avatar May 23 '22 15:05 kazuki0824

Are you saying that someone somewhere uses algorithms which wrap a classic block mode (e.g. CBC) and in addition to key/IV it requires additional random block which is used as a one-time pad to encrypt plaintext tail? To be honest to me it looks like a somewhat strange mode. Can you point to a standard which defines something like it? IIUC the traits in this PR are not applicable to the ciphertext stealing modes.

Even if such mode is used somewhere in practice, I am not sure we need the new traits. A crate which implements it could simply use inherent encrypt/decrypt methods.

newpavlov avatar May 24 '22 19:05 newpavlov

@newpavlov Sorry, my explanation seems inadequate. Of course I'm also agree with your opinion. I am trying to implement https://pastebin.com/xsL2j1ti which is important for Japanese video DRM implementation, but in the functions cipher00 and cipher40, it contains an unfamiliar unaligned bytes processing. I had also never seen this type of processing method before, but I have come to believe that it is actually one of the techniques widely used in the industry as a "know how" that I am unaware of. This is because it is often the case that the size of the data to be encrypted is not exactly an integer multiple of the block size.

kazuki0824 avatar Jun 04 '22 10:06 kazuki0824

By using it, I'm also trying to implement the CBC with unaligned bytes processing mentioned above in tail_cbc

kazuki0824 avatar Jun 04 '22 10:06 kazuki0824

IIUC the linked modification of CBC uses a modified processing of last block. In the classic CBC you XOR plaintext with IV and then encrypt result. With the modification for last block you encrypt IV (without XORing) and then XOR plaintext with encryption result.

The modification requires full message to be passed into encryption/decryption function since it has to know whether it processes last block or not, so the existing traits will be a bad fit here.

I think a good start would be to open a PR in the block-modes repository with implementation which would expose API based on inherent methods, i.e. you should not implement the BlockEncryptMut/BlockDecryptMut traits. API could look like this:

impl<C> Encryptor<C>
where
    C: BlockEncryptMut + BlockCipher,
{
    fn encrypt_inout(self, buf: InOutBuf<'_, '_, u8>) { .. }
    fn encrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> { .. }
    fn encrypt(self, buf: &mut [u8]) { .. }
}

With the latter two methods being implemented in terms of encrypt_inout.

Later we may introduce traits for ciphertext stealing modes, which I think should cover this mode modification as well.

newpavlov avatar Jun 04 '22 11:06 newpavlov

I think a good start would be to open a PR in the block-modes repository with implementation which would expose API based on inherent methods, i.e. you should not implement the BlockEncryptMut/BlockDecryptMut traits.

Ok I will create a new PR in https://github.com/RustCrypto/block-modes , and close this soon.

Later we may introduce traits for ciphertext stealing modes, which I think should cover this mode modification as well.

Thanks It's very interesting.

kazuki0824 avatar Jun 27 '22 14:06 kazuki0824