commit 7a5cf9f51c5d7c2f82dfd1de03efd8bae4580618
parent ba5e344f0adc2dd9cce774a970d64b27176b0b47
Author: William Casarin <jb55@jb55.com>
Date: Sun, 16 Jan 2022 08:48:09 -0800
handshake_success to initialize final crypto state
Diffstat:
4 files changed, 76 insertions(+), 25 deletions(-)
diff --git a/crypto.h b/crypto.h
@@ -0,0 +1,40 @@
+
+#ifndef LNSOCKET_CRYPTO_H
+#define LNSOCKET_CRYPTO_H
+
+#include <secp256k1.h>
+
+#define PUBKEY_CMPR_LEN 33
+
+struct secret {
+ u8 data[32];
+};
+
+struct node_id {
+ u8 k[PUBKEY_CMPR_LEN];
+};
+
+struct pubkey {
+ secp256k1_pubkey pubkey;
+};
+
+struct privkey {
+ struct secret secret;
+};
+
+struct keypair {
+ struct pubkey pub;
+ struct privkey priv;
+};
+
+struct crypto_state {
+ /* Received and sent nonces. */
+ u64 rn, sn;
+ /* Sending and receiving keys. */
+ struct secret sk, rk;
+ /* Chaining key for re-keying */
+ struct secret s_ck, r_ck;
+};
+
+
+#endif /* LNSOCKET_CRYPTO_H */
diff --git a/handshake.c b/handshake.c
@@ -218,6 +218,33 @@ static int decrypt(const struct secret *k, u64 nonce,
return 1;
}
+static int handshake_success(struct lnsocket *ln, struct handshake *h)
+{
+ struct crypto_state *cs = &ln->crypto_state;
+
+ /* BOLT #8:
+ *
+ * 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
+ *
+ * * 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);
+ else
+ hkdf_two_keys(&cs->sk, &cs->rk, &h->ck, NULL, 0);
+
+ cs->rn = cs->sn = 0;
+ cs->r_ck = cs->s_ck = h->ck;
+
+ return 1;
+}
+
static int act_three_initiator(struct lnsocket *ln, struct handshake *h)
{
u8 spub[PUBKEY_CMPR_LEN];
@@ -274,7 +301,7 @@ static int act_three_initiator(struct lnsocket *ln, struct handshake *h)
return note_error(&ln->errs, "handshake failed on initial send");
}
- return note_error(&ln->errs, "handshake success!\n");
+ return handshake_success(ln, h);
}
// act2: read the response to the message sent in act1
diff --git a/handshake.h b/handshake.h
@@ -24,44 +24,22 @@ THE SOFTWARE.
#include "typedefs.h"
#include "sha256.h"
+#include "crypto.h"
#include <netdb.h>
#include <sodium/crypto_aead_chacha20poly1305.h>
#include <secp256k1_extrakeys.h>
-#define PUBKEY_CMPR_LEN 33
-
#define ACT_ONE_SIZE 50
#define ACT_TWO_SIZE 50
#define ACT_THREE_SIZE 66
-struct node_id {
- u8 k[PUBKEY_CMPR_LEN];
-};
-
enum bolt8_side {
INITIATOR,
RESPONDER
};
-struct secret {
- u8 data[32];
-};
-
-struct pubkey {
- secp256k1_pubkey pubkey;
-};
-
-struct privkey {
- struct secret secret;
-};
-
-struct keypair {
- struct pubkey pub;
- struct privkey priv;
-};
-
/* BOLT #8:
*
* Act One is sent from initiator to responder. During Act One, the
diff --git a/lnsocket_internal.h b/lnsocket_internal.h
@@ -1,11 +1,17 @@
+#ifndef LNSOCKET_INTERNAL_H
+#define LNSOCKET_INTERNAL_H
+
+#include "crypto.h"
struct lnsocket {
const char *errors[8];
struct cursor mem;
struct errors errs;
- int socket;
int num_errors;
+ int socket;
struct keypair key;
+ struct crypto_state crypto_state;
secp256k1_context *secp;
};
+#endif /* LNSOCKET_INTERNAL_H */