diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index d7bc77a04..935534b61 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -763,34 +763,6 @@ static struct io_plan *init_hsm(struct io_conn *conn, &bolt12))); } -/*~ The client has asked us to extract the shared secret from an EC Diffie - * Hellman token. This doesn't leak any information, but requires the private - * key, so the hsmd performs it. It's used to set up an encryption key for the - * connection handshaking (BOLT #8) and for the onion wrapping (BOLT #4). */ -static struct io_plan *handle_ecdh(struct io_conn *conn, - struct client *c, - const u8 *msg_in) -{ - struct privkey privkey; - struct pubkey point; - struct secret ss; - - if (!fromwire_hsmd_ecdh_req(msg_in, &point)) - return bad_req(conn, c, msg_in); - - /*~ We simply use the secp256k1_ecdh function: if privkey.secret.data is invalid, - * we kill them for bad randomness (~1 in 2^127 if privkey.secret.data is random) */ - node_key(&privkey, NULL); - if (secp256k1_ecdh(secp256k1_ctx, ss.data, &point.pubkey, - privkey.secret.data, NULL, NULL) != 1) { - return bad_req_fmt(conn, c, msg_in, "secp256k1_ecdh fail"); - } - - /*~ In the normal case, we return the shared secret, and then read - * the next msg. */ - return req_reply(conn, c, take(towire_hsmd_ecdh_resp(NULL, &ss))); -} - /*~ The specific routine to sign the channel_announcement message. This is * defined in BOLT #7, and requires *two* signatures: one from this node's key * (to prove it's from us), and one from the bitcoin key used to create the @@ -1785,9 +1757,6 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY: return handle_get_output_scriptpubkey(conn, c, c->msg_in); - case WIRE_HSMD_ECDH_REQ: - return handle_ecdh(conn, c, c->msg_in); - case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ: return handle_cannouncement_sig(conn, c, c->msg_in); @@ -1835,6 +1804,8 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) case WIRE_HSMD_SIGN_INVOICE: case WIRE_HSMD_SIGN_MESSAGE: case WIRE_HSMD_SIGN_BOLT12: + case WIRE_HSMD_ECDH_REQ: + /* Hand off to libhsmd for processing */ return req_reply(conn, c, take(hsmd_handle_client_message( diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index 231c7b028..a834daf1e 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -437,6 +437,33 @@ static u8 *handle_get_channel_basepoints(struct hsmd_client *c, &funding_pubkey); } +/*~ The client has asked us to extract the shared secret from an EC Diffie + * Hellman token. This doesn't leak any information, but requires the private + * key, so the hsmd performs it. It's used to set up an encryption key for the + * connection handshaking (BOLT #8) and for the onion wrapping (BOLT #4). */ +static u8 *handle_ecdh(struct hsmd_client *c, const u8 *msg_in) +{ + struct privkey privkey; + struct pubkey point; + struct secret ss; + + if (!fromwire_hsmd_ecdh_req(msg_in, &point)) + return hsmd_status_malformed_request(c, msg_in); + + /*~ We simply use the secp256k1_ecdh function: if privkey.secret.data is invalid, + * we kill them for bad randomness (~1 in 2^127 if privkey.secret.data is random) */ + node_key(&privkey, NULL); + if (secp256k1_ecdh(secp256k1_ctx, ss.data, &point.pubkey, + privkey.secret.data, NULL, NULL) != 1) { + return hsmd_status_bad_request_fmt(c, msg_in, + "secp256k1_ecdh fail"); + } + + /*~ In the normal case, we return the shared secret, and then read + * the next msg. */ + return towire_hsmd_ecdh_resp(NULL, &ss); +} + u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, const u8 *msg) { @@ -464,7 +491,6 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, case WIRE_HSMD_INIT: case WIRE_HSMD_CLIENT_HSMFD: case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY: - case WIRE_HSMD_ECDH_REQ: case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ: case WIRE_HSMD_CUPDATE_SIG_REQ: case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REQ: @@ -482,6 +508,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, /* Not implemented yet. Should not have been passed here yet. */ return hsmd_status_bad_request_fmt(client, msg, "Not implemented yet."); + case WIRE_HSMD_ECDH_REQ: + return handle_ecdh(client, msg); case WIRE_HSMD_SIGN_INVOICE: return handle_sign_invoice(client, msg); case WIRE_HSMD_SIGN_BOLT12: