Skip to content

Commit 03c9ccb

Browse files
DRY shared hkdf_extract_expand code to new module
1 parent 5e7b2bf commit 03c9ccb

File tree

4 files changed

+57
-45
lines changed

4 files changed

+57
-45
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ mod inbound_payment {
8181
use ln::msgs;
8282
use ln::msgs::MAX_VALUE_MSAT;
8383
use util::chacha20::ChaCha20;
84+
use util::crypto::hkdf_extract_expand_thrice;
8485
use util::logger::Logger;
8586

8687
use core::convert::TryInto;
@@ -112,7 +113,13 @@ mod inbound_payment {
112113

113114
impl ExpandedKey {
114115
pub(super) fn new(key_material: &KeyMaterial) -> ExpandedKey {
115-
hkdf_extract_expand(b"LDK Inbound Payment Key Expansion", &key_material)
116+
let (metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) =
117+
hkdf_extract_expand_thrice(b"LDK Inbound Payment Key Expansion", &key_material.0);
118+
Self {
119+
metadata_key,
120+
ldk_pmt_hash_key,
121+
user_pmt_hash_key,
122+
}
116123
}
117124
}
118125

@@ -330,31 +337,6 @@ mod inbound_payment {
330337
}
331338
return Ok(PaymentPreimage(decoded_payment_preimage))
332339
}
333-
334-
fn hkdf_extract_expand(salt: &[u8], ikm: &KeyMaterial) -> ExpandedKey {
335-
let mut hmac = HmacEngine::<Sha256>::new(salt);
336-
hmac.input(&ikm.0);
337-
let prk = Hmac::from_engine(hmac).into_inner();
338-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
339-
hmac.input(&[1; 1]);
340-
let metadata_key = Hmac::from_engine(hmac).into_inner();
341-
342-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
343-
hmac.input(&metadata_key);
344-
hmac.input(&[2; 1]);
345-
let ldk_pmt_hash_key = Hmac::from_engine(hmac).into_inner();
346-
347-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
348-
hmac.input(&ldk_pmt_hash_key);
349-
hmac.input(&[3; 1]);
350-
let user_pmt_hash_key = Hmac::from_engine(hmac).into_inner();
351-
352-
ExpandedKey {
353-
metadata_key,
354-
ldk_pmt_hash_key,
355-
user_pmt_hash_key,
356-
}
357-
}
358340
}
359341

360342
// We hold various information about HTLC relay in the HTLC objects in Channel itself:

lightning/src/ln/peer_channel_encryptor.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use prelude::*;
1212
use ln::msgs::LightningError;
1313
use ln::msgs;
1414

15-
use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine};
15+
use bitcoin::hashes::{Hash, HashEngine};
1616
use bitcoin::hashes::sha256::Hash as Sha256;
1717

1818
use bitcoin::secp256k1::Secp256k1;
@@ -21,6 +21,7 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
2121
use bitcoin::secp256k1;
2222

2323
use util::chacha20poly1305rfc::ChaCha20Poly1305RFC;
24+
use util::crypto::hkdf_extract_expand_twice;
2425
use bitcoin::hashes::hex::ToHex;
2526

2627
/// Maximum Lightning message data length according to
@@ -160,22 +161,9 @@ impl PeerChannelEncryptor {
160161
Ok(())
161162
}
162163

163-
fn hkdf_extract_expand(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32]) {
164-
let mut hmac = HmacEngine::<Sha256>::new(salt);
165-
hmac.input(ikm);
166-
let prk = Hmac::from_engine(hmac).into_inner();
167-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
168-
hmac.input(&[1; 1]);
169-
let t1 = Hmac::from_engine(hmac).into_inner();
170-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
171-
hmac.input(&t1);
172-
hmac.input(&[2; 1]);
173-
(t1, Hmac::from_engine(hmac).into_inner())
174-
}
175-
176164
#[inline]
177165
fn hkdf(state: &mut BidirectionalNoiseState, ss: SharedSecret) -> [u8; 32] {
178-
let (t1, t2) = Self::hkdf_extract_expand(&state.ck, &ss[..]);
166+
let (t1, t2) = hkdf_extract_expand_twice(&state.ck, &ss[..]);
179167
state.ck = t1;
180168
t2
181169
}
@@ -311,7 +299,7 @@ impl PeerChannelEncryptor {
311299
let temp_k = PeerChannelEncryptor::hkdf(bidirectional_state, ss);
312300

313301
PeerChannelEncryptor::encrypt_with_ad(&mut res[50..], 0, &temp_k, &bidirectional_state.h, &[0; 0]);
314-
final_hkdf = Self::hkdf_extract_expand(&bidirectional_state.ck, &[0; 0]);
302+
final_hkdf = hkdf_extract_expand_twice(&bidirectional_state.ck, &[0; 0]);
315303
ck = bidirectional_state.ck.clone();
316304
res
317305
},
@@ -365,7 +353,7 @@ impl PeerChannelEncryptor {
365353
let temp_k = PeerChannelEncryptor::hkdf(bidirectional_state, ss);
366354

367355
PeerChannelEncryptor::decrypt_with_ad(&mut [0; 0], 0, &temp_k, &bidirectional_state.h, &act_three[50..])?;
368-
final_hkdf = Self::hkdf_extract_expand(&bidirectional_state.ck, &[0; 0]);
356+
final_hkdf = hkdf_extract_expand_twice(&bidirectional_state.ck, &[0; 0]);
369357
ck = bidirectional_state.ck.clone();
370358
},
371359
_ => panic!("Wrong direction for act"),
@@ -399,7 +387,7 @@ impl PeerChannelEncryptor {
399387
match self.noise_state {
400388
NoiseState::Finished { ref mut sk, ref mut sn, ref mut sck, rk: _, rn: _, rck: _ } => {
401389
if *sn >= 1000 {
402-
let (new_sck, new_sk) = Self::hkdf_extract_expand(sck, sk);
390+
let (new_sck, new_sk) = hkdf_extract_expand_twice(sck, sk);
403391
*sck = new_sck;
404392
*sk = new_sk;
405393
*sn = 0;
@@ -425,7 +413,7 @@ impl PeerChannelEncryptor {
425413
match self.noise_state {
426414
NoiseState::Finished { sk: _, sn: _, sck: _, ref mut rk, ref mut rn, ref mut rck } => {
427415
if *rn >= 1000 {
428-
let (new_rck, new_rk) = Self::hkdf_extract_expand(rck, rk);
416+
let (new_rck, new_rk) = hkdf_extract_expand_twice(rck, rk);
429417
*rck = new_rck;
430418
*rk = new_rk;
431419
*rn = 0;

lightning/src/util/crypto.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use bitcoin::hashes::{Hash, HashEngine};
2+
use bitcoin::hashes::hmac::{Hmac, HmacEngine};
3+
use bitcoin::hashes::sha256::Hash as Sha256;
4+
5+
macro_rules! hkdf_extract_expand {
6+
($salt: expr, $ikm: expr) => {{
7+
let mut hmac = HmacEngine::<Sha256>::new($salt);
8+
hmac.input($ikm);
9+
let prk = Hmac::from_engine(hmac).into_inner();
10+
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
11+
hmac.input(&[1; 1]);
12+
let t1 = Hmac::from_engine(hmac).into_inner();
13+
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
14+
hmac.input(&t1);
15+
hmac.input(&[2; 1]);
16+
(t1, Hmac::from_engine(hmac).into_inner(), prk)
17+
}};
18+
($salt: expr, $ikm: expr, 2) => {{
19+
let (k1, k2, _) = hkdf_extract_expand!($salt, $ikm);
20+
(k1, k2)
21+
}};
22+
($salt: expr, $ikm: expr, 3) => {{
23+
let (k1, k2, prk) = hkdf_extract_expand!($salt, $ikm);
24+
25+
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
26+
hmac.input(&k2);
27+
hmac.input(&[3; 1]);
28+
(k1, k2, Hmac::from_engine(hmac).into_inner())
29+
}}
30+
}
31+
32+
pub fn hkdf_extract_expand_twice(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32]) {
33+
hkdf_extract_expand!(salt, ikm, 2)
34+
}
35+
36+
pub fn hkdf_extract_expand_thrice(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32], [u8; 32]) {
37+
hkdf_extract_expand!(salt, ikm, 3)
38+
}

lightning/src/util/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ pub(crate) mod scid_utils;
3838
#[macro_use]
3939
pub(crate) mod macro_logger;
4040

41+
/// Cryptography utilities.
42+
pub(crate) mod crypto;
43+
4144
// These have to come after macro_logger to build
4245
pub mod logger;
4346
pub mod config;
@@ -49,3 +52,4 @@ pub mod test_utils;
4952
/// machine errors and used in fuzz targets and tests.
5053
#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
5154
pub mod enforcing_trait_impls;
55+

0 commit comments

Comments
 (0)