Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using CFB as a stream cipher fails with BlockModeError #28

Closed
iceiix opened this issue Sep 30, 2018 · 4 comments
Closed

Using CFB as a stream cipher fails with BlockModeError #28

iceiix opened this issue Sep 30, 2018 · 4 comments

Comments

@iceiix
Copy link

iceiix commented Sep 30, 2018

Hello I'm attempting to switch from OpenSSL to this module but it is returning BlockModeError when decrypting/encrypting in CFB mode with a non-multiple of block size. Example program:

extern crate aes;
extern crate block_modes;

use aes::block_cipher_trait::generic_array::GenericArray;
use aes::Aes128;
use block_modes::{BlockMode, BlockModeIv, Cfb};
use block_modes::block_padding::ZeroPadding;
type Aes128Cfb = Cfb<Aes128, ZeroPadding>;

const N: usize = 32;

fn main() {
    let key = &[71, 174, 234, 93, 242, 208, 116, 243, 124, 41, 213, 92, 130, 106, 100, 61];

    {
        let mut cipher = Aes128Cfb::new_varkey(key, GenericArray::from_slice(key)).unwrap();
        println!("enabling encryption with key={:?}", key);

        println!("encrypting");
        let mut data: [u8; N] = [42; N];
        println!("data = {:?}", data);
        //data.clone_from_slice(&buf);
        cipher.encrypt_nopad(&mut data).expect("failed to encrypt");

        println!("data = {:?}", data);
    }

    {
        let mut cipher = Aes128Cfb::new_varkey(key, GenericArray::from_slice(key)).unwrap();
        let mut data = [3, 183, 34, 56, 139, 222, 104, 78, 232, 246, 32, 183, 49, 151, 255, 163, 144, 145, 145, 75, 255, 63, 208, 64, 219, 243, 43, 234, 93, 187, 207, 138];

        cipher.decrypt_nopad(&mut data).expect("failed to decrypt");
        println!("decrypted = {:?}", data);
    }
}

succeeds with N=32 but change to not a multiple, example N=1, fails:

enabling encryption with key=[71, 174, 234, 93, 242, 208, 116, 243, 124, 41, 213, 92, 130, 106, 100, 61]
encrypting
data = [42]
thread 'main' panicked at 'failed to encrypt: BlockModeError', libcore/result.rs:1009:5

if buffer.len() % bs != 0 {
has this check:

        if buffer.len() % bs != 0 {
            Err(BlockModeError)?
        }

so multiples of block size will fail with all modes. This is of course expected with most of the modes, but with CFB, decrypting/encrypting any number of bits is allowed: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_(CFB)

The Cipher Feedback (CFB) mode, a close relative of CBC, makes a block cipher into a self-synchronizing stream cipher.

and it works with OpenSSL. Any ideas of how to accomplish this using RustCrypto. It seems padding is mandatory with this module. Should CFB be implemented in https://github.com/RustCrypto/stream-ciphers?

@newpavlov
Copy link
Member

Yes, block-modes implementations currently require mandatory padding. I think it will be better to add a separate crate which will implement CFB mode as a self-synchronizing stream cipher. Though I am not yet sure how traits should look for this family of algorithms and how they should relate to synchronous stream cipher traits, so we could start with trait-less implementation. I will try to implement it today.

@newpavlov
Copy link
Member

See cfb-mode crate. I think it should cover all your requirements. Note that for optimal performance it's recommended to enable aes target feature. (ergonomic dynamic detection of target feature availability is still being worked out) On my machine I get 1450/350 MB/s for decrypt/ encrypt respectively with enabled AES-NI, and 67/12 MB/s with disabled.

@newpavlov
Copy link
Member

Feel free to open additional issues if you'll encounter any problems!

@iceiix
Copy link
Author

iceiix commented Oct 4, 2018

Thanks! I'll take a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants