tor_llcrypto::pk::ed25519::ExpandedSecretKey::from_bytes() accepts byte buffers which are somehow invalid private keys
Found fuzzing my tor_crypto module in Gosling which wraps tor_llcrypto
. The from_bytes method accepts byte buffers which can be used to successfully construct public keys and sign messages which then cannot be verified.
#![no_main]
// extern
use tor_llcrypto::*;
use signature::Verifier;
// fuzzing
use libfuzzer_sys::fuzz_target;
use libfuzzer_sys::arbitrary;
use libfuzzer_sys::arbitrary::Arbitrary;
#[derive(Arbitrary, Debug)]
struct CryptoData<'a> {
ed25519_private_raw: [u8; 64],
message: &'a [u8],
}
fuzz_target!(|data: CryptoData| {
// tor_llcrpyto version
if !data.message.is_empty() {
let ed25519_private = pk::ed25519::ExpandedSecretKey::from_bytes(&data.ed25519_private_raw).unwrap();
let ed25519_public = pk::ed25519::PublicKey::from(&ed25519_private);
let signature = ed25519_private.sign(data.message, &ed25519_public);
if let Err(err) = ed25519_public.verify(data.message, &signature) {
panic!("{:?}", err); // panics here
}
}
});
Breaking input:
CryptoData {
ed25519_private_raw: [
46,
38,
10,
119,
119,
119,
119,
119,
10,
119,
119,
119,
119,
93,
119,
119,
119,
119,
119,
119,
119,
119,
130,
180,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
119,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
119,
119,
119,
119,
119,
130,
136,
],
message: [
119,
],
}
The error triggering the panic is: signature::Error { source: Some(Verification equation was not satisfied) }
I think I would have expected from_bytes()
to have returned some error if the bytes are not a valid private key per https://docs.rs/tor-llcrypto/latest/tor_llcrypto/pk/ed25519/struct.ExpandedSecretKey.html#method.from_bytes
EDIT1: updated with more accurate analysis
EDIT2:
Breaking key in a more usable format:
let private_raw: [u8; ED25519_PRIVATE_KEY_SIZE] = [
0x2eu8, 0x26u8, 0x0au8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x0au8, 0x77u8, 0x77u8,
0x77u8, 0x77u8, 0x5du8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8,
0x82u8, 0xb4u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8,
0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0xffu8,
0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8, 0xffu8,
0xffu8, 0xffu8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x77u8, 0x82u8, 0x88u8,
];
Edited by richard