shadowsocks/shadowsocks-rust · error
AES-256
Error message
AES-256
What it means
Counterpart for AES-256 methods: Aes256::new_from_slice(&identity_sub_key[0..32]).expect("AES-256") unwraps the key-length conversion. Like the AES-128 case it is an internal invariant (blake3 derive_key supplies 32 bytes), so it should never fire in normal operation; a panic indicates the key material slicing/derivation was broken by a code or dependency change.
Source
Thrown at crates/shadowsocks/src/relay/tcprelay/aead_2022.rs:324
return Err(ProtocolError::MissingExtendedIdentityHeader).into();
}
let (eih, remain_header_chunk) = header_chunk.split_at_mut(16);
header_chunk = remain_header_chunk;
let key_material = [key, salt].concat();
let identity_sub_key = blake3::derive_key(AEAD2022_EIH_SUBKEY_CONTEXT, &key_material);
let mut user_hash = Block::from([0u8; 16]);
match self.method {
CipherKind::AEAD2022_BLAKE3_AES_128_GCM => {
let cipher = Aes128::new_from_slice(&identity_sub_key[0..16]).expect("AES-128");
cipher.decrypt_block_b2b(
<&Block as TryFrom<&[u8]>>::try_from(eih).expect("EIH key length mismatch"),
&mut user_hash,
);
}
CipherKind::AEAD2022_BLAKE3_AES_256_GCM => {
let cipher = Aes256::new_from_slice(&identity_sub_key[0..32]).expect("AES-256");
cipher.decrypt_block_b2b(
<&Block as TryFrom<&[u8]>>::try_from(eih).expect("EIH key length mismatch"),
&mut user_hash,
);
}
_ => unreachable!("{} doesn't support EIH", self.method),
}
let user_hash = user_hash.as_slice();
trace!(
"server EIH {:?}, hash: {:?}",
ByteStr::new(eih),
ByteStr::new(user_hash)
);
match user_manager.get_user_by_hash(user_hash) {
None => {
return Err(ProtocolError::InvalidClientUser(Bytes::copy_from_slice(user_hash))).into();View on GitHub (pinned to 8eb0f0a65b)
Solutions
- Report a bug if encountered at runtime with crate versions
- Propagate an error instead of expect when modifying the derivation code
- After dependency upgrades, assert derive_key output length in tests
Defensive patterns
Strategy: validation
Validate before calling
debug_assert!(identity_sub_key.len() >= 32, "EIH sub-key too short");
Type guard
fn key_material_ok(k: &[u8]) -> bool { k.len() >= 32 } Try / catch
let cipher = Aes256::new_from_slice(&identity_sub_key[0..32])
.map_err(|_| ProtocolError::InvalidState)?; Prevention
- Add unit tests asserting derive_key output >= 32 bytes
- Pin KDF and aes crate versions
- Propagate errors instead of expect in derived code paths
When it happens
Trigger: Only reachable if blake3::derive_key returns fewer than 32 bytes or the 0..32 slice is altered — effectively a code bug, not a runtime condition users can trigger.
Common situations: Seen only during development after refactoring the EIH sub-key derivation or swapping the KDF/aes crates.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09).
Data as JSON: /api/errors/bef12028c8605739.
Report an issue: GitHub.