Skip to content

Commit 936a2b9

Browse files
committed
encrypt attr data
1 parent 077992d commit 936a2b9

File tree

2 files changed

+70
-49
lines changed

2 files changed

+70
-49
lines changed

lightning/src/ln/onion_route_tests.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -699,14 +699,14 @@ fn test_onion_failure() {
699699
let mut hmac = HmacEngine::<Sha256>::new(&um);
700700
hmac.input(&decoded_err_packet.encode()[32..]);
701701
decoded_err_packet.hmac = Hmac::from_engine(hmac).to_byte_array();
702-
let onion_error = OnionErrorPacket{
702+
let mut onion_error = OnionErrorPacket{
703703
data: decoded_err_packet.encode(),
704704
attribution_data: Some([0; ATTRIBUTION_DATA_LEN]),
705705
};
706-
let failure = onion_utils::encrypt_failure_packet(
707-
&onion_keys[1].shared_secret.as_ref(), &onion_error);
708-
msg.reason = failure.data;
709-
msg.attribution_data = failure.attribution_data;
706+
onion_utils::encrypt_failure_packet(
707+
&onion_keys[1].shared_secret.as_ref(), &mut onion_error);
708+
msg.reason = onion_error.data;
709+
msg.attribution_data = onion_error.attribution_data;
710710
}, || nodes[2].node.fail_htlc_backwards(&payment_hash), false, None,
711711
Some(NetworkUpdate::NodeFailure { node_id: route.paths[0].hops[1].pubkey, is_permanent: true }),
712712
Some(channels[1].0.contents.short_channel_id), None);
@@ -728,12 +728,14 @@ fn test_onion_failure() {
728728
let mut hmac = HmacEngine::<Sha256>::new(&um);
729729
hmac.input(&decoded_err_packet.encode()[32..]);
730730
decoded_err_packet.hmac = Hmac::from_engine(hmac).to_byte_array();
731-
let onion_error = OnionErrorPacket{
731+
let mut onion_error = OnionErrorPacket{
732732
data: decoded_err_packet.encode(),
733733
attribution_data: Some([0; ATTRIBUTION_DATA_LEN]),
734734
};
735-
let failure = onion_utils::encrypt_failure_packet(
736-
&onion_keys[0].shared_secret.as_ref(), &onion_error);
735+
onion_utils::encrypt_failure_packet(
736+
&onion_keys[0].shared_secret.as_ref(), &mut onion_error);
737+
738+
// update msg?
737739
}, || {}, true, Some(0x1000|7),
738740
Some(NetworkUpdate::ChannelFailure {
739741
short_channel_id: channels[1].0.contents.short_channel_id,
@@ -756,12 +758,14 @@ fn test_onion_failure() {
756758
let mut hmac = HmacEngine::<Sha256>::new(&um);
757759
hmac.input(&decoded_err_packet.encode()[32..]);
758760
decoded_err_packet.hmac = Hmac::from_engine(hmac).to_byte_array();
759-
let onion_error = OnionErrorPacket{
761+
let mut onion_error = OnionErrorPacket{
760762
data: decoded_err_packet.encode(),
761763
attribution_data: Some([0; ATTRIBUTION_DATA_LEN]),
762764
};
763-
let failure = onion_utils::encrypt_failure_packet(
764-
&onion_keys[1].shared_secret.as_ref(), &onion_error);
765+
onion_utils::encrypt_failure_packet(
766+
&onion_keys[1].shared_secret.as_ref(), &mut onion_error);
767+
768+
// update msg?
765769
}, || nodes[2].node.fail_htlc_backwards(&payment_hash), true, Some(0x1000|7),
766770
Some(NetworkUpdate::ChannelFailure {
767771
short_channel_id: channels[1].0.contents.short_channel_id,

lightning/src/ln/onion_utils.rs

+55-38
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ pub(super) fn gen_ammag_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
8989
Hmac::from_engine(hmac).to_byte_array()
9090
}
9191

92+
#[inline]
93+
pub(super) fn gen_ammagext_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
94+
assert_eq!(shared_secret.len(), 32);
95+
let mut hmac = HmacEngine::<Sha256>::new(&[0x61, 0x6d, 0x6d, 0x61, 0x67, 0x65, 0x78, 0x74]); // ammagext
96+
hmac.input(&shared_secret);
97+
Hmac::from_engine(hmac).to_byte_array()
98+
}
99+
92100
#[cfg(test)]
93101
#[inline]
94102
pub(super) fn gen_pad_from_shared_secret(shared_secret: &[u8]) -> [u8; 32] {
@@ -875,16 +883,20 @@ fn construct_onion_packet_with_init_noise<HD: Writeable, P: Packet>(
875883
/// Encrypts a failure packet. raw_packet can either be a
876884
/// msgs::DecodedOnionErrorPacket.encode() result or a msgs::OnionErrorPacket.data element.
877885
pub(super) fn encrypt_failure_packet(
878-
shared_secret: &[u8], packet: &OnionErrorPacket
879-
) -> msgs::OnionErrorPacket {
880-
let raw_packet = &packet.data;
886+
shared_secret: &[u8], packet: &mut OnionErrorPacket
887+
) {
881888
let ammag = gen_ammag_from_shared_secret(&shared_secret);
889+
process_chacha(&ammag, &mut packet.data);
882890

883-
let mut packet_crypted = Vec::with_capacity(raw_packet.len());
884-
packet_crypted.resize(raw_packet.len(), 0);
885-
let mut chacha = ChaCha20::new(&ammag, &[0u8; 8]);
886-
chacha.process(&raw_packet, &mut packet_crypted[..]);
887-
msgs::OnionErrorPacket { data: packet_crypted, attribution_data: packet.attribution_data } // TODO: Encrypt attribution_data
891+
if let Some(ref mut attribution_data) = packet.attribution_data {
892+
let ammagext = gen_ammagext_from_shared_secret(&shared_secret);
893+
process_chacha(&ammagext, attribution_data);
894+
}
895+
}
896+
897+
pub(super) fn process_chacha(key: &[u8; 32], packet: &mut [u8]) {
898+
let mut chacha = ChaCha20::new(key, &[0u8; 8]);
899+
chacha.process_in_place(packet);
888900
}
889901

890902
pub(super) fn build_failure_packet(
@@ -938,8 +950,10 @@ pub(super) fn build_first_hop_failure_packet(
938950
shared_secret: &[u8], failure_type: u16, failure_data: &[u8],
939951
) -> msgs::OnionErrorPacket {
940952
let payload = [0; 4];
941-
let failure_packet = build_failure_packet(shared_secret, failure_type, failure_data, &payload);
942-
encrypt_failure_packet(shared_secret, &failure_packet)
953+
let mut failure_packet = build_failure_packet(shared_secret, failure_type, failure_data, &payload);
954+
encrypt_failure_packet(shared_secret, &mut failure_packet);
955+
956+
failure_packet
943957
}
944958

945959
pub(crate) struct DecodedOnionFailure {
@@ -956,12 +970,12 @@ pub(crate) struct DecodedOnionFailure {
956970
/// Note that we always decrypt `packet` in-place here even if the deserialization into
957971
/// [`msgs::DecodedOnionErrorPacket`] ultimately fails.
958972
fn decrypt_onion_error_packet(
959-
packet: &mut Vec<u8>, shared_secret: SharedSecret,
973+
packet: &mut OnionErrorPacket, shared_secret: SharedSecret,
960974
) -> Result<msgs::DecodedOnionErrorPacket, msgs::DecodeError> {
961-
let ammag = gen_ammag_from_shared_secret(shared_secret.as_ref());
962-
let mut chacha = ChaCha20::new(&ammag, &[0u8; 8]);
963-
chacha.process_in_place(packet);
964-
msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(packet))
975+
// Decrypt the packet.
976+
encrypt_failure_packet(shared_secret.as_ref(), packet);
977+
978+
msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet.data))
965979
}
966980

967981
/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
@@ -1048,7 +1062,7 @@ where
10481062
// Actually parse the onion error data in tests so we can check that blinded hops fail
10491063
// back correctly.
10501064
let err_packet =
1051-
decrypt_onion_error_packet(&mut encrypted_packet.data, shared_secret)
1065+
decrypt_onion_error_packet(&mut encrypted_packet, shared_secret)
10521066
.unwrap();
10531067
error_code_ret = Some(u16::from_be_bytes(
10541068
err_packet.failuremsg.get(0..2).unwrap().try_into().unwrap(),
@@ -1070,7 +1084,7 @@ where
10701084
let amt_to_forward = htlc_msat - route_hop.fee_msat;
10711085
htlc_msat = amt_to_forward;
10721086

1073-
let decrypt_result = decrypt_onion_error_packet(&mut encrypted_packet.data, shared_secret);
1087+
let decrypt_result = decrypt_onion_error_packet(&mut encrypted_packet, shared_secret);
10741088

10751089
let um = gen_um_from_shared_secret(shared_secret.as_ref());
10761090

@@ -1452,26 +1466,32 @@ impl HTLCFailReason {
14521466
HTLCFailReasonRepr::Reason { ref failure_code, ref data } => {
14531467
let payload = [1; 4];
14541468
if let Some(phantom_ss) = phantom_shared_secret {
1455-
let phantom_packet =
1469+
let mut phantom_packet =
14561470
build_failure_packet(phantom_ss, *failure_code, &data[..], &payload);
1457-
let encrypted_phantom_packet =
1458-
encrypt_failure_packet(phantom_ss, &phantom_packet);
1471+
encrypt_failure_packet(phantom_ss, &mut phantom_packet);
14591472
encrypt_failure_packet(
14601473
incoming_packet_shared_secret,
1461-
&encrypted_phantom_packet
1462-
)
1474+
&mut phantom_packet
1475+
);
1476+
1477+
phantom_packet
14631478
} else {
1464-
let packet = build_failure_packet(
1479+
let mut packet = build_failure_packet(
14651480
incoming_packet_shared_secret,
14661481
*failure_code,
14671482
&data[..],
14681483
&payload
14691484
);
1470-
encrypt_failure_packet(incoming_packet_shared_secret, &packet)
1485+
encrypt_failure_packet(incoming_packet_shared_secret, &mut packet);
1486+
1487+
packet
14711488
}
14721489
},
14731490
HTLCFailReasonRepr::LightningError { ref err } => {
1474-
encrypt_failure_packet(incoming_packet_shared_secret, &err)
1491+
let mut err = err.clone();
1492+
encrypt_failure_packet(incoming_packet_shared_secret, &mut err);
1493+
1494+
err
14751495
},
14761496
}
14771497
}
@@ -2341,12 +2361,9 @@ use crate::util::test_utils::TestLogger;
23412361
for mutated_index in 0..1060+920 {
23422362
let decrypted_failure = test_attributable_failure_packet_onion_with_mutation(mutating_node, mutated_index);
23432363

2344-
// if let Some(chan_id) = decrypted_failure.short_channel_id {
2345-
// println!("Testing mutation {} on node {}: chan failure at {}", mutated_index, mutating_node, chan_id);
2346-
// }
2347-
2348-
assert!(decrypted_failure.onion_error_code == Some(16399) || decrypted_failure.short_channel_id.is_some());
2349-
}
2364+
assert!(decrypted_failure.onion_error_code == Some(16399) ||
2365+
decrypted_failure.short_channel_id == Some(4-mutating_node as u64));
2366+
}
23502367
}
23512368
}
23522369

@@ -2383,12 +2400,12 @@ use crate::util::test_utils::TestLogger;
23832400
let payload = [0, 0, 0, 1];
23842401

23852402
let onion_keys = build_test_onion_keys();
2386-
let onion_error =
2403+
let mut onion_error =
23872404
super::build_failure_packet(onion_keys[4].shared_secret.as_ref(), 0x400f, &failure_data, &payload);
23882405

23892406
let logger: Arc<TestLogger> = Arc::new(TestLogger::new());
23902407

2391-
let mut encrypted_packet = super::encrypt_failure_packet(onion_keys[4].shared_secret.as_ref(), &onion_error);
2408+
super::encrypt_failure_packet(onion_keys[4].shared_secret.as_ref(), &mut onion_error);
23922409
// assert_eq!(encrypted_packet.data.to_lower_hex_string(), EXPECTED_MESSAGES[0]);
23932410

23942411
let mutate_packet = |packet: &mut OnionErrorPacket, mutated_index| {
@@ -2401,19 +2418,19 @@ use crate::util::test_utils::TestLogger;
24012418
};
24022419

24032420
if mutating_node == 0 {
2404-
mutate_packet(&mut encrypted_packet, mutated_index);
2421+
mutate_packet(&mut onion_error, mutated_index);
24052422
}
24062423

24072424
for idx in 1..5 {
24082425

24092426
let shared_secret = onion_keys[4 - idx].shared_secret.as_ref();
24102427

24112428
let payload = [0, 0, 0, (idx + 1) as u8];
2412-
process_failure_packet(&mut encrypted_packet, shared_secret, &payload);
2413-
encrypted_packet = super::encrypt_failure_packet(shared_secret, &encrypted_packet);
2429+
process_failure_packet(&mut onion_error, shared_secret, &payload);
2430+
super::encrypt_failure_packet(shared_secret, &mut onion_error);
24142431

24152432
if mutating_node == idx {
2416-
mutate_packet(&mut encrypted_packet, mutated_index);
2433+
mutate_packet(&mut onion_error, mutated_index);
24172434
}
24182435

24192436
// assert_eq!(encrypted_packet.data.to_lower_hex_string(), EXPECTED_MESSAGES[idx]);
@@ -2432,7 +2449,7 @@ use crate::util::test_utils::TestLogger;
24322449

24332450

24342451
// Assert that the original failure can be retrieved and that all hmacs check out.
2435-
let decrypted_failure = process_onion_failure(&ctx_full, &logger, &htlc_source, encrypted_packet);
2452+
let decrypted_failure = process_onion_failure(&ctx_full, &logger, &htlc_source, onion_error);
24362453

24372454
decrypted_failure
24382455

0 commit comments

Comments
 (0)