* [PATCH BlueZ v2 0/3] Add possibility to use remote device keys
@ 2019-07-02 9:07 Michał Lowas-Rzechonek
2019-07-02 9:07 ` [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Michał Lowas-Rzechonek @ 2019-07-02 9:07 UTC (permalink / raw)
To: linux-bluetooth
This patchset adds support for sending and receiving messages encrypted
with remote device keys.
This plugs a 'leak' in the API where it was possible to exchange such
messages using Send()/MessageReceived() API by using 0x7fff app key
index.
In order to allow the application to receive responses from a local
Config Server model, messages originating from a local node and
encrypted using local device key are also forwarded to the application
via D-Bus (assuming they were not handled by one of internal models).
Michał Lowas-Rzechonek (3):
mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE
mesh: Implement DevKeySend() method on Node interface
mesh: Handle messages encrypted with a remote device key
mesh/cfgmod-server.c | 15 +++----
mesh/model.c | 93 +++++++++++++++++++++++++++++++++++++-------
mesh/net.h | 10 +++--
mesh/node.c | 59 +++++++++++++++++++++++++++-
4 files changed, 150 insertions(+), 27 deletions(-)
--
2.19.1
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE 2019-07-02 9:07 [PATCH BlueZ v2 0/3] Add possibility to use remote device keys Michał Lowas-Rzechonek @ 2019-07-02 9:07 ` Michał Lowas-Rzechonek 2019-07-02 18:15 ` Gix, Brian 2019-07-02 9:07 ` [PATCH BlueZ v2 2/3] mesh: Implement DevKeySend() method on Node interface Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 3/3] mesh: Handle messages encrypted with a remote device key Michał Lowas-Rzechonek 2 siblings, 1 reply; 5+ messages in thread From: Michał Lowas-Rzechonek @ 2019-07-02 9:07 UTC (permalink / raw) To: linux-bluetooth; +Cc: Inga Stotland, Brian Gix This is needed to distinguish incoming messages encrypted using a device key: if the key is local, the message can be forwarded to internal models. If the key is a known remote one, it will be forwarded to the application via DevKeyMessageReceived() API. --- mesh/cfgmod-server.c | 15 ++++++++------- mesh/model.c | 20 +++++++++++--------- mesh/net.h | 10 ++++++---- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c index 634ac006b..a849b5e99 100644 --- a/mesh/cfgmod-server.c +++ b/mesh/cfgmod-server.c @@ -69,7 +69,8 @@ static void send_pub_status(struct mesh_node *node, uint16_t src, uint16_t dst, n += 2; } - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, + msg, n); } static bool config_pub_get(struct mesh_node *node, uint16_t src, uint16_t dst, @@ -254,7 +255,7 @@ static void send_sub_status(struct mesh_node *node, uint16_t src, uint16_t dst, n += 2; } - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); } static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst, @@ -312,7 +313,7 @@ static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst, *msg_status = (uint8_t) status; - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); return true; } @@ -487,7 +488,7 @@ static void send_model_app_status(struct mesh_node *node, uint16_t src, l_put_le16(id, msg + n); n += 2; - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); } static void model_app_list(struct mesh_node *node, uint16_t src, uint16_t dst, @@ -540,7 +541,7 @@ static void model_app_list(struct mesh_node *node, uint16_t src, uint16_t dst, if (result >= 0) { *status = result; - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); } @@ -758,7 +759,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst, uint16_t interval; uint16_t n; - if (idx != APP_IDX_DEV) + if (idx != APP_IDX_DEV_LOCAL) return false; if (mesh_model_opcode_get(pkt, size, &opcode, &n)) { @@ -1259,7 +1260,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst, if (n) { /* print_packet("App Tx", long_msg ? long_msg : msg, n); */ mesh_model_send(node, unicast, src, - APP_IDX_DEV, DEFAULT_TTL, + APP_IDX_DEV_LOCAL, DEFAULT_TTL, long_msg ? long_msg : msg, n); } l_free(long_msg); diff --git a/mesh/model.c b/mesh/model.c index 7401dcecb..e09dbd364 100644 --- a/mesh/model.c +++ b/mesh/model.c @@ -306,7 +306,8 @@ static void forward_model(void *a, void *b) bool result; l_debug("model %8.8x with idx %3.3x", mod->id, fwd->idx); - if (fwd->idx != APP_IDX_DEV && !has_binding(mod->bindings, fwd->idx)) + + if (fwd->idx != APP_IDX_DEV_LOCAL && !has_binding(mod->bindings, fwd->idx)) return; dst = fwd->dst; @@ -356,15 +357,16 @@ static int dev_packet_decrypt(struct mesh_node *node, const uint8_t *data, uint16_t dst, uint8_t key_id, uint32_t seq, uint32_t iv_idx, uint8_t *out) { - const uint8_t *dev_key; + uint8_t dev_key[16]; + const uint8_t *key; - dev_key = node_get_device_key(node); - if (!dev_key) + key = node_get_device_key(node); + if (!key) return false; if (mesh_crypto_payload_decrypt(NULL, 0, data, size, szmict, src, - dst, key_id, seq, iv_idx, out, dev_key)) - return APP_IDX_DEV; + dst, key_id, seq, iv_idx, out, key)) + return APP_IDX_DEV_LOCAL; return -1; } @@ -952,7 +954,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target, if (IS_UNASSIGNED(target)) return false; - if (app_idx == APP_IDX_DEV) { + if (app_idx == APP_IDX_DEV_LOCAL) { key = node_get_device_key(node); if (!key) return false; @@ -1381,12 +1383,12 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx, if (ele_idx != PRIMARY_ELE_IDX) return NULL; - l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV)); + l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV_LOCAL)); return mod; } if (db_mod->id == CONFIG_CLI_MODEL) { - l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV)); + l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV_LOCAL)); return mod; } diff --git a/mesh/net.h b/mesh/net.h index f19024766..834712d8d 100644 --- a/mesh/net.h +++ b/mesh/net.h @@ -37,10 +37,12 @@ struct mesh_node; #define SEQ_MASK 0xffffff #define CREDFLAG_MASK 0x1000 -#define APP_IDX_MASK 0x0fff -#define APP_IDX_DEV 0x7fff -#define APP_IDX_ANY 0x8000 -#define APP_IDX_NET 0xffff + +#define APP_IDX_MASK 0x0fff +#define APP_IDX_DEV_REMOTE 0x6fff +#define APP_IDX_DEV_LOCAL 0x7fff +#define APP_IDX_ANY 0x8000 +#define APP_IDX_NET 0xffff #define NET_IDX_INVALID 0xffff #define NET_NID_INVALID 0xff -- 2.19.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE 2019-07-02 9:07 ` [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek @ 2019-07-02 18:15 ` Gix, Brian 0 siblings, 0 replies; 5+ messages in thread From: Gix, Brian @ 2019-07-02 18:15 UTC (permalink / raw) To: michal.lowas-rzechonek@silvair.com, linux-bluetooth@vger.kernel.org Cc: Stotland, Inga Hi Michał, This patch fails check patch, plus other issues: WARNING:LONG_LINE: line over 80 characters #79: FILE: mesh/model.c:310: + if (fwd->idx != APP_IDX_DEV_LOCAL && !has_binding(mod->bindings, fwd->idx)) WARNING:LONG_LINE: line over 80 characters #119: FILE: mesh/model.c:1386: + l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV_LOCAL)); WARNING:LONG_LINE: line over 80 characters #125: FILE: mesh/model.c:1391: + l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV_LOCAL)); total: 0 errors, 3 warnings, 125 lines checked On Tue, 2019-07-02 at 11:07 +0200, Michał Lowas-Rzechonek wrote: > This is needed to distinguish incoming messages encrypted using a device > key: if the key is local, the message can be forwarded to internal > models. If the key is a known remote one, it will be forwarded to the > application via DevKeyMessageReceived() API. > --- > mesh/cfgmod-server.c | 15 ++++++++------- > mesh/model.c | 20 +++++++++++--------- > mesh/net.h | 10 ++++++---- > 3 files changed, 25 insertions(+), 20 deletions(-) > > diff --git a/mesh/cfgmod-server.c b/mesh/cfgmod-server.c > index 634ac006b..a849b5e99 100644 > --- a/mesh/cfgmod-server.c > +++ b/mesh/cfgmod-server.c > @@ -69,7 +69,8 @@ static void send_pub_status(struct mesh_node *node, uint16_t src, uint16_t dst, > n += 2; > } > > - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); > + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, > + msg, n); > } > > static bool config_pub_get(struct mesh_node *node, uint16_t src, uint16_t dst, > @@ -254,7 +255,7 @@ static void send_sub_status(struct mesh_node *node, uint16_t src, uint16_t dst, > n += 2; > } > > - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); > + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); > } > > static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst, > @@ -312,7 +313,7 @@ static bool config_sub_get(struct mesh_node *node, uint16_t src, uint16_t dst, > > *msg_status = (uint8_t) status; > > - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); > + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); > return true; > } > > @@ -487,7 +488,7 @@ static void send_model_app_status(struct mesh_node *node, uint16_t src, > l_put_le16(id, msg + n); > n += 2; > > - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, msg, n); > + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, msg, n); > } > > static void model_app_list(struct mesh_node *node, uint16_t src, uint16_t dst, > @@ -540,7 +541,7 @@ static void model_app_list(struct mesh_node *node, uint16_t src, uint16_t dst, > > if (result >= 0) { > *status = result; > - mesh_model_send(node, dst, src, APP_IDX_DEV, DEFAULT_TTL, > + mesh_model_send(node, dst, src, APP_IDX_DEV_LOCAL, DEFAULT_TTL, > msg, n); > } > > @@ -758,7 +759,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst, > uint16_t interval; > uint16_t n; > > - if (idx != APP_IDX_DEV) > + if (idx != APP_IDX_DEV_LOCAL) > return false; > > if (mesh_model_opcode_get(pkt, size, &opcode, &n)) { > @@ -1259,7 +1260,7 @@ static bool cfg_srv_pkt(uint16_t src, uint32_t dst, > if (n) { > /* print_packet("App Tx", long_msg ? long_msg : msg, n); */ > mesh_model_send(node, unicast, src, > - APP_IDX_DEV, DEFAULT_TTL, > + APP_IDX_DEV_LOCAL, DEFAULT_TTL, > long_msg ? long_msg : msg, n); > } > l_free(long_msg); > diff --git a/mesh/model.c b/mesh/model.c > index 7401dcecb..e09dbd364 100644 > --- a/mesh/model.c > +++ b/mesh/model.c > @@ -306,7 +306,8 @@ static void forward_model(void *a, void *b) > bool result; > > l_debug("model %8.8x with idx %3.3x", mod->id, fwd->idx); > - if (fwd->idx != APP_IDX_DEV && !has_binding(mod->bindings, fwd->idx)) > + > + if (fwd->idx != APP_IDX_DEV_LOCAL && !has_binding(mod->bindings, fwd->idx)) > return; > > dst = fwd->dst; > @@ -356,15 +357,16 @@ static int dev_packet_decrypt(struct mesh_node *node, const uint8_t *data, > uint16_t dst, uint8_t key_id, uint32_t seq, > uint32_t iv_idx, uint8_t *out) > { > - const uint8_t *dev_key; > + uint8_t dev_key[16]; > + const uint8_t *key; You have renamed dev_key --> key, and no longer use dev_key that I can see here... which will cause it's own build warning: mesh/model.c: In function ‘dev_packet_decrypt’: mesh/model.c:360:10: error: unused variable ‘dev_key’ [-Werror=unused-variable] uint8_t dev_key[16]; ^~~~~~~ cc1: all warnings being treated as errors > > - dev_key = node_get_device_key(node); > - if (!dev_key) > + key = node_get_device_key(node); > + if (!key) > return false; > > if (mesh_crypto_payload_decrypt(NULL, 0, data, size, szmict, src, > - dst, key_id, seq, iv_idx, out, dev_key)) > - return APP_IDX_DEV; > + dst, key_id, seq, iv_idx, out, key)) > + return APP_IDX_DEV_LOCAL; > > return -1; > } > @@ -952,7 +954,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target, > if (IS_UNASSIGNED(target)) > return false; > > - if (app_idx == APP_IDX_DEV) { > + if (app_idx == APP_IDX_DEV_LOCAL) { > key = node_get_device_key(node); > if (!key) > return false; > @@ -1381,12 +1383,12 @@ struct mesh_model *mesh_model_setup(struct mesh_node *node, uint8_t ele_idx, > if (ele_idx != PRIMARY_ELE_IDX) > return NULL; > > - l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV)); > + l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV_LOCAL)); > return mod; > } > > if (db_mod->id == CONFIG_CLI_MODEL) { > - l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV)); > + l_queue_push_head(mod->bindings, L_UINT_TO_PTR(APP_IDX_DEV_LOCAL)); > return mod; > } > > diff --git a/mesh/net.h b/mesh/net.h > index f19024766..834712d8d 100644 > --- a/mesh/net.h > +++ b/mesh/net.h > @@ -37,10 +37,12 @@ struct mesh_node; > #define SEQ_MASK 0xffffff > > #define CREDFLAG_MASK 0x1000 > -#define APP_IDX_MASK 0x0fff > -#define APP_IDX_DEV 0x7fff > -#define APP_IDX_ANY 0x8000 > -#define APP_IDX_NET 0xffff > + > +#define APP_IDX_MASK 0x0fff > +#define APP_IDX_DEV_REMOTE 0x6fff > +#define APP_IDX_DEV_LOCAL 0x7fff > +#define APP_IDX_ANY 0x8000 > +#define APP_IDX_NET 0xffff Since this patch-set needs to be re-spun, Inga was hoping you could also remove the unused cruft APP_IDX_NET altogether... > > #define NET_IDX_INVALID 0xffff > #define NET_NID_INVALID 0xff ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH BlueZ v2 2/3] mesh: Implement DevKeySend() method on Node interface 2019-07-02 9:07 [PATCH BlueZ v2 0/3] Add possibility to use remote device keys Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek @ 2019-07-02 9:07 ` Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 3/3] mesh: Handle messages encrypted with a remote device key Michał Lowas-Rzechonek 2 siblings, 0 replies; 5+ messages in thread From: Michał Lowas-Rzechonek @ 2019-07-02 9:07 UTC (permalink / raw) To: linux-bluetooth; +Cc: Inga Stotland This patch implements D-Bus DevKeySend() method of org.bluez.mesh.Node1 interface, allowing the application to send messages encrypted using a known remote device key. At the moment the call ignores net_index argument and sends messages using the primary subnet. Also, it's no longer possible to use 'magic' key_index value 0x7fff (denoting local device key) when calling regular Send(). Applications should use DevKeySend() instead. --- mesh/model.c | 8 ++++++- mesh/node.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/mesh/model.c b/mesh/model.c index e09dbd364..0d44ea72e 100644 --- a/mesh/model.c +++ b/mesh/model.c @@ -941,6 +941,7 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target, const void *msg, uint16_t msg_len) { uint8_t key_id; + uint8_t dev_key[16]; const uint8_t *key; /* print_packet("Mod Tx", msg, msg_len); */ @@ -959,7 +960,12 @@ bool mesh_model_send(struct mesh_node *node, uint16_t src, uint16_t target, if (!key) return false; - l_debug("(%x)", app_idx); + key_id = APP_ID_DEV; + } else if (app_idx == APP_IDX_DEV_REMOTE) { + if (!keyring_get_remote_dev_key(node, target, dev_key)) + return false; + + key = dev_key; key_id = APP_ID_DEV; } else { key = appkey_get_key(node_get_net(node), app_idx, &key_id); diff --git a/mesh/node.c b/mesh/node.c index 9acf153d9..316b889e8 100644 --- a/mesh/node.c +++ b/mesh/node.c @@ -1959,7 +1959,11 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus, return dbus_error(msg, MESH_ERROR_INVALID_ARGS, "Incorrect data"); - if (!mesh_model_send(node, src, dst, app_idx, + if ((app_idx & APP_IDX_MASK) != app_idx) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, + "Invalid key_index"); + + if (!mesh_model_send(node, src, dst, app_idx & APP_IDX_MASK, mesh_net_get_default_ttl(node->net), data, len)) return dbus_error(msg, MESH_ERROR_FAILED, NULL); @@ -1969,6 +1973,53 @@ static struct l_dbus_message *send_call(struct l_dbus *dbus, return reply; } +static struct l_dbus_message *dev_key_send_call(struct l_dbus *dbus, + struct l_dbus_message *msg, + void *user_data) +{ + struct mesh_node *node = user_data; + const char *sender, *ele_path; + struct l_dbus_message_iter iter_data; + struct node_element *ele; + uint16_t dst, net_idx, src; + uint8_t *data; + uint32_t len; + struct l_dbus_message *reply; + + l_debug("DevKeySend"); + + sender = l_dbus_message_get_sender(msg); + + if (strcmp(sender, node->owner)) + return dbus_error(msg, MESH_ERROR_NOT_AUTHORIZED, NULL); + + if (!l_dbus_message_get_arguments(msg, "oqqay", &ele_path, &dst, + &net_idx, &iter_data)) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL); + + ele = l_queue_find(node->elements, match_element_path, ele_path); + if (!ele) + return dbus_error(msg, MESH_ERROR_NOT_FOUND, + "Element not found"); + + src = node_get_primary(node) + ele->idx; + + if (!l_dbus_message_iter_get_fixed_array(&iter_data, &data, &len) || + !len || len > MESH_MAX_ACCESS_PAYLOAD) + return dbus_error(msg, MESH_ERROR_INVALID_ARGS, + "Incorrect data"); + + /* TODO: use net_idx */ + if (!mesh_model_send(node, src, dst, APP_IDX_DEV_REMOTE, + mesh_net_get_default_ttl(node->net), data, len)) + return dbus_error(msg, MESH_ERROR_NOT_FOUND, NULL); + + reply = l_dbus_message_new_method_return(msg); + l_dbus_message_set_arguments(reply, ""); + + return reply; +} + static struct l_dbus_message *publish_call(struct l_dbus *dbus, struct l_dbus_message *msg, void *user_data) @@ -2074,7 +2125,11 @@ static void setup_node_interface(struct l_dbus_interface *iface) { l_dbus_interface_method(iface, "Send", 0, send_call, "", "oqqay", "element_path", "destination", - "key", "data"); + "key_index", "data"); + l_dbus_interface_method(iface, "DevKeySend", 0, dev_key_send_call, + "", "oqqay", "element_path", + "destination", "net_index", + "data"); l_dbus_interface_method(iface, "Publish", 0, publish_call, "", "oqay", "element_path", "model_id", "data"); l_dbus_interface_method(iface, "VendorPublish", 0, vendor_publish_call, -- 2.19.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH BlueZ v2 3/3] mesh: Handle messages encrypted with a remote device key 2019-07-02 9:07 [PATCH BlueZ v2 0/3] Add possibility to use remote device keys Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 2/3] mesh: Implement DevKeySend() method on Node interface Michał Lowas-Rzechonek @ 2019-07-02 9:07 ` Michał Lowas-Rzechonek 2 siblings, 0 replies; 5+ messages in thread From: Michał Lowas-Rzechonek @ 2019-07-02 9:07 UTC (permalink / raw) To: linux-bluetooth; +Cc: Inga Stotland, Jakub Witowski This adds ability to receive messages encrypted using known remote device key. Such a key must be added to the node's keyring using ImportRemoteNode() method of org.bluez.mesh.Management1 interface. Decrypted messages are then forwarded to the application using DevKeyMessageReceived() D-Bus API. Also, messages originating from a local node and encrypted using local device key are forwarde to the application as well, if they weren't handled by internal model. This allows e.g. receiving status messages from a local Config Server in the application. --- mesh/model.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/mesh/model.c b/mesh/model.c index 0d44ea72e..e9b8a8ce2 100644 --- a/mesh/model.c +++ b/mesh/model.c @@ -39,6 +39,7 @@ #include "mesh/dbus.h" #include "mesh/util.h" #include "mesh/model.h" +#include "mesh/keyring.h" /* Divide and round to ceiling (up) to calculate segment count */ #define CEILDIV(val, div) (((val) + (div) - 1) / (div)) @@ -368,6 +369,14 @@ static int dev_packet_decrypt(struct mesh_node *node, const uint8_t *data, dst, key_id, seq, iv_idx, out, key)) return APP_IDX_DEV_LOCAL; + if (!keyring_get_remote_dev_key(node, src, dev_key)) + return -1; + + key = dev_key; + if (mesh_crypto_payload_decrypt(NULL, 0, data, size, szmict, src, + dst, key_id, seq, iv_idx, out, key)) + return APP_IDX_DEV_REMOTE; + return -1; } @@ -694,6 +703,47 @@ static int add_sub(struct mesh_net *net, struct mesh_model *mod, return MESH_STATUS_SUCCESS; } +static void send_dev_key_msg_rcvd(struct mesh_node *node, uint8_t ele_idx, + uint16_t src, uint16_t net_idx, + uint16_t size, const uint8_t *data) +{ + struct l_dbus *dbus = dbus_get_bus(); + struct l_dbus_message *msg; + struct l_dbus_message_builder *builder; + const char *owner; + const char *path; + + owner = node_get_owner(node); + path = node_get_element_path(node, ele_idx); + if (!path || !owner) + return; + + l_debug("Send \"DevKeyMessageReceived\""); + + msg = l_dbus_message_new_method_call(dbus, owner, path, + MESH_ELEMENT_INTERFACE, + "DevKeyMessageReceived"); + + builder = l_dbus_message_builder_new(msg); + + if (!l_dbus_message_builder_append_basic(builder, 'q', &src)) + goto error; + + if (!l_dbus_message_builder_append_basic(builder, 'q', &net_idx)) + goto error; + + if (!dbus_append_byte_array(builder, data, size)) + goto error; + + if (!l_dbus_message_builder_finalize(builder)) + goto error; + + l_dbus_send(dbus, msg); + +error: + l_dbus_message_builder_destroy(builder); +} + static void send_msg_rcvd(struct mesh_node *node, uint8_t ele_idx, bool is_sub, uint16_t src, uint16_t key_idx, uint16_t size, const uint8_t *data) @@ -842,10 +892,17 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0, * Cycle through external models if the message has not been * handled by internal models */ - if (forward.has_dst && !forward.done) - send_msg_rcvd(node, i, is_subscription, src, - forward.idx, forward.size, - forward.data); + if (forward.has_dst && !forward.done) { + if ((decrypt_idx & APP_IDX_MASK) == decrypt_idx) + send_msg_rcvd(node, i, is_subscription, src, + forward.idx, forward.size, + forward.data); + else if (decrypt_idx == APP_IDX_DEV_REMOTE || + (decrypt_idx == APP_IDX_DEV_LOCAL && + mesh_net_is_local_address(net, src))) + send_dev_key_msg_rcvd(node, i, src, 0, + forward.size, forward.data); + } /* * Either the message has been processed internally or -- 2.19.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-07-02 18:15 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-07-02 9:07 [PATCH BlueZ v2 0/3] Add possibility to use remote device keys Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 1/3] mesh: Split APP_IDX_DEV into APP_IDX_DEV_LOCAL and APP_IDX_DEV_REMOTE Michał Lowas-Rzechonek 2019-07-02 18:15 ` Gix, Brian 2019-07-02 9:07 ` [PATCH BlueZ v2 2/3] mesh: Implement DevKeySend() method on Node interface Michał Lowas-Rzechonek 2019-07-02 9:07 ` [PATCH BlueZ v2 3/3] mesh: Handle messages encrypted with a remote device key Michał Lowas-Rzechonek
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).