Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1116669yba; Thu, 9 May 2019 11:00:56 -0700 (PDT) X-Google-Smtp-Source: APXvYqw6ouDKrCn6dXT870/suTXMNTqcBV/10Nam6pcDumtlNTClcE3Fm7B5XLoMwAJEgndhYpYH X-Received: by 2002:aa7:93ba:: with SMTP id x26mr7192875pff.238.1557424856675; Thu, 09 May 2019 11:00:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557424856; cv=none; d=google.com; s=arc-20160816; b=ub4c/H5hNidxbzB6krd0B0S2Gt/NGa73cIPqehRelEfsPbhDl4livrwy3LWVBzRp0D dUjZeJloSGnOQo49jdJoQlM0YpckBYuKPoJJPzI0C5o+0h+YWCk2y4sDkrBnksitMa5v lMTB9zDhNX7I9ZoV1YjTFrokinhb4vUoxQ3IeA4fVg/Mf1Tr+B8/KtQzRW7gczM/4KEB 9HBMF1O96vFu2BsAe+bOyuqA1qxdNlY+NJYDYsaJPF+fHaeM7myGILsTe3TSl0JLiUMf shXRBOQ9o6eOurmuMN389f+Tn4p+TO2vUF19YCZyZ76bLX+zPnPiDhj5dDk8Yw4Rj6TH A++Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=3U8gOcwM6jvPOUZsDmSanwd7iZJ8pfxKuGXvtuPrMbg=; b=QgJtd7crVDXGjIDwyzeVJyXuYFWnE0Vb9GwYc50xkLFRQNlMPkm4QxKuacgEkhvIZJ zyMO3AVLU+BcUYEf3fJfB7OEAZFfeHYDhViqwuugYTINl96bAqsOac+13zNMVNAmRi0d Re/cm9SudwEm9NPy4UuAcX9EDhmS+GVC9KHJvYp5d83N98kkhLLsEUMLnMS8Rwd7YJi6 mlUa/U8T44WlNPdigDaP0Gxa5UVbEcVIGYZtyxV/7yZ54Su45AHBuIhcjipWIV1EYcP5 W9YToTApzUKJmzV7PNlM1oKdt/Pl7eumYSPC7izTLCntnXC3eW3rCDqs0aEB4tsjHWSy Q8sQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-bluetooth-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f23si3715597pgv.21.2019.05.09.11.00.40; Thu, 09 May 2019 11:00:56 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-bluetooth-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-bluetooth-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726704AbfEIR6R (ORCPT + 99 others); Thu, 9 May 2019 13:58:17 -0400 Received: from mga04.intel.com ([192.55.52.120]:65363 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726558AbfEIR6Q (ORCPT ); Thu, 9 May 2019 13:58:16 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 May 2019 10:58:16 -0700 X-ExtLoop1: 1 Received: from bgix-dell-lap.sea.intel.com ([10.251.10.18]) by fmsmga004.fm.intel.com with ESMTP; 09 May 2019 10:58:16 -0700 From: Brian Gix To: linux-bluetooth@vger.kernel.org Cc: inga.stotland@intel.com, brian.gix@intel.com Subject: [PATCH BlueZ v5 2/2] mesh: Add key storage Date: Thu, 9 May 2019 10:57:39 -0700 Message-Id: <20190509175739.16891-3-brian.gix@intel.com> X-Mailer: git-send-email 2.14.5 In-Reply-To: <20190509175739.16891-1-brian.gix@intel.com> References: <20190509175739.16891-1-brian.gix@intel.com> Sender: linux-bluetooth-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This implements internal key storage add/delete/fetch for the three basic key types managed in Mesh: Network, Application and Device. This key storage is separate from keys assigned to nodes within the mesh, and are used to support Configuration Client functionality. --- Makefile.mesh | 1 + mesh/keyring.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mesh/keyring.h | 49 ++++++++++ 3 files changed, 347 insertions(+) create mode 100644 mesh/keyring.c create mode 100644 mesh/keyring.h diff --git a/Makefile.mesh b/Makefile.mesh index 76e424b92..bccd4d946 100644 --- a/Makefile.mesh +++ b/Makefile.mesh @@ -25,6 +25,7 @@ mesh_sources = mesh/mesh.h mesh/mesh.c \ mesh/agent.h mesh/agent.c \ mesh/prov-acceptor.c mesh/prov-initiator.c \ mesh/pb-adv.h mesh/pb-adv.c \ + mesh/keyring.h mesh/keyring.c \ mesh/mesh-defs.h libexec_PROGRAMS += mesh/bluetooth-meshd diff --git a/mesh/keyring.c b/mesh/keyring.c new file mode 100644 index 000000000..0ca53b0f8 --- /dev/null +++ b/mesh/keyring.c @@ -0,0 +1,297 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "mesh/mesh-defs.h" + +#include "mesh/net.h" +#include "mesh/keyring.h" +#include "mesh/mesh.h" +#include "mesh/node.h" + +const char *dev_key_dir = "/dev_keys"; +const char *app_key_dir = "/app_keys"; +const char *net_key_dir = "/net_keys"; + +bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx, + struct keyring_net_key *key) +{ + char *node_path; + char key_file[PATH_MAX]; + bool result = false; + int fd; + + if (!node || !key) + return false; + + node_path = node_path_get(node); + + if (strlen(node_path) + strlen(net_key_dir) + 1 + 3 >= PATH_MAX) + return false; + + snprintf(key_file, PATH_MAX, "%s%s", node_path, net_key_dir); + mkdir(key_file, 0755); + snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir, + net_idx); + l_debug("Put Net Key %s", key_file); + + fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC); + if (fd > 0) { + if (write(fd, key, sizeof(*key)) == sizeof(*key)) + result = true; + + close(fd); + } + + return result; +} + +bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx, + uint16_t net_idx, struct keyring_app_key *key) +{ + char *node_path; + char key_file[PATH_MAX]; + bool result = false; + int fd; + + if (!node || !key) + return false; + + node_path = node_path_get(node); + + if (strlen(node_path) + strlen(app_key_dir) + 1 + 3 >= PATH_MAX) + return false; + + snprintf(key_file, PATH_MAX, "%s%s", node_path, app_key_dir); + mkdir(key_file, 0755); + snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir, + app_idx); + l_debug("Put App Key %s", key_file); + + fd = open(key_file, O_RDONLY); + if (fd > 0) { + struct keyring_app_key old_key; + + if (read(fd, &old_key, sizeof(old_key)) == sizeof(old_key)) { + if (old_key.net_idx != net_idx) { + close(fd); + return false; + } + } + close(fd); + } + + fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC); + if (fd > 0) { + if (write(fd, key, sizeof(*key)) == sizeof(*key)) + result = true; + } + close(fd); + + return result; +} + +bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast, + uint8_t count, uint8_t dev_key[16]) +{ + char *node_path; + char key_file[PATH_MAX]; + bool result = true; + int fd, i; + + if (!node) + return false; + + node_path = node_path_get(node); + + if (strlen(node_path) + strlen(dev_key_dir) + 1 + 4 >= PATH_MAX) + return false; + + snprintf(key_file, PATH_MAX, "%s%s", node_path, dev_key_dir); + mkdir(key_file, 0755); + + for (i = 0; i < count; i++) { + snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, + dev_key_dir, unicast + i); + l_debug("Put Dev Key %s", key_file); + + fd = open(key_file, O_WRONLY | O_CREAT | O_TRUNC); + if (fd > 0) { + if (write(fd, dev_key, 16) != 16) + result = false; + + close(fd); + } else + result = false; + } + + return result; +} + +bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx, + struct keyring_net_key *key) +{ + char *node_path; + char key_file[PATH_MAX]; + bool result = false; + int fd; + + if (!node || !key) + return false; + + node_path = node_path_get(node); + snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir, + net_idx); + + fd = open(key_file, O_RDONLY); + if (fd > 0) { + if (read(fd, key, sizeof(*key)) == sizeof(*key)) + result = true; + + close(fd); + } + + return result; +} + +bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx, + struct keyring_app_key *key) +{ + char *node_path; + char key_file[PATH_MAX]; + bool result = false; + int fd; + + if (!node || !key) + return false; + + node_path = node_path_get(node); + snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir, + app_idx); + + fd = open(key_file, O_RDONLY); + if (fd > 0) { + if (read(fd, key, sizeof(*key)) == sizeof(*key)) + result = true; + + close(fd); + } + + return result; +} + +bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast, + uint8_t dev_key[16]) +{ + char *node_path; + char key_file[PATH_MAX]; + bool result = false; + int fd; + + if (!node) + return false; + + node_path = node_path_get(node); + snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, dev_key_dir, + unicast); + + fd = open(key_file, O_RDONLY); + if (fd > 0) { + if (read(fd, dev_key, 16) == 16) + result = true; + + close(fd); + } + + return result; +} + +bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx) +{ + char *node_path; + char key_file[PATH_MAX]; + + if (!node) + return false; + + node_path = node_path_get(node); + snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, net_key_dir, + net_idx); + l_debug("RM Net Key %s", key_file); + remove(key_file); + + /* TODO: See if it is easiest to delete all bound App keys here */ + /* TODO: see nftw() */ + + return true; +} + +bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx) +{ + char *node_path; + char key_file[PATH_MAX]; + + if (!node) + return false; + + node_path = node_path_get(node); + snprintf(key_file, PATH_MAX, "%s%s/%3.3x", node_path, app_key_dir, + app_idx); + l_debug("RM App Key %s", key_file); + remove(key_file); + + return true; +} + +bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast, + uint8_t count) +{ + char *node_path; + char key_file[PATH_MAX]; + int i; + + if (!node) + return false; + + node_path = node_path_get(node); + for (i = 0; i < count; i++) { + snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, + dev_key_dir, unicast + i); + l_debug("RM Dev Key %s", key_file); + remove(key_file); + } + + return true; +} diff --git a/mesh/keyring.h b/mesh/keyring.h new file mode 100644 index 000000000..167191013 --- /dev/null +++ b/mesh/keyring.h @@ -0,0 +1,49 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +struct keyring_net_key { + uint16_t net_idx; + uint8_t phase; + uint8_t old_key[16]; + uint8_t new_key[16]; +}; + +struct keyring_app_key { + uint16_t app_idx; + uint16_t net_idx; + uint8_t old_key[16]; + uint8_t new_key[16]; +}; + +bool keyring_put_net_key(struct mesh_node *node, uint16_t net_idx, + struct keyring_net_key *key); +bool keyring_get_net_key(struct mesh_node *node, uint16_t net_idx, + struct keyring_net_key *key); +bool keyring_del_net_key(struct mesh_node *node, uint16_t net_idx); +bool keyring_put_app_key(struct mesh_node *node, uint16_t app_idx, + uint16_t net_idx, struct keyring_app_key *key); +bool keyring_get_app_key(struct mesh_node *node, uint16_t app_idx, + struct keyring_app_key *key); +bool keyring_del_app_key(struct mesh_node *node, uint16_t app_idx); +bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast, + uint8_t dev_key[16]); +bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast, + uint8_t count, uint8_t dev_key[16]); +bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast, + uint8_t count); -- 2.14.5