Hello all,
Found this issue while refactoring my secret-service library. I'm definitely not a crypto expert, so I don't know if I'm understanding this correctly.
Suggestions for handling crypto (AES-CBC) are also welcome, I was thinking of moving away from rust-crypto since there seem to be concerns about its ongoing maintenance, but haven't found an easy-to-use replacement.
The github issue: https://github.com/DaGenix/rust-crypto/issues/410
AES-CBC does not encrypt blank input. Basically, the result of input []
is []
. I'm not a crypto expert, but from what I've read the encryptor should add PKCS7 padding to the input (even an empty block) and then encrypt (this might be called finalize
in another lib). At least, for my secret-service library, I'm unable to use a blank input to create items in the vault because of incorrect encryption.
I may not be understanding the architecture of the blockmodes.rs
architecture, but it looks like an empty input results in exiting the encrypting function with BlockEngineState::FastMode
https://github.com/DaGenix/rust-crypto/blob/master/src/blockmodes.rs#L164
I think this means that in the state machine, https://github.com/DaGenix/rust-crypto/blob/master/src/blockmodes.rs#L246, an empty input will never be able to reach BlockEngineState::LastInput
, which would be required to pad an empty block and encrypt it. Non-empty non-full blocks seem to be padded and processed fine.
As a quick example, running https://github.com/DaGenix/rust-crypto/blob/master/examples/symmetriccipher.rs with a println!
after encrypting the data and blank message
let message = "";
.
.
.
let encrypted_data = encrypt(message.as_bytes(), &key, &iv).ok().unwrap();
println!("{:?}", encrypted_data);
while switching the state machine transition at https://github.com/DaGenix/rust-crypto/blob/master/src/blockmodes.rs#L164 from
return BlockEngineState::FastMode;
to
return BlockEngineState::LastInput;
results in the following output:
mochi:rust-crypto (master|✚2) > cargo run --example symmetriccipher
Compiling rust-crypto v0.2.36 (file:///home/hwchen/projects/rust/secret-service/rust-crypto)
Finished dev [unoptimized + debuginfo] target(s) in 8.14 secs
Running `target/debug/examples/symmetriccipher`
[]
mochi:rust-crypto (master|✚2) > cargo run --example symmetriccipher
Compiling rust-crypto v0.2.36 (file:///home/hwchen/projects/rust/secret-service/rust-crypto)
Finished dev [unoptimized + debuginfo] target(s) in 8.39 secs
Running `target/debug/examples/symmetriccipher`
[98, 8, 226, 87, 130, 36, 3, 95, 121, 177, 74, 250, 126, 11, 199, 41]
Please let me know if I've understood this correctly.