|
|
@ -33,7 +33,7 @@ enum bolt8_side { |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* Act One is sent from initiator to responder. During `Act One`, the |
|
|
|
* Act One is sent from initiator to responder. During Act One, the |
|
|
|
* initiator attempts to satisfy an implicit challenge by the responder. To |
|
|
|
* complete this challenge, the initiator _must_ know the static public key of |
|
|
|
* the responder. |
|
|
@ -44,15 +44,15 @@ struct act_one { |
|
|
|
u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES]; |
|
|
|
}; |
|
|
|
|
|
|
|
/* BOLT #8: The handshake message is _exactly_ `50 bytes` */ |
|
|
|
/* BOLT #8: The handshake message is _exactly_ 50 bytes */ |
|
|
|
#define ACT_ONE_SIZE 50 /* ARM's stupid ABI adds padding. */ |
|
|
|
|
|
|
|
static inline void check_act_one(const struct act_one *act1) |
|
|
|
{ |
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* : `1 byte` for the handshake version, `33 bytes` for the compressed |
|
|
|
* ephemeral public key of the initiator, and `16 bytes` for the |
|
|
|
* : 1 byte for the handshake version, 33 bytes for the compressed |
|
|
|
* ephemeral public key of the initiator, and 16 bytes for the |
|
|
|
* `poly1305` tag. |
|
|
|
*/ |
|
|
|
BUILD_ASSERT(sizeof(act1->v) == 1); |
|
|
@ -62,10 +62,10 @@ static inline void check_act_one(const struct act_one *act1) |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* `Act Two` is sent from the responder to the initiator. `Act Two` will |
|
|
|
* _only_ take place if `Act One` was successful. `Act One` was successful if |
|
|
|
* the responder was able to properly decrypt and check the `MAC` of the tag |
|
|
|
* sent at the end of `Act One`. |
|
|
|
* Act Two is sent from the responder to the initiator. Act Two will |
|
|
|
* _only_ take place if Act One was successful. Act One was successful if |
|
|
|
* the responder was able to properly decrypt and check the MAC of the tag |
|
|
|
* sent at the end of Act One. |
|
|
|
*/ |
|
|
|
struct act_two { |
|
|
|
u8 v; |
|
|
@ -73,15 +73,15 @@ struct act_two { |
|
|
|
u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES]; |
|
|
|
}; |
|
|
|
|
|
|
|
/* BOLT #8: The handshake is _exactly_ `50 bytes:` */ |
|
|
|
/* BOLT #8: The handshake is _exactly_ 50 bytes: */ |
|
|
|
#define ACT_TWO_SIZE 50 /* ARM's stupid ABI adds padding. */ |
|
|
|
|
|
|
|
static inline void check_act_two(const struct act_two *act2) |
|
|
|
{ |
|
|
|
/* BOLT #8:
|
|
|
|
* `1 byte` for the handshake version, |
|
|
|
* `33 bytes` for the compressed ephemeral public key of the initiator, and |
|
|
|
* `16 bytes` for the `poly1305` tag. |
|
|
|
* 1 byte for the handshake version, |
|
|
|
* 33 bytes for the compressed ephemeral public key of the initiator, and |
|
|
|
* 16 bytes for the `poly1305` tag. |
|
|
|
*/ |
|
|
|
BUILD_ASSERT(sizeof(act2->v) == 1); |
|
|
|
BUILD_ASSERT(sizeof(act2->pubkey) == 33); |
|
|
@ -90,11 +90,11 @@ static inline void check_act_two(const struct act_two *act2) |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* `Act Three` is the final phase in the authenticated key agreement described |
|
|
|
* Act Three is the final phase in the authenticated key agreement described |
|
|
|
* in this section. This act is sent from the initiator to the responder as a |
|
|
|
* final concluding step. `Act Three` is only executed `iff` `Act Two` was |
|
|
|
* successful. During `Act Three`, the initiator transports its static public |
|
|
|
* key to the responder encrypted with _strong_ forward secrecy using the |
|
|
|
* concluding step. Act Three is executed _if and only if_ Act Two was |
|
|
|
* successful. During Act Three, the initiator transports its static public |
|
|
|
* key to the responder encrypted with _strong_ forward secrecy, using the |
|
|
|
* accumulated `HKDF` derived secret key at this point of the handshake. |
|
|
|
*/ |
|
|
|
struct act_three { |
|
|
@ -103,17 +103,17 @@ struct act_three { |
|
|
|
u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES]; |
|
|
|
}; |
|
|
|
|
|
|
|
/* BOLT #8: The handshake is _exactly_ `66 bytes` */ |
|
|
|
/* BOLT #8: The handshake is _exactly_ 66 bytes */ |
|
|
|
#define ACT_THREE_SIZE 66 /* ARM's stupid ABI adds padding. */ |
|
|
|
|
|
|
|
static inline void check_act_three(const struct act_three *act3) |
|
|
|
{ |
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* `1 byte` for the handshake version, `33 bytes` for the ephemeral |
|
|
|
* public key encrypted with the `ChaCha20` stream cipher, `16 bytes` |
|
|
|
* for the encrypted public key's tag generated via the `AEAD` |
|
|
|
* construction, and `16 bytes` for a final authenticating tag. |
|
|
|
* 1 byte for the handshake version, 33 bytes for the ephemeral |
|
|
|
* public key encrypted with the `ChaCha20` stream cipher, 16 bytes |
|
|
|
* for the encrypted public key's tag generated via the AEAD |
|
|
|
* construction, and 16 bytes for a final authenticating tag. |
|
|
|
*/ |
|
|
|
BUILD_ASSERT(sizeof(act3->v) == 1); |
|
|
|
BUILD_ASSERT(sizeof(act3->ciphertext) == 33 + 16); |
|
|
@ -122,12 +122,11 @@ static inline void check_act_three(const struct act_three *act3) |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `generateKey()` |
|
|
|
* * where generateKey generates and returns a fresh `secp256k1` keypair |
|
|
|
* * the object returned by `generateKey` has two attributes: |
|
|
|
* * `.pub`: which returns an abstract object representing the |
|
|
|
* * `generateKey()`: generates and returns a fresh `secp256k1` keypair |
|
|
|
* * where the object returned by `generateKey` has two attributes: |
|
|
|
* * `.pub`, which returns an abstract object representing the |
|
|
|
* public key |
|
|
|
* * `.priv`: which represents the private key used to generate the |
|
|
|
* * `.priv`, which represents the private key used to generate the |
|
|
|
* public key |
|
|
|
*/ |
|
|
|
struct keypair { |
|
|
@ -141,20 +140,20 @@ struct keypair { |
|
|
|
* |
|
|
|
* * `ck`: The **chaining key**. This value is the accumulated hash of all |
|
|
|
* previous ECDH outputs. At the end of the handshake, `ck` is used to |
|
|
|
* derive the encryption keys for lightning messages. |
|
|
|
* derive the encryption keys for Lightning messages. |
|
|
|
* |
|
|
|
* * `h`: The **handshake hash**. This value is the accumulated hash of _all_ |
|
|
|
* handshake data that has been sent and received so far during the |
|
|
|
* handshake process. |
|
|
|
* |
|
|
|
* * `temp_k1`, `temp_k2`, `temp_k3`: **intermediate keys** used to |
|
|
|
* encrypt/decrypt the zero-length AEAD payloads at the end of each |
|
|
|
* * `temp_k1`, `temp_k2`, `temp_k3`: **intermediate keys**. These are used to |
|
|
|
* encrypt and decrypt the zero-length AEAD payloads at the end of each |
|
|
|
* handshake message. |
|
|
|
* |
|
|
|
* * `e`: A party's **ephemeral keypair**. For each session a node MUST |
|
|
|
* generate a new ephemeral key with strong cryptographic randomness. |
|
|
|
* |
|
|
|
* * `s`: A party's **static public key** (`ls` for local, `rs` for remote) |
|
|
|
* * `s`: a party's **static public key** (`ls` for local, `rs` for remote) |
|
|
|
*/ |
|
|
|
struct handshake { |
|
|
|
struct secret ck; |
|
|
@ -230,9 +229,9 @@ static void hkdf_two_keys(struct secret *out1, struct secret *out2, |
|
|
|
{ |
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `HKDF(salt,ikm)`: a function is defined in [3](#reference-3), |
|
|
|
* evaluated with a zero-length `info` field. |
|
|
|
* * All invocations of the `HKDF` implicitly return `64-bytes` |
|
|
|
* * `HKDF(salt,ikm)`: a function defined in `RFC 5869`<sup>[3](#reference-3)</sup>, |
|
|
|
* evaluated with a zero-length `info` field |
|
|
|
* * All invocations of `HKDF` implicitly return 64 bytes |
|
|
|
* of cryptographic randomness using the extract-and-expand |
|
|
|
* component of the `HKDF`. |
|
|
|
*/ |
|
|
@ -253,7 +252,7 @@ static void le64_nonce(unsigned char *npub, u64 nonce) |
|
|
|
{ |
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* ...with nonce `n` encoded as 32 zero bits followed by a |
|
|
|
* ...with nonce `n` encoded as 32 zero bits, followed by a |
|
|
|
* *little-endian* 64-bit value (this follows the Noise Protocol |
|
|
|
* convention, rather than our normal endian). |
|
|
|
*/ |
|
|
@ -362,15 +361,15 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `rk, sk = HKDF(ck, zero)` |
|
|
|
* 9. `rk, sk = HKDF(ck, zero)` |
|
|
|
* * where `zero` is a zero-length plaintext, `rk` is the key to |
|
|
|
* be used by the responder to decrypt the messages sent by the |
|
|
|
* initiator, and `sk` is the key to be used by the responder |
|
|
|
* to encrypt messages to the initiator, |
|
|
|
* to encrypt messages to the initiator |
|
|
|
* |
|
|
|
* * This step generates the final encryption keys to be used for |
|
|
|
* sending and receiving messages for the duration of the |
|
|
|
* session. |
|
|
|
* * The final encryption keys to be used for sending and |
|
|
|
* receiving messages for the duration of the session are |
|
|
|
* generated. |
|
|
|
*/ |
|
|
|
if (h->side == RESPONDER) |
|
|
|
hkdf_two_keys(&cs.rk, &cs.sk, &h->ck, NULL, 0); |
|
|
@ -428,11 +427,11 @@ static struct handshake *new_handshake(const tal_t *ctx, |
|
|
|
* into the handshake digest: |
|
|
|
* |
|
|
|
* * The initiating node mixes in the responding node's static public |
|
|
|
* key serialized in Bitcoin's DER compressed format: |
|
|
|
* key serialized in Bitcoin's DER-compressed format: |
|
|
|
* * `h = SHA-256(h || rs.pub.serializeCompressed())` |
|
|
|
* |
|
|
|
* * The responding node mixes in their local static public key |
|
|
|
* serialized in Bitcoin's DER compressed format: |
|
|
|
* serialized in Bitcoin's DER-compressed format: |
|
|
|
* * `h = SHA-256(h || ls.pub.serializeCompressed())` |
|
|
|
*/ |
|
|
|
sha_mix_in_key(&handshake->h, responder_id); |
|
|
@ -451,8 +450,8 @@ static struct io_plan *act_three_initiator(struct io_conn *conn, |
|
|
|
SUPERVERBOSE("Initiator: Act 3"); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* * `c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())` |
|
|
|
* * where `s` is the static public key of the initiator. |
|
|
|
* 1. `c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())` |
|
|
|
* * where `s` is the static public key of the initiator |
|
|
|
*/ |
|
|
|
secp256k1_ec_pubkey_serialize(secp256k1_ctx, spub, &len, |
|
|
|
&h->my_id.pubkey, |
|
|
@ -464,14 +463,14 @@ static struct io_plan *act_three_initiator(struct io_conn *conn, |
|
|
|
h->act3.ciphertext, sizeof(h->act3.ciphertext))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* * `h = SHA-256(h || c)` |
|
|
|
* 2. `h = SHA-256(h || c)` |
|
|
|
*/ |
|
|
|
sha_mix_in(&h->h, h->act3.ciphertext, sizeof(h->act3.ciphertext)); |
|
|
|
SUPERVERBOSE("# h=0x%s", tal_hexstr(tmpctx, &h->h, sizeof(h->h))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ss = ECDH(re, s.priv)` |
|
|
|
* 3. `ss = ECDH(re, s.priv)` |
|
|
|
* * where `re` is the ephemeral public key of the responder. |
|
|
|
* |
|
|
|
*/ |
|
|
@ -482,8 +481,9 @@ static struct io_plan *act_three_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ck, temp_k3 = HKDF(ck, ss)` |
|
|
|
* * Mix the final intermediate shared secret into the running chaining key. |
|
|
|
* 4. `ck, temp_k3 = HKDF(ck, ss)` |
|
|
|
* * The final intermediate shared secret is mixed into the running |
|
|
|
* chaining key. |
|
|
|
*/ |
|
|
|
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss, sizeof(h->ss)); |
|
|
|
SUPERVERBOSE("# ck,temp_k3=0x%s,0x%s", |
|
|
@ -492,7 +492,7 @@ static struct io_plan *act_three_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `t = encryptWithAD(temp_k3, 0, h, zero)` |
|
|
|
* 5. `t = encryptWithAD(temp_k3, 0, h, zero)` |
|
|
|
* * where `zero` is a zero-length plaintext |
|
|
|
* |
|
|
|
*/ |
|
|
@ -503,7 +503,7 @@ static struct io_plan *act_three_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * Send `m = 0 || c || t` over the network buffer. |
|
|
|
* 8. Send `m = 0 || c || t` over the network buffer. |
|
|
|
* |
|
|
|
*/ |
|
|
|
h->act3.v = 0; |
|
|
@ -519,7 +519,7 @@ static struct io_plan *act_two_initiator2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * If `v` is an unrecognized handshake version, then the responder |
|
|
|
* 3. If `v` is an unrecognized handshake version, then the responder |
|
|
|
* MUST abort the connection attempt. |
|
|
|
*/ |
|
|
|
if (h->act2.v != 0) |
|
|
@ -540,14 +540,15 @@ static struct io_plan *act_two_initiator2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || re.serializeCompressed())` |
|
|
|
* 4. `h = SHA-256(h || re.serializeCompressed())` |
|
|
|
*/ |
|
|
|
sha_mix_in_key(&h->h, &h->re); |
|
|
|
SUPERVERBOSE("# h=0x%s", tal_hexstr(tmpctx, &h->h, sizeof(h->h))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ss = ECDH(re, e.priv)` |
|
|
|
* 5. `ss = ECDH(re, e.priv)` |
|
|
|
* * where `re` is the responder's ephemeral public key |
|
|
|
*/ |
|
|
|
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &h->re.pubkey, |
|
|
|
h->e.priv.secret.data)) |
|
|
@ -557,9 +558,9 @@ static struct io_plan *act_two_initiator2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ck, temp_k2 = HKDF(ck, ss)` |
|
|
|
* * This phase generates a new temporary encryption key |
|
|
|
* which is used to generate the authenticating MAC. |
|
|
|
* 6. `ck, temp_k2 = HKDF(ck, ss)` |
|
|
|
* * A new temporary encryption key is generated, which is |
|
|
|
* used to generate the authenticating MAC. |
|
|
|
*/ |
|
|
|
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss, sizeof(h->ss)); |
|
|
|
SUPERVERBOSE("# ck,temp_k2=0x%s,0x%s", |
|
|
@ -568,7 +569,7 @@ static struct io_plan *act_two_initiator2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `p = decryptWithAD(temp_k2, 0, h, c)` |
|
|
|
* 7. `p = decryptWithAD(temp_k2, 0, h, c)` |
|
|
|
* * If the MAC check in this operation fails, then the initiator |
|
|
|
* MUST terminate the connection without any further messages. |
|
|
|
*/ |
|
|
@ -578,9 +579,10 @@ static struct io_plan *act_two_initiator2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || c)` |
|
|
|
* * Mix the received ciphertext into the handshake digest. This |
|
|
|
* step serves to ensure the payload wasn't modified by a MiTM. |
|
|
|
* 8. `h = SHA-256(h || c)` |
|
|
|
* * The received ciphertext is mixed into the handshake digest. |
|
|
|
* This step serves to ensure the payload wasn't modified by a |
|
|
|
* MITM. |
|
|
|
*/ |
|
|
|
sha_mix_in(&h->h, h->act2.tag, sizeof(h->act2.tag)); |
|
|
|
SUPERVERBOSE("# h=0x%s", tal_hexstr(tmpctx, &h->h, sizeof(h->h))); |
|
|
@ -595,13 +597,11 @@ static struct io_plan *act_two_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * Read _exactly_ `50-bytes` from the network buffer. |
|
|
|
* 1. Read _exactly_ 50 bytes from the network buffer. |
|
|
|
* |
|
|
|
* * Parse out the read message (`m`) into `v = m[0]`, `re = m[1:33]` |
|
|
|
* and `c = m[34:]` |
|
|
|
* * where `m[0]` is the _first_ byte of `m`, `m[1:33]` are the |
|
|
|
* next `33` bytes of `m` and `m[34:]` is the last 16 bytes of |
|
|
|
* `m` |
|
|
|
* 2. Parse the read message (`m`) into `v`, `re` and `c`: |
|
|
|
* * where `v` is the _first_ byte of `m`, `re` is the next 33 |
|
|
|
* bytes of `m`, and `c` is the last 16 bytes of `m`. |
|
|
|
*/ |
|
|
|
return io_read(conn, &h->act2, ACT_TWO_SIZE, act_two_initiator2, h); |
|
|
|
} |
|
|
@ -617,7 +617,7 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
* |
|
|
|
* **Sender Actions:** |
|
|
|
* |
|
|
|
* * `e = generateKey()` |
|
|
|
* 1. `e = generateKey()` |
|
|
|
*/ |
|
|
|
h->e = generate_key(); |
|
|
|
SUPERVERBOSE("e.priv: 0x%s", |
|
|
@ -627,8 +627,8 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || e.pub.serializeCompressed())` |
|
|
|
* * The newly generated ephemeral key is accumulated into our |
|
|
|
* 2. `h = SHA-256(h || e.pub.serializeCompressed())` |
|
|
|
* * The newly generated ephemeral key is accumulated into the |
|
|
|
* running handshake digest. |
|
|
|
*/ |
|
|
|
sha_mix_in_key(&h->h, &h->e.pub); |
|
|
@ -636,9 +636,9 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ss = ECDH(rs, e.priv)` |
|
|
|
* * The initiator performs a `ECDH` between its newly generated |
|
|
|
* ephemeral key with the remote node's static public key. |
|
|
|
* 3. `ss = ECDH(rs, e.priv)` |
|
|
|
* * The initiator performs an ECDH between its newly generated |
|
|
|
* ephemeral key and the remote node's static public key. |
|
|
|
*/ |
|
|
|
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, |
|
|
|
&h->their_id.pubkey, h->e.priv.secret.data)) |
|
|
@ -648,9 +648,9 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ck, temp_k1 = HKDF(ck, ss)` |
|
|
|
* * This phase generates a new temporary encryption key |
|
|
|
* which is used to generate the authenticating MAC. |
|
|
|
* 4. `ck, temp_k1 = HKDF(ck, ss)` |
|
|
|
* * A new temporary encryption key is generated, which is |
|
|
|
* used to generate the authenticating MAC. |
|
|
|
*/ |
|
|
|
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss, sizeof(h->ss)); |
|
|
|
SUPERVERBOSE("# ck,temp_k1=0x%s,0x%s", |
|
|
@ -658,8 +658,7 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
tal_hexstr(tmpctx, &h->temp_k, sizeof(h->temp_k))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `c = encryptWithAD(temp_k1, 0, h, zero)` |
|
|
|
* 5. `c = encryptWithAD(temp_k1, 0, h, zero)` |
|
|
|
* * where `zero` is a zero-length plaintext |
|
|
|
*/ |
|
|
|
encrypt_ad(&h->temp_k, 0, &h->h, sizeof(h->h), NULL, 0, |
|
|
@ -668,8 +667,7 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
tal_hexstr(tmpctx, h->act1.tag, sizeof(h->act1.tag))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || c)` |
|
|
|
* 6. `h = SHA-256(h || c)` |
|
|
|
* * Finally, the generated ciphertext is accumulated into the |
|
|
|
* authenticating handshake digest. |
|
|
|
*/ |
|
|
@ -678,7 +676,7 @@ static struct io_plan *act_one_initiator(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * Send `m = 0 || e.pub.serializeCompressed() || c` to the responder over the network buffer. |
|
|
|
* 7. Send `m = 0 || e.pub.serializeCompressed() || c` to the responder over the network buffer. |
|
|
|
*/ |
|
|
|
h->act1.v = 0; |
|
|
|
len = sizeof(h->act1.pubkey); |
|
|
@ -700,22 +698,24 @@ static struct io_plan *act_three_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * Parse out the read message (`m`) into `v = m[0]`, `c = m[1:49]` and `t = m[50:]` |
|
|
|
* 2. Parse the read message (`m`) into `v`, `c` and `t`: |
|
|
|
* * where `v` is the _first_ byte of `m`, `c` is the next 49 |
|
|
|
* bytes of `m`, and `t` is the last 16 bytes of `m`. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * If `v` is an unrecognized handshake version, then the responder MUST |
|
|
|
* abort the connection attempt. |
|
|
|
* 3. If `v` is an unrecognized handshake version, then the responder |
|
|
|
* MUST abort the connection attempt. |
|
|
|
*/ |
|
|
|
if (h->act3.v != 0) |
|
|
|
return handshake_failed(conn, h); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `rs = decryptWithAD(temp_k2, 1, h, c)` |
|
|
|
* * At this point, the responder has recovered the static public key of the |
|
|
|
* initiator. |
|
|
|
* 4. `rs = decryptWithAD(temp_k2, 1, h, c)` |
|
|
|
* * At this point, the responder has recovered the static public |
|
|
|
* key of the initiator. |
|
|
|
*/ |
|
|
|
if (!decrypt(&h->temp_k, 1, &h->h, sizeof(h->h), |
|
|
|
h->act3.ciphertext, sizeof(h->act3.ciphertext), |
|
|
@ -730,7 +730,7 @@ static struct io_plan *act_three_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || c)` |
|
|
|
* 5. `h = SHA-256(h || c)` |
|
|
|
* |
|
|
|
*/ |
|
|
|
sha_mix_in(&h->h, h->act3.ciphertext, sizeof(h->act3.ciphertext)); |
|
|
@ -738,7 +738,7 @@ static struct io_plan *act_three_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ss = ECDH(rs, e.priv)` |
|
|
|
* 6. `ss = ECDH(rs, e.priv)` |
|
|
|
* * where `e` is the responder's original ephemeral key |
|
|
|
*/ |
|
|
|
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &h->their_id.pubkey, |
|
|
@ -748,7 +748,7 @@ static struct io_plan *act_three_responder2(struct io_conn *conn, |
|
|
|
SUPERVERBOSE("# ss=0x%s", tal_hexstr(tmpctx, &h->ss, sizeof(h->ss))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* * `ck, temp_k3 = HKDF(ck, ss)` |
|
|
|
* 7. `ck, temp_k3 = HKDF(ck, ss)` |
|
|
|
*/ |
|
|
|
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss, sizeof(h->ss)); |
|
|
|
SUPERVERBOSE("# ck,temp_k3=0x%s,0x%s", |
|
|
@ -756,9 +756,9 @@ static struct io_plan *act_three_responder2(struct io_conn *conn, |
|
|
|
tal_hexstr(tmpctx, &h->temp_k, sizeof(h->temp_k))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* * `p = decryptWithAD(temp_k3, 0, h, t)` |
|
|
|
* * If the MAC check in this operation fails, then the responder MUST |
|
|
|
* terminate the connection without any further messages. |
|
|
|
* 8. `p = decryptWithAD(temp_k3, 0, h, t)` |
|
|
|
* * If the MAC check in this operation fails, then the responder |
|
|
|
* MUST terminate the connection without any further messages. |
|
|
|
* |
|
|
|
*/ |
|
|
|
if (!decrypt(&h->temp_k, 0, &h->h, sizeof(h->h), |
|
|
@ -778,7 +778,7 @@ static struct io_plan *act_three_responder(struct io_conn *conn, |
|
|
|
* |
|
|
|
* **Receiver Actions:** |
|
|
|
* |
|
|
|
* * Read _exactly_ `66-bytes` from the network buffer. |
|
|
|
* 1. Read _exactly_ 66 bytes from the network buffer. |
|
|
|
*/ |
|
|
|
return io_read(conn, &h->act3, ACT_THREE_SIZE, act_three_responder2, h); |
|
|
|
} |
|
|
@ -794,7 +794,7 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
* |
|
|
|
* **Sender Actions:** |
|
|
|
* |
|
|
|
* * `e = generateKey()` |
|
|
|
* 1. `e = generateKey()` |
|
|
|
*/ |
|
|
|
h->e = generate_key(); |
|
|
|
SUPERVERBOSE("# e.pub=0x%s e.priv=0x%s", |
|
|
@ -803,8 +803,8 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || e.pub.serializeCompressed())` |
|
|
|
* * The newly generated ephemeral key is accumulated into our |
|
|
|
* 2. `h = SHA-256(h || e.pub.serializeCompressed())` |
|
|
|
* * The newly generated ephemeral key is accumulated into the |
|
|
|
* running handshake digest. |
|
|
|
*/ |
|
|
|
sha_mix_in_key(&h->h, &h->e.pub); |
|
|
@ -812,9 +812,9 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ss = ECDH(re, e.priv)` |
|
|
|
* * where `re` is the ephemeral key of the initiator which was |
|
|
|
* received during `ActOne`. |
|
|
|
* 3. `ss = ECDH(re, e.priv)` |
|
|
|
* * where `re` is the ephemeral key of the initiator, which was |
|
|
|
* received during Act One |
|
|
|
*/ |
|
|
|
if (!secp256k1_ecdh(secp256k1_ctx, h->ss.data, &h->re.pubkey, |
|
|
|
h->e.priv.secret.data)) |
|
|
@ -823,9 +823,9 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ck, temp_k2 = HKDF(ck, ss)` |
|
|
|
* * This phase generates a new temporary encryption key |
|
|
|
* which is used to generate the authenticating MAC. |
|
|
|
* 4. `ck, temp_k2 = HKDF(ck, ss)` |
|
|
|
* * A new temporary encryption key is generated, which is |
|
|
|
* used to generate the authenticating MAC. |
|
|
|
*/ |
|
|
|
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss, sizeof(h->ss)); |
|
|
|
SUPERVERBOSE("# ck,temp_k2=0x%s,0x%s", |
|
|
@ -834,7 +834,7 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `c = encryptWithAD(temp_k2, 0, h, zero)` |
|
|
|
* 5. `c = encryptWithAD(temp_k2, 0, h, zero)` |
|
|
|
* * where `zero` is a zero-length plaintext |
|
|
|
*/ |
|
|
|
encrypt_ad(&h->temp_k, 0, &h->h, sizeof(h->h), NULL, 0, |
|
|
@ -843,7 +843,7 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || c)` |
|
|
|
* 6. `h = SHA-256(h || c)` |
|
|
|
* * Finally, the generated ciphertext is accumulated into the |
|
|
|
* authenticating handshake digest. |
|
|
|
*/ |
|
|
@ -852,7 +852,7 @@ static struct io_plan *act_two_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * Send `m = 0 || e.pub.serializeCompressed() || c` to the initiator over the network buffer. |
|
|
|
* 7. Send `m = 0 || e.pub.serializeCompressed() || c` to the initiator over the network buffer. |
|
|
|
*/ |
|
|
|
h->act2.v = 0; |
|
|
|
len = sizeof(h->act2.pubkey); |
|
|
@ -871,7 +871,7 @@ static struct io_plan *act_one_responder2(struct io_conn *conn, |
|
|
|
{ |
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * If `v` is an unrecognized handshake version, then the responder |
|
|
|
* 3. If `v` is an unrecognized handshake version, then the responder |
|
|
|
* MUST abort the connection attempt. |
|
|
|
*/ |
|
|
|
if (h->act1.v != 0) |
|
|
@ -891,17 +891,17 @@ static struct io_plan *act_one_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || re.serializeCompressed())` |
|
|
|
* * Accumulate the initiator's ephemeral key into the |
|
|
|
* authenticating handshake digest. |
|
|
|
* 4. `h = SHA-256(h || re.serializeCompressed())` |
|
|
|
* * The responder accumulates the initiator's ephemeral key into the |
|
|
|
* authenticating handshake digest. |
|
|
|
*/ |
|
|
|
sha_mix_in_key(&h->h, &h->re); |
|
|
|
SUPERVERBOSE("# h=0x%s", tal_hexstr(tmpctx, &h->h, sizeof(h->h))); |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* * `ss = ECDH(re, s.priv)` |
|
|
|
* * The responder performs an `ECDH` between its static public |
|
|
|
* key and the initiator's ephemeral public key. |
|
|
|
* 5. `ss = ECDH(re, s.priv)` |
|
|
|
* * The responder performs an ECDH between its static private key and |
|
|
|
* the initiator's ephemeral public key. |
|
|
|
*/ |
|
|
|
if (!hsm_do_ecdh(&h->ss, &h->re)) |
|
|
|
return handshake_failed(conn, h); |
|
|
@ -910,10 +910,9 @@ static struct io_plan *act_one_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `ck, temp_k1 = HKDF(ck, ss)` |
|
|
|
* * This phase generates a new temporary encryption key |
|
|
|
* which will be used to shortly check the |
|
|
|
* authenticating MAC. |
|
|
|
* 6. `ck, temp_k1 = HKDF(ck, ss)` |
|
|
|
* * A new temporary encryption key is generated, which will |
|
|
|
* shortly be used to check the authenticating MAC. |
|
|
|
*/ |
|
|
|
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss, sizeof(h->ss)); |
|
|
|
SUPERVERBOSE("# ck,temp_k1=0x%s,0x%s", |
|
|
@ -922,10 +921,10 @@ static struct io_plan *act_one_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `p = decryptWithAD(temp_k1, 0, h, c)` |
|
|
|
* 7. `p = decryptWithAD(temp_k1, 0, h, c)` |
|
|
|
* * If the MAC check in this operation fails, then the initiator |
|
|
|
* does _not_ know our static public key. If so, then the |
|
|
|
* responder MUST terminate the connection without any further |
|
|
|
* does _not_ know the responder's static public key. If so, then |
|
|
|
* the responder MUST terminate the connection without any further |
|
|
|
* messages. |
|
|
|
*/ |
|
|
|
if (!decrypt(&h->temp_k, 0, &h->h, sizeof(h->h), |
|
|
@ -934,9 +933,10 @@ static struct io_plan *act_one_responder2(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * `h = SHA-256(h || c)` |
|
|
|
* * Mix the received ciphertext into the handshake digest. This |
|
|
|
* step serves to ensure the payload wasn't modified by a MiTM. |
|
|
|
* 8. `h = SHA-256(h || c)` |
|
|
|
* * The received ciphertext is mixed into the handshake digest. |
|
|
|
* This step serves to ensure the payload wasn't modified by a |
|
|
|
* MITM. |
|
|
|
*/ |
|
|
|
sha_mix_in(&h->h, h->act1.tag, sizeof(h->act1.tag)); |
|
|
|
SUPERVERBOSE("# h=0x%s", tal_hexstr(tmpctx, &h->h, sizeof(h->h))); |
|
|
@ -952,13 +952,11 @@ static struct io_plan *act_one_responder(struct io_conn *conn, |
|
|
|
|
|
|
|
/* BOLT #8:
|
|
|
|
* |
|
|
|
* * Read _exactly_ `50-bytes` from the network buffer. |
|
|
|
* 1. Read _exactly_ 50 bytes from the network buffer. |
|
|
|
* |
|
|
|
* * Parse out the read message (`m`) into `v = m[0]`, `re = |
|
|
|
* m[1:33]` and `c = m[34:]` |
|
|
|
* * where `m[0]` is the _first_ byte of `m`, `m[1:33]` are the |
|
|
|
* next `33` bytes of `m` and `m[34:]` is the last 16 bytes of |
|
|
|
* `m` |
|
|
|
* 2. Parse the read message (`m`) into `v`, `re` and `c`: |
|
|
|
* * where `v` is the _first_ byte of `m`, `re` is the next 33 |
|
|
|
* bytes of `m`, and `c` is the last 16 bytes of `m`. |
|
|
|
*/ |
|
|
|
return io_read(conn, &h->act1, ACT_ONE_SIZE, act_one_responder2, h); |
|
|
|
} |
|
|
|