#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void hkdf_two_keys(struct secret *out1, struct secret *out2, const struct secret *in1, const struct secret *in2) { /* 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` * of cryptographic randomness using the extract-and-expand * component of the `HKDF`. */ struct secret okm[2]; BUILD_ASSERT(sizeof(okm) == 64); hkdf_sha256(okm, sizeof(okm), in1, sizeof(*in1), in2, sizeof(*in2), NULL, 0); *out1 = okm[0]; *out2 = okm[1]; } static void maybe_rotate_key(u64 *n, struct secret *k, struct secret *ck) { struct secret new_k, new_ck; /* BOLT #8: * * A key is to be rotated after a party sends or decrypts * `1000` messages with it. This can be properly accounted * for by rotating the key once the nonce dedicated to it * exceeds `1000`. */ if (*n != 1000) return; /* BOLT #8: * * Key rotation for a key `k` is performed according to the following: * * * Let `ck` be the chaining key obtained at the end of `Act Three`. * * `ck', k' = HKDF(ck, k)` * * Reset the nonce for the key to `n = 0`. * * `k = k'` * * `ck = ck'` */ hkdf_two_keys(&new_ck, &new_k, ck, k); #ifdef SUPERVERBOSE status_trace("# 0x%s, 0x%s = HKDF(0x%s, 0x%s)", tal_hexstr(trc, &new_ck, sizeof(new_ck)), tal_hexstr(trc, &new_k, sizeof(new_k)), tal_hexstr(trc, ck, sizeof(*ck)), tal_hexstr(trc, k, sizeof(*k))); #endif *ck = new_ck; *k = new_k; *n = 0; } static void le64_nonce(unsigned char *npub, u64 nonce) { /* BOLT #8: * * ...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). */ le64 le_nonce = cpu_to_le64(nonce); const size_t zerolen = crypto_aead_chacha20poly1305_ietf_NPUBBYTES - sizeof(le_nonce); BUILD_ASSERT(crypto_aead_chacha20poly1305_ietf_NPUBBYTES >= sizeof(le_nonce)); /* First part is 0, followed by nonce. */ memset(npub, 0, zerolen); memcpy(npub + zerolen, &le_nonce, sizeof(le_nonce)); } u8 *cryptomsg_decrypt_body(const tal_t *ctx, struct crypto_state *cs, const u8 *in) { unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; unsigned long long mlen; size_t inlen = tal_count(in); u8 *decrypted; if (inlen < 16) return NULL; decrypted = tal_arr(ctx, u8, inlen - 16); le64_nonce(npub, cs->rn++); /* BOLT #8: * * * Decrypt `c` using `ChaCha20-Poly1305`, `rn`, and `rk` to * obtain decrypted plaintext packet `p`. * * * The nonce `rn` MUST be incremented after this step. */ if (crypto_aead_chacha20poly1305_ietf_decrypt(decrypted, &mlen, NULL, memcheck(in, inlen), inlen, NULL, 0, npub, cs->rk.data) != 0) { /* FIXME: Report error! */ return tal_free(decrypted); } assert(mlen == tal_count(decrypted)); maybe_rotate_key(&cs->rn, &cs->rk, &cs->r_ck); return decrypted; } static struct io_plan *peer_decrypt_body(struct io_conn *conn, struct peer_crypto_state *pcs) { struct io_plan *plan; u8 *in, *decrypted; pcs->reading_body = false; decrypted = cryptomsg_decrypt_body(pcs->in, &pcs->cs, pcs->in); if (!decrypted) return io_close(conn); status_peer_io(LOG_IO_IN, decrypted); /* BOLT #1: * * A node MUST ignore a received message of unknown type, if that type * is odd. */ if (unlikely(is_unknown_msg_discardable(decrypted))) { pcs->in = tal_free(pcs->in); return peer_read_message(conn, pcs, pcs->next_in); } /* Steal cs->in: we free it after, and decrypted too unless * they steal but be careful not to touch anything after * next_in (could free itself) */ in = tal_steal(NULL, pcs->in); pcs->in = NULL; plan = pcs->next_in(conn, pcs->peer, decrypted); tal_free(in); return plan; } bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp) { unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; unsigned long long mlen; be16 len; le64_nonce(npub, cs->rn++); /* BOLT #8: * * * Let the encrypted length prefix be known as `lc` * * * Decrypt `lc` using `ChaCha20-Poly1305`, `rn`, and `rk` to * obtain size of the encrypted packet `l`. * * A zero-length byte slice is to be passed as the AD * (associated data). * * The nonce `rn` MUST be incremented after this step. */ if (crypto_aead_chacha20poly1305_ietf_decrypt((unsigned char *)&len, &mlen, NULL, memcheck(hdr, 18), 18, NULL, 0, npub, cs->rk.data) != 0) { /* FIXME: Report error! */ return false; } assert(mlen == sizeof(len)); *lenp = be16_to_cpu(len); return true; } static struct io_plan *peer_decrypt_header(struct io_conn *conn, struct peer_crypto_state *pcs) { u16 len; if (!cryptomsg_decrypt_header(&pcs->cs, pcs->in, &len)) return io_close(conn); tal_free(pcs->in); pcs->reading_body = true; /* BOLT #8: * * * Read _exactly_ `l+16` bytes from the network buffer, let * the bytes be known as `c`. */ pcs->in = tal_arr(conn, u8, (u32)len + 16); return io_read(conn, pcs->in, tal_count(pcs->in), peer_decrypt_body, pcs); } struct io_plan *peer_read_message(struct io_conn *conn, struct peer_crypto_state *pcs, struct io_plan *(*next)(struct io_conn *, struct peer *, u8 *msg)) { assert(!pcs->in); /* BOLT #8: * * ### Decrypting Messages * * In order to decrypt the _next_ message in the network * stream, the following is done: * * * Read _exactly_ `18-bytes` from the network buffer. */ pcs->reading_body = false; pcs->in = tal_arr(conn, u8, 18); pcs->next_in = next; return io_read(conn, pcs->in, 18, peer_decrypt_header, pcs); } static struct io_plan *peer_write_done(struct io_conn *conn, struct peer_crypto_state *pcs) { pcs->out = tal_free(pcs->out); return pcs->next_out(conn, pcs->peer); } u8 *cryptomsg_encrypt_msg(const tal_t *ctx, struct crypto_state *cs, const u8 *msg TAKES) { unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES]; unsigned long long clen, mlen = tal_count(msg); be16 l; int ret; u8 *out; out = tal_arr(ctx, u8, sizeof(l) + 16 + mlen + 16); /* BOLT #8: * * In order to encrypt a lightning message (`m`), given a * sending key (`sk`), and a nonce (`sn`), the following is done: * * * * let `l = len(m)`, * where `len` obtains the length in bytes of the lightning message. * * * Serialize `l` into `2-bytes` encoded as a big-endian integer. */ l = cpu_to_be16(mlen); /* BOLT #8: * * * Encrypt `l` using `ChaChaPoly-1305`, `sn`, and `sk` to obtain `lc` * (`18-bytes`) * * The nonce `sn` is encoded as a 96-bit little-endian number. * As our decoded nonces a 64-bit, we encode the 96-bit nonce as * follows: 32-bits of leading zeroes followed by a 64-bit value. * * The nonce `sn` MUST be incremented after this step. * * A zero-length byte slice is to be passed as the AD */ le64_nonce(npub, cs->sn++); ret = crypto_aead_chacha20poly1305_ietf_encrypt(out, &clen, (unsigned char *) memcheck(&l, sizeof(l)), sizeof(l), NULL, 0, NULL, npub, cs->sk.data); assert(ret == 0); assert(clen == sizeof(l) + 16); #ifdef SUPERVERBOSE status_trace("# encrypt l: cleartext=0x%s, AD=NULL, sn=0x%s, sk=0x%s => 0x%s", tal_hexstr(trc, &l, sizeof(l)), tal_hexstr(trc, npub, sizeof(npub)), tal_hexstr(trc, &cs->sk, sizeof(cs->sk)), tal_hexstr(trc, out, clen)); #endif /* BOLT #8: * * * Finally encrypt the message itself (`m`) using the same * procedure used to encrypt the length prefix. Let * encrypted ciphertext be known as `c`. * * * The nonce `sn` MUST be incremented after this step. */ le64_nonce(npub, cs->sn++); ret = crypto_aead_chacha20poly1305_ietf_encrypt(out + clen, &clen, memcheck(msg, mlen), mlen, NULL, 0, NULL, npub, cs->sk.data); assert(ret == 0); assert(clen == mlen + 16); #ifdef SUPERVERBOSE status_trace("# encrypt m: cleartext=0x%s, AD=NULL, sn=0x%s, sk=0x%s => 0x%s", tal_hexstr(trc, msg, mlen), tal_hexstr(trc, npub, sizeof(npub)), tal_hexstr(trc, &cs->sk, sizeof(cs->sk)), tal_hexstr(trc, out + 18, clen)); #endif maybe_rotate_key(&cs->sn, &cs->sk, &cs->s_ck); if (taken(msg)) tal_free(msg); return out; } #if DEVELOPER static struct io_plan *peer_write_postclose(struct io_conn *conn, struct peer_crypto_state *pcs) { pcs->out = tal_free(pcs->out); dev_sabotage_fd(io_conn_fd(conn)); return pcs->next_out(conn, pcs->peer); } #endif struct io_plan *peer_write_message(struct io_conn *conn, struct peer_crypto_state *pcs, const u8 *msg, struct io_plan *(*next)(struct io_conn *, struct peer *)) { struct io_plan *(*post)(struct io_conn *, struct peer_crypto_state *); #if DEVELOPER int type = fromwire_peektype(msg); #endif assert(!pcs->out); /* Important: this doesn't take msg! */ status_peer_io(LOG_IO_OUT, msg); pcs->out = cryptomsg_encrypt_msg(conn, &pcs->cs, msg); pcs->next_out = next; post = peer_write_done; #if DEVELOPER switch (dev_disconnect(type)) { case DEV_DISCONNECT_BEFORE: dev_sabotage_fd(io_conn_fd(conn)); break; case DEV_DISCONNECT_DROPPKT: pcs->out = NULL; /* FALL THRU */ case DEV_DISCONNECT_AFTER: post = peer_write_postclose; break; case DEV_DISCONNECT_BLACKHOLE: dev_blackhole_fd(io_conn_fd(conn)); break; case DEV_DISCONNECT_NORMAL: break; } #endif /* DEVELOPER */ /* BOLT #8: * * Send `lc || c` over the network buffer. */ return io_write(conn, pcs->out, tal_count(pcs->out), post, pcs); } /* We read in two parts, so we might have started body. */ bool peer_in_started(const struct io_conn *conn, const struct peer_crypto_state *cs) { return io_plan_in_started(conn) || cs->reading_body; } void init_peer_crypto_state(struct peer *peer, struct peer_crypto_state *pcs) { pcs->peer = peer; pcs->out = pcs->in = NULL; pcs->reading_body = false; }