diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2015-10-25 22:03:34 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-11-27 08:26:40 +0100 |
commit | cd04ed31209d31db0642dcc910354eda9c6d5c52 (patch) | |
tree | 62be1a6a0e1b2064f9c0c06f9ffa8070709ee7a2 /crypto/keystore.c | |
parent | 7ce48b67cb9abd7772c72a9e3f9d6c7716741be4 (diff) | |
download | barebox-cd04ed31209d31db0642dcc910354eda9c6d5c52.tar.gz |
crypto: add simple keystore
This patch adds a simple keystore to barebox. The keystore implements a simple
key-value store to hold arbitrary values.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'crypto/keystore.c')
-rw-r--r-- | crypto/keystore.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/crypto/keystore.c b/crypto/keystore.c new file mode 100644 index 0000000000..90b470fe67 --- /dev/null +++ b/crypto/keystore.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ + +#include <common.h> +#include <linux/kernel.h> +#include <linux/list.h> + +static LIST_HEAD(keystore_list); + +#define for_each_key(key) list_for_each_entry(key, &keystore_list, list) + +struct keystore_key { + struct list_head list; + const char *name; + const u8 *secret; + int secret_len; +}; + +static int keystore_compare(struct list_head *a, struct list_head *b) +{ + const char *na = list_entry(a, struct keystore_key, list)->name; + const char *nb = list_entry(b, struct keystore_key, list)->name; + + return strcmp(na, nb); +} + +/** + * @param[in] name Name of the secret to get + * @param[out] secret Double pointer to memory representing the secret, do _not_ free() after use + * @param[out] secret_len Pointer to length of the secret + */ +int keystore_get_secret(const char *name, const u8 **secret, int *secret_len) +{ + struct keystore_key *key; + + for_each_key(key) { + if (!strcmp(name, key->name)) { + if (!secret || !secret_len) + return 0; + + *secret = key->secret; + *secret_len = key->secret_len; + + return 0; + } + } + + return -ENOENT; +} + +/** + * @param[in] name Name of the secret to set + * @param[in] secret Pointer to memory holding the secret + * @param[in] secret_len Length of the secret + */ +int keystore_set_secret(const char *name, const u8 *secret, int secret_len) +{ + struct keystore_key *key; + int ret; + + /* check if key is already in store */ + ret = keystore_get_secret(name, NULL, NULL); + if (!ret) + return -EBUSY; + + key = xzalloc(sizeof(*key)); + INIT_LIST_HEAD(&key->list); + key->name = xstrdup(name); + key->secret = xmemdup(secret, secret_len); + key->secret_len = secret_len; + + list_add_sort(&key->list, &keystore_list, keystore_compare); + + return 0; +} |