Contiki-NG
Loading...
Searching...
No Matches
edhoc-key-storage.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024, RISE Research Institutes of Sweden AB.
3 * Copyright (c) 2020, Industrial Systems Institute (ISI), Patras, Greece
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holder nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 */
31
32/**
33 * \file
34 * edhoc-key-storage an implementation of a key storage to keep the ECC authentication keys to work with.
35 *
36 * \author
37 * Lidia Pocero <pocero@isi.gr>, Rikard Höglund, Marco Tiloca
38 */
39
40#include "edhoc-key-storage.h"
41#include "edhoc-error.h"
42#include "contiki.h"
43#include "contiki-lib.h"
44#include <string.h>
45
46#include "sys/log.h"
47#define LOG_MODULE "EDHOC"
48#define LOG_LEVEL LOG_LEVEL_EDHOC
49
50/*---------------------------------------------------------------------------*/
51LIST(key_list);
52MEMB(key_memb, cose_key_t, 2);
53/*---------------------------------------------------------------------------*/
56{
57 list_init(key_list);
58 memb_init(&key_memb);
59 return EDHOC_SUCCESS;
60}
61/*---------------------------------------------------------------------------*/
63edhoc_check_key_list_identity(char *identity, uint8_t identity_size,
64 cose_key_t **authentication_key)
65{
66 if(identity == NULL || authentication_key == NULL) {
68 }
69
70 if(identity_size == 0 || identity_size > EDHOC_MAX_IDENTITY_LEN) {
72 }
73
74 cose_key_t *key;
75 for(key = list_head(key_list); key != NULL; key = list_item_next(key)) {
76 if(key->identity_sz == identity_size &&
77 memcmp(key->identity, identity, identity_size) == 0) {
78 *authentication_key = key;
79 return EDHOC_SUCCESS;
80 }
81 }
83}
84/*---------------------------------------------------------------------------*/
86edhoc_check_key_list_kid(uint8_t *key_id, uint8_t key_id_size, cose_key_t **authentication_key)
87{
88 if(key_id == NULL || authentication_key == NULL) {
90 }
91
92 if(key_id_size == 0 || key_id_size > sizeof(((cose_key_t*)0)->kid)) {
94 }
95
96 cose_key_t *key;
97 for(key = list_head(key_list); key != NULL; key = list_item_next(key)) {
98 if(key->kid_sz == key_id_size &&
99 memcmp(key->kid, key_id, key_id_size) == 0) {
100 *authentication_key = key;
101 return EDHOC_SUCCESS;
102 }
103 }
105}
106/*---------------------------------------------------------------------------*/
109{
110 if(key == NULL) {
112 }
113
114 /* Check for duplicate keys */
115 cose_key_t *existing_key = NULL;
116 if(edhoc_check_key_list_kid(key->kid, key->kid_sz, &existing_key) == EDHOC_SUCCESS) {
118 }
119
120 cose_key_t *k = memb_alloc(&key_memb);
121 if(k == NULL) {
122 LOG_ERR("Failed to allocate memory for key\n");
124 }
125
126 memcpy(k, key, sizeof(cose_key_t));
127 list_add(key_list, k);
128
129 LOG_DBG("Added key KID 0x%02x (sz=%d), identity='%.*s'\n",
130 k->kid[0], k->kid_sz, k->identity_sz, k->identity);
131
132 return EDHOC_SUCCESS;
133}
134/*---------------------------------------------------------------------------*/
137{
138 if(k == NULL || key == NULL) {
140 }
141
142 memcpy(k, key, sizeof(cose_key_t));
143 return EDHOC_SUCCESS;
144}
145/*---------------------------------------------------------------------------*/
147edhoc_remove_key_kid(uint8_t *kid, uint8_t kid_sz)
148{
149 if(kid == NULL) {
151 }
152
153 cose_key_t *key = NULL;
154 edhoc_error_t result = edhoc_check_key_list_kid(kid, kid_sz, &key);
155 if(result == EDHOC_SUCCESS) {
156 list_remove(key_list, key);
157 memb_free(&key_memb, key);
158 return EDHOC_SUCCESS;
159 }
160 return result; /* Propagate the error from check function */
161}
162/*---------------------------------------------------------------------------*/
164edhoc_remove_key_identity(char *identity, uint8_t identity_sz)
165{
166 if(identity == NULL) {
168 }
169
170 cose_key_t *key = NULL;
171 edhoc_error_t result = edhoc_check_key_list_identity(identity, identity_sz, &key);
172 if(result == EDHOC_SUCCESS) {
173 list_remove(key_list, key);
174 memb_free(&key_memb, key);
175 return EDHOC_SUCCESS;
176 }
177 return result; /* Propagate the error from check function */
178}
179/*---------------------------------------------------------------------------*/
182{
183 if(auth_key == NULL) {
185 }
186
187 list_remove(key_list, auth_key);
188 memb_free(&key_memb, auth_key);
189 return EDHOC_SUCCESS;
190}
191/*---------------------------------------------------------------------------*/
192void
194{
195 LOG_DBG("kid: ");
196 LOG_DBG_BYTES(cose->kid, cose->kid_sz);
197 LOG_DBG_("\n");
198 LOG_DBG("identity: ");
199 LOG_DBG_BYTES((uint8_t *)cose->identity, cose->identity_sz);
200 LOG_DBG_("\n");
201 LOG_DBG("kty: %d\n", cose->kty);
202 LOG_DBG("crv: %d\n", cose->crv);
203 LOG_DBG("x: ");
204 LOG_DBG_BYTES(cose->ecc.pub.x, ECC_KEY_LEN);
205 LOG_DBG_("\n");
206 LOG_DBG("y: ");
207 LOG_DBG_BYTES(cose->ecc.pub.y, ECC_KEY_LEN);
208 LOG_DBG_("\n");
209}
210/*---------------------------------------------------------------------------*/
211void
212edhoc_print_key_info(const cose_key_t *key, const char *label)
213{
214 if(key == NULL || label == NULL) {
215 LOG_ERR("Invalid parameters for key info print\n");
216 return;
217 }
218
219 LOG_INFO("=== %s Key Information ===\n", label);
220 LOG_INFO("KID: ");
221 for(int i = 0; i < key->kid_sz; i++) {
222 LOG_INFO_("%02x", key->kid[i]);
223 }
224 LOG_INFO_("\n");
225 LOG_INFO("Identity: %.*s\n", key->identity_sz, key->identity);
226 LOG_INFO("Key Type: %s\n", key->kty == 2 ? "EC2" : "Unknown");
227 LOG_INFO("Curve: %s\n", key->crv == 1 ? "P-256" : "Unknown");
228 LOG_INFO("Public Key X: ");
229 for(int i = 0; i < 8; i++) {
230 LOG_INFO_("%02x ", key->ecc.pub.x[i]);
231 }
232 LOG_INFO_("... (32 bytes total)\n");
233 LOG_INFO("Public Key Y: ");
234 for(int i = 0; i < 8; i++) {
235 LOG_INFO_("%02x ", key->ecc.pub.y[i]);
236 }
237 LOG_INFO_("... (32 bytes total)\n");
238 LOG_INFO("Private Key: %s\n",
239 (key->ecc.priv[0] == 0 && key->ecc.priv[1] == 0) ? "Not present" : "Present");
240 LOG_INFO("=============================\n");
241}
242/*---------------------------------------------------------------------------*/
243void
244edhoc_print_credential(const char *label, const uint8_t *cred, size_t cred_sz)
245{
246 if(label == NULL || cred == NULL || cred_sz == 0) {
247 LOG_ERR("Invalid parameters for credential print\n");
248 return;
249 }
250
251 LOG_INFO("%s (%zu bytes): ", label, cred_sz);
252 for(size_t i = 0; i < cred_sz && i < 32; i++) {
253 LOG_INFO_("%02x ", cred[i]);
254 }
255 if(cred_sz > 32) {
256 LOG_INFO_("... (%zu more bytes)", cred_sz - 32);
257 }
258 LOG_INFO_("\n");
259
260 LOG_INFO("%s structure: {identity: ..., cose_key: {kty, kid, crv, x, y}}\n", label);
261}
262/*---------------------------------------------------------------------------*/
263uint8_t
265{
266 uint8_t count = 0;
267 cose_key_t *key;
268 for(key = list_head(key_list); key != NULL; key = list_item_next(key)) {
269 count++;
270 }
271 return count;
272}
273/*---------------------------------------------------------------------------*/
274void
276{
277 cose_key_t *key;
278 uint8_t count = 0;
279
280 for(key = list_head(key_list); key != NULL; key = list_item_next(key)) {
281 count++;
282 LOG_INFO(" %d. KID: %02x, Identity: %.*s, Type: %s\n",
283 count, key->kid[0], key->identity_sz, key->identity,
284 key->kty == 2 ? "EC2" : "Unknown");
285 }
286
287 if(count == 0) {
288 LOG_INFO(" No keys loaded\n");
289 }
290}
291/*---------------------------------------------------------------------------*/
294{
295 LOG_INFO("=== EDHOC Key Configuration Check ===\n");
296
297 uint8_t key_count = edhoc_get_key_count();
298 if(key_count == 0) {
299 LOG_ERR("No keys loaded!\n");
301 }
302
303 LOG_INFO("Loaded keys (%d total):\n", key_count);
305
306 cose_key_t *key;
307 uint8_t keys_with_private = 0;
308 uint8_t keys_public_only = 0;
309
310 for(key = list_head(key_list); key != NULL; key = list_item_next(key)) {
311 if(key->ecc.priv[0] != 0 || key->ecc.priv[1] != 0) {
312 keys_with_private++;
313 } else {
314 keys_public_only++;
315 }
316
317 if(key->kty != 2) {
318 LOG_WARN("Key %02x: Non-EC2 key type (%d)\n", key->kid[0], key->kty);
319 }
320
321 if(key->crv != 1) {
322 LOG_WARN("Key %02x: Non-P-256 curve (%d)\n", key->kid[0], key->crv);
323 }
324 }
325
326 LOG_INFO("Keys with private key: %d (for own identity)\n", keys_with_private);
327 LOG_INFO("Public-only keys: %d (for peer verification)\n", keys_public_only);
328
329 if(keys_with_private == 0) {
330 LOG_WARN("No keys with private key found - cannot authenticate as any identity\n");
331 }
332
333 if(keys_public_only == 0) {
334 LOG_WARN("No public-only keys found - cannot verify peer credentials\n");
335 }
336
337 LOG_INFO("=====================================\n");
338 return EDHOC_SUCCESS;
339}
340/*---------------------------------------------------------------------------*/
343 const char *own_label, const char *peer_label)
344{
345 if(own_key == NULL || peer_key == NULL || own_label == NULL || peer_label == NULL) {
347 }
348
349 memset(peer_key->ecc.priv, 0, sizeof(peer_key->ecc.priv));
350
351 edhoc_error_t result = edhoc_add_key(own_key);
352 if(result != EDHOC_SUCCESS) {
353 LOG_ERR("Failed to add %s key: %s\n", own_label, edhoc_error_string(result));
354 return result;
355 }
356
357 result = edhoc_add_key(peer_key);
358 if(result != EDHOC_SUCCESS) {
359 LOG_ERR("Failed to add %s key: %s\n", peer_label, edhoc_error_string(result));
360 return result;
361 }
362
363 LOG_INFO("Key pair configured: %s (KID: %02x) <-> %s (KID: %02x)\n",
364 own_label, own_key->kid[0], peer_label, peer_key->kid[0]);
365
366 return EDHOC_SUCCESS;
367}
368/*---------------------------------------------------------------------------*/
const char * edhoc_error_string(edhoc_error_t error)
Get a human-readable error message for an error code.
Definition edhoc-error.c:44
Error handling module header for EDHOC.
edhoc_error_t
Unified error type for EDHOC operations.
Definition edhoc-error.h:60
@ EDHOC_ERR_NULL_POINTER
Null pointer provided.
Definition edhoc-error.h:68
@ EDHOC_ERR_KEY_NOT_FOUND
Key not found in storage.
Definition edhoc-error.h:95
@ EDHOC_ERR_DUPLICATE_KEY
Duplicate key in storage.
Definition edhoc-error.h:99
@ EDHOC_ERR_INVALID_LENGTH
Invalid length parameter.
Definition edhoc-error.h:69
@ EDHOC_ERR_MEMORY_ALLOCATION
Memory allocation failed.
Definition edhoc-error.h:65
void edhoc_print_credential(const char *label, const uint8_t *cred, size_t cred_sz)
Print credential (CRED_I/CRED_R) values in readable format.
edhoc_error_t edhoc_create_key_list(void)
Create the keys repository.
void edhoc_list_all_keys(void)
List all keys in the key storage with basic information.
edhoc_error_t edhoc_remove_key_identity(char *identity, uint8_t identity_sz)
Remove from the keys repository the key with the specific identity.
edhoc_error_t edhoc_check_key_list_kid(uint8_t *key_id, uint8_t key_id_size, cose_key_t **authentication_key)
Check in the keys repository for the key with the specific KID.
edhoc_error_t edhoc_add_key(cose_key_t *key)
Add a DH key to the repository.
edhoc_error_t edhoc_remove_key_kid(uint8_t *kid, uint8_t kid_sz)
Remove from the keys repository the key with the specific KID.
void edhoc_print_key_info(const cose_key_t *key, const char *label)
Print detailed key information at INFO level for user visibility.
void cose_print_key(cose_key_t *cose)
Print a key in cose_key_t struct format for debugging.
edhoc_error_t edhoc_validate_key_setup(void)
Validate the current key setup and print diagnostic information.
edhoc_error_t edhoc_copy_key(cose_key_t *k, cose_key_t *key)
Copy a COSE key from one structure to another.
edhoc_error_t edhoc_check_key_list_identity(char *identity, uint8_t identity_size, cose_key_t **authentication_key)
Check in the keys repository for the key with the specific identity.
edhoc_error_t edhoc_setup_key_pair(cose_key_t *own_key, cose_key_t *peer_key, const char *own_label, const char *peer_label)
Helper function to set up a key pair (own + peer) with validation.
edhoc_error_t edhoc_remove_key(cose_key_t *auth_key)
Remove from the keys repository the specific DH cose_key_t key.
uint8_t edhoc_get_key_count(void)
Get the total number of keys loaded in the key storage.
EDHOC key storage - Implementation of key storage for managing DH-static authentication key pairs.
struct cose_key cose_key_t
KEY length in bytes.
static volatile uint64_t count
Num.
Definition clock.c:50
#define EDHOC_MAX_IDENTITY_LEN
Maximum length of identity strings in credentials Used for human-readable credential identities (e....
static void list_init(list_t list)
Initialize a list.
Definition list.h:152
#define LIST(name)
Declare a linked list.
Definition list.h:90
static void * list_item_next(const void *item)
Get the next item following this item.
Definition list.h:294
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition list.c:71
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
Definition list.c:134
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition list.h:169
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
Definition memb.c:78
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
Definition memb.c:59
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
Definition memb.c:52
#define MEMB(name, structure, num)
Declare a memory block.
Definition memb.h:91
Header file for the logging system.