aboutsummaryrefslogtreecommitdiff
path: root/rpc_pkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpc_pkey.c')
-rw-r--r--rpc_pkey.c439
1 files changed, 294 insertions, 145 deletions
diff --git a/rpc_pkey.c b/rpc_pkey.c
index bdf8a7e..1aee050 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -39,6 +39,7 @@
#include "hal.h"
#include "hal_internal.h"
#include "asn1_internal.h"
+#include "hashsig.h"
#ifndef HAL_STATIC_PKEY_STATE_BLOCKS
#define HAL_STATIC_PKEY_STATE_BLOCKS 0
@@ -78,11 +79,11 @@ static inline hal_pkey_slot_t *alloc_slot(const hal_key_flags_t flags)
if ((flags & HAL_KEY_FLAG_TOKEN) != 0)
glop |= HAL_PKEY_HANDLE_TOKEN_FLAG;
- for (int i = 0; slot == NULL && i < sizeof(pkey_slot)/sizeof(*pkey_slot); i++) {
- if (pkey_slot[i].pkey_handle.handle != HAL_HANDLE_NONE)
+ for (size_t i = 0; slot == NULL && i < sizeof(pkey_slot)/sizeof(*pkey_slot); i++) {
+ if (pkey_slot[i].pkey.handle != HAL_HANDLE_NONE)
continue;
memset(&pkey_slot[i], 0, sizeof(pkey_slot[i]));
- pkey_slot[i].pkey_handle.handle = i | glop;
+ pkey_slot[i].pkey.handle = i | glop;
pkey_slot[i].hint = -1;
slot = &pkey_slot[i];
}
@@ -118,9 +119,9 @@ static inline hal_pkey_slot_t *find_handle(const hal_pkey_handle_t handle)
hal_critical_section_start();
#if HAL_STATIC_PKEY_STATE_BLOCKS > 0
- const int i = (int) (handle.handle & 0xFFFF);
+ const size_t i = handle.handle & 0xFFFF;
- if (i < sizeof(pkey_slot)/sizeof(*pkey_slot) && pkey_slot[i].pkey_handle.handle == handle.handle)
+ if (i < sizeof(pkey_slot)/sizeof(*pkey_slot) && pkey_slot[i].pkey.handle == handle.handle)
slot = &pkey_slot[i];
#endif
@@ -129,6 +130,32 @@ static inline hal_pkey_slot_t *find_handle(const hal_pkey_handle_t handle)
}
/*
+ * Clean up key state associated with a client when logging out.
+ */
+
+hal_error_t hal_pkey_logout(const hal_client_handle_t client)
+{
+ if (client.handle == HAL_HANDLE_NONE)
+ return HAL_OK;
+
+ hal_error_t err;
+
+ if ((err = hal_ks_logout(hal_ks_volatile, client)) != HAL_OK ||
+ (err = hal_ks_logout(hal_ks_token, client)) != HAL_OK)
+ return err;
+
+ hal_critical_section_start();
+
+ for (size_t i = 0; i < sizeof(pkey_slot)/sizeof(*pkey_slot); i++)
+ if (pkey_slot[i].pkey.handle == client.handle)
+ memset(&pkey_slot[i], 0, sizeof(pkey_slot[i]));
+
+ hal_critical_section_end();
+
+ return HAL_OK;
+}
+
+/*
* Access rules are a bit complicated, mostly due to PKCS #11.
*
* The simple, obvious rule would be that one must be logged in as
@@ -270,52 +297,25 @@ static hal_error_t pkcs1_5_pad(const uint8_t * const data, const size_t data_len
}
/*
- * Given key flags, open appropriate keystore driver.
- */
-
-static inline hal_error_t ks_open_from_flags(hal_ks_t **ks, const hal_key_flags_t flags)
-{
- return hal_ks_open((flags & HAL_KEY_FLAG_TOKEN) == 0
- ? hal_ks_volatile_driver
- : hal_ks_token_driver,
- ks);
-}
-
-/*
- * Fetch a key from a driver.
+ * Given key flags, return appropriate keystore.
*/
-static inline hal_error_t ks_fetch_from_driver(const hal_ks_driver_t * const driver,
- hal_pkey_slot_t *slot,
- uint8_t *der, size_t *der_len, const size_t der_max)
+static inline hal_ks_t *ks_from_flags(const hal_key_flags_t flags)
{
- hal_ks_t *ks = NULL;
- hal_error_t err;
-
- if ((err = hal_ks_open(driver, &ks)) != HAL_OK)
- return err;
-
- if ((err = hal_ks_fetch(ks, slot, der, der_len, der_max)) == HAL_OK)
- err = hal_ks_close(ks);
- else
- (void) hal_ks_close(ks);
-
- return err;
+ return (flags & HAL_KEY_FLAG_TOKEN) == 0 ? hal_ks_volatile : hal_ks_token;
}
/*
- * Same thing but from key flag in slot object rather than explict driver.
+ * Fetch a key from keystore indicated by key flag in slot object.
*/
static inline hal_error_t ks_fetch_from_flags(hal_pkey_slot_t *slot,
uint8_t *der, size_t *der_len, const size_t der_max)
{
- assert(slot != NULL);
+ if (slot == NULL)
+ return HAL_ERROR_IMPOSSIBLE;
- return ks_fetch_from_driver((slot->flags & HAL_KEY_FLAG_TOKEN) == 0
- ? hal_ks_volatile_driver
- : hal_ks_token_driver,
- slot, der, der_len, der_max);
+ return hal_ks_fetch(ks_from_flags(slot->flags), slot, der, der_len, der_max);
}
@@ -336,7 +336,6 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
hal_curve_name_t curve;
hal_pkey_slot_t *slot;
hal_key_type_t type;
- hal_ks_t *ks = NULL;
hal_error_t err;
if ((err = check_writable(client, flags)) != HAL_OK)
@@ -351,24 +350,18 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
return err;
- slot->client_handle = client;
- slot->session_handle = session;
- slot->type = type;
- slot->curve = curve;
- slot->flags = flags;
-
- if ((err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
- (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
- err = hal_ks_close(ks);
- else if (ks != NULL)
- (void) hal_ks_close(ks);
+ slot->client = client;
+ slot->session = session;
+ slot->type = type;
+ slot->curve = curve;
+ slot->flags = flags;
- if (err != HAL_OK) {
+ if ((err = hal_ks_store(ks_from_flags(flags), slot, der, der_len)) != HAL_OK) {
slot->type = HAL_KEY_TYPE_NONE;
return err;
}
- *pkey = slot->pkey_handle;
+ *pkey = slot->pkey;
*name = slot->name;
return HAL_OK;
}
@@ -393,20 +386,20 @@ static hal_error_t pkey_local_open(const hal_client_handle_t client,
if ((slot = alloc_slot(0)) == NULL)
return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
- slot->name = *name;
- slot->client_handle = client;
- slot->session_handle = session;
+ slot->name = *name;
+ slot->client = client;
+ slot->session = session;
- if ((err = ks_fetch_from_driver(hal_ks_token_driver, slot, NULL, NULL, 0)) == HAL_OK)
- slot->pkey_handle.handle |= HAL_PKEY_HANDLE_TOKEN_FLAG;
+ if ((err = hal_ks_fetch(hal_ks_token, slot, NULL, NULL, 0)) == HAL_OK)
+ slot->pkey.handle |= HAL_PKEY_HANDLE_TOKEN_FLAG;
else if (err == HAL_ERROR_KEY_NOT_FOUND)
- err = ks_fetch_from_driver(hal_ks_volatile_driver, slot, NULL, NULL, 0);
+ err = hal_ks_fetch(hal_ks_volatile, slot, NULL, NULL, 0);
if (err != HAL_OK)
goto fail;
- *pkey = slot->pkey_handle;
+ *pkey = slot->pkey;
return HAL_OK;
fail:
@@ -431,7 +424,6 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
uint8_t keybuf[hal_rsa_key_t_size];
hal_rsa_key_t *key = NULL;
hal_pkey_slot_t *slot;
- hal_ks_t *ks = NULL;
hal_error_t err;
if ((err = check_writable(client, flags)) != HAL_OK)
@@ -443,11 +435,11 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
return err;
- slot->client_handle = client;
- slot->session_handle = session;
- slot->type = HAL_KEY_TYPE_RSA_PRIVATE;
- slot->curve = HAL_CURVE_NONE;
- slot->flags = flags;
+ slot->client = client;
+ slot->session = session;
+ slot->type = HAL_KEY_TYPE_RSA_PRIVATE;
+ slot->curve = HAL_CURVE_NONE;
+ slot->flags = flags;
if ((err = hal_rsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), key_length / 8,
public_exponent, public_exponent_len)) != HAL_OK) {
@@ -458,12 +450,8 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
uint8_t der[hal_rsa_private_key_to_der_len(key)];
size_t der_len;
- if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK &&
- (err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
- (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
- err = hal_ks_close(ks);
- else if (ks != NULL)
- (void) hal_ks_close(ks);
+ if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
+ err = hal_ks_store(ks_from_flags(flags), slot, der, der_len);
memset(keybuf, 0, sizeof(keybuf));
memset(der, 0, sizeof(der));
@@ -473,7 +461,7 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
return err;
}
- *pkey = slot->pkey_handle;
+ *pkey = slot->pkey;
*name = slot->name;
return HAL_OK;
}
@@ -495,7 +483,6 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
uint8_t keybuf[hal_ecdsa_key_t_size];
hal_ecdsa_key_t *key = NULL;
hal_pkey_slot_t *slot;
- hal_ks_t *ks = NULL;
hal_error_t err;
if ((err = check_writable(client, flags)) != HAL_OK)
@@ -507,11 +494,11 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
return err;
- slot->client_handle = client;
- slot->session_handle = session;
- slot->type = HAL_KEY_TYPE_EC_PRIVATE;
- slot->curve = curve;
- slot->flags = flags;
+ slot->client = client;
+ slot->session = session;
+ slot->type = HAL_KEY_TYPE_EC_PRIVATE;
+ slot->curve = curve;
+ slot->flags = flags;
if ((err = hal_ecdsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), curve)) != HAL_OK) {
slot->type = HAL_KEY_TYPE_NONE;
@@ -521,12 +508,8 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
uint8_t der[hal_ecdsa_private_key_to_der_len(key)];
size_t der_len;
- if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK &&
- (err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
- (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
- err = hal_ks_close(ks);
- else if (ks != NULL)
- (void) hal_ks_close(ks);
+ if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
+ err = hal_ks_store(ks_from_flags(flags), slot, der, der_len);
memset(keybuf, 0, sizeof(keybuf));
memset(der, 0, sizeof(der));
@@ -536,7 +519,69 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
return err;
}
- *pkey = slot->pkey_handle;
+ *pkey = slot->pkey;
+ *name = slot->name;
+ return HAL_OK;
+}
+
+/*
+ * Generate a new hash-tree key with supplied name, return a key handle.
+ */
+
+static hal_error_t pkey_local_generate_hashsig(const hal_client_handle_t client,
+ const hal_session_handle_t session,
+ hal_pkey_handle_t *pkey,
+ hal_uuid_t *name,
+ const size_t hss_levels,
+ const lms_algorithm_t lms_type,
+ const lmots_algorithm_t lmots_type,
+ const hal_key_flags_t flags)
+{
+ assert(pkey != NULL && name != NULL);
+
+ hal_hashsig_key_t *key = NULL;
+ hal_pkey_slot_t *slot;
+ hal_error_t err;
+
+ if ((err = check_writable(client, flags)) != HAL_OK)
+ return err;
+
+ if ((slot = alloc_slot(flags)) == NULL)
+ return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
+
+ if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
+ return err;
+
+ slot->client = client;
+ slot->session = session;
+ slot->type = HAL_KEY_TYPE_HASHSIG_PRIVATE,
+ slot->curve = HAL_CURVE_NONE;
+ slot->flags = flags;
+
+ if ((err = hal_hashsig_key_gen(NULL, &key, hss_levels, lms_type, lmots_type)) != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
+ return err;
+ }
+
+ uint8_t der[hal_hashsig_private_key_to_der_len(key)];
+ size_t der_len;
+
+ if ((err = hal_hashsig_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
+ err = hal_ks_store(ks_from_flags(flags), slot, der, der_len);
+
+ /* There's nothing sensitive in the top-level private key, but we wipe
+ * the der anyway, for symmetry with other key types. The actual key buf
+ * is allocated internally and stays in memory, because everything else
+ * is linked off of it.
+ */
+ memset(der, 0, sizeof(der));
+
+ if (err != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
+ return err;
+ }
+
+ *pkey = slot->pkey;
*name = slot->name;
return HAL_OK;
}
@@ -560,6 +605,7 @@ static hal_error_t pkey_local_close(const hal_pkey_handle_t pkey)
/*
* Delete a key from the store, given its key handle.
*/
+static hal_error_t pkey_local_get_key_type(const hal_pkey_handle_t pkey, hal_key_type_t *type);
static hal_error_t pkey_local_delete(const hal_pkey_handle_t pkey)
{
@@ -568,17 +614,27 @@ static hal_error_t pkey_local_delete(const hal_pkey_handle_t pkey)
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- hal_ks_t *ks = NULL;
hal_error_t err;
- if ((err = check_writable(slot->client_handle, slot->flags)) != HAL_OK)
+ if ((err = check_writable(slot->client, slot->flags)) != HAL_OK)
return err;
- if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
- (err = hal_ks_delete(ks, slot)) == HAL_OK)
- err = hal_ks_close(ks);
- else if (ks != NULL)
- (void) hal_ks_close(ks);
+ hal_key_type_t key_type;
+ if ((err = pkey_local_get_key_type(pkey, &key_type)) != HAL_OK)
+ return err;
+
+ if (key_type == HAL_KEY_TYPE_HASHSIG_PRIVATE) {
+ hal_hashsig_key_t *key;
+ uint8_t keybuf[hal_hashsig_key_t_size];
+ uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
+ size_t der_len;
+ if ((err = ks_fetch_from_flags(slot, der, &der_len, sizeof(der))) != HAL_OK ||
+ (err = hal_hashsig_private_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)) != HAL_OK ||
+ (err = hal_hashsig_key_delete(key)) != HAL_OK)
+ return err;
+ }
+
+ err = hal_ks_delete(ks_from_flags(slot->flags), slot);
if (err == HAL_OK || err == HAL_ERROR_KEY_NOT_FOUND)
clear_slot(slot);
@@ -659,9 +715,15 @@ static size_t pkey_local_get_public_key_len(const hal_pkey_handle_t pkey)
size_t result = 0;
- uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
- hal_rsa_key_t *rsa_key = NULL;
- hal_ecdsa_key_t *ecdsa_key = NULL;
+#ifndef max
+#define max(a, b) ((a) >= (b) ? (a) : (b))
+#endif
+ size_t keybuf_size = max(hal_rsa_key_t_size, hal_ecdsa_key_t_size);
+ keybuf_size = max(keybuf_size, hal_hashsig_key_t_size);
+ uint8_t keybuf[keybuf_size];
+ hal_rsa_key_t *rsa_key = NULL;
+ hal_ecdsa_key_t *ecdsa_key = NULL;
+ hal_hashsig_key_t *hashsig_key = NULL;
uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
size_t der_len;
hal_error_t err;
@@ -671,6 +733,7 @@ static size_t pkey_local_get_public_key_len(const hal_pkey_handle_t pkey)
case HAL_KEY_TYPE_RSA_PUBLIC:
case HAL_KEY_TYPE_EC_PUBLIC:
+ case HAL_KEY_TYPE_HASHSIG_PUBLIC:
result = der_len;
break;
@@ -684,6 +747,11 @@ static size_t pkey_local_get_public_key_len(const hal_pkey_handle_t pkey)
result = hal_ecdsa_public_key_to_der_len(ecdsa_key);
break;
+ case HAL_KEY_TYPE_HASHSIG_PRIVATE:
+ if (hal_hashsig_private_key_from_der(&hashsig_key, keybuf, sizeof(keybuf), der, der_len) == HAL_OK)
+ result = hal_hashsig_public_key_to_der_len(hashsig_key);
+ break;
+
default:
break;
}
@@ -707,10 +775,12 @@ static hal_error_t pkey_local_get_public_key(const hal_pkey_handle_t pkey,
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size
- ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
- hal_rsa_key_t *rsa_key = NULL;
- hal_ecdsa_key_t *ecdsa_key = NULL;
+ size_t keybuf_size = max(hal_rsa_key_t_size, hal_ecdsa_key_t_size);
+ keybuf_size = max(keybuf_size, hal_hashsig_key_t_size);
+ uint8_t keybuf[keybuf_size];
+ hal_rsa_key_t *rsa_key = NULL;
+ hal_ecdsa_key_t *ecdsa_key = NULL;
+ hal_hashsig_key_t *hashsig_key = NULL;
uint8_t buf[HAL_KS_WRAPPED_KEYSIZE];
size_t buf_len;
hal_error_t err;
@@ -720,6 +790,7 @@ static hal_error_t pkey_local_get_public_key(const hal_pkey_handle_t pkey,
case HAL_KEY_TYPE_RSA_PUBLIC:
case HAL_KEY_TYPE_EC_PUBLIC:
+ case HAL_KEY_TYPE_HASHSIG_PUBLIC:
if (der_len != NULL)
*der_len = buf_len;
if (der != NULL && der_max < buf_len)
@@ -738,6 +809,11 @@ static hal_error_t pkey_local_get_public_key(const hal_pkey_handle_t pkey,
err = hal_ecdsa_public_key_to_der(ecdsa_key, der, der_len, der_max);
break;
+ case HAL_KEY_TYPE_HASHSIG_PRIVATE:
+ if ((err = hal_hashsig_private_key_from_der(&hashsig_key, keybuf, sizeof(keybuf), buf, buf_len)) == HAL_OK)
+ err = hal_hashsig_public_key_to_der(hashsig_key, der, der_len, der_max);
+ break;
+
default:
err = HAL_ERROR_UNSUPPORTED_KEY;
break;
@@ -757,7 +833,8 @@ static hal_error_t pkey_local_get_public_key(const hal_pkey_handle_t pkey,
* algorithm-specific functions.
*/
-static hal_error_t pkey_local_sign_rsa(uint8_t *keybuf, const size_t keybuf_len,
+static hal_error_t pkey_local_sign_rsa(hal_pkey_slot_t *slot,
+ uint8_t *keybuf, const size_t keybuf_len,
const uint8_t * const der, const size_t der_len,
const hal_hash_handle_t hash,
const uint8_t * input, size_t input_len,
@@ -782,14 +859,25 @@ static hal_error_t pkey_local_sign_rsa(uint8_t *keybuf, const size_t keybuf_len,
input = signature;
}
- if ((err = pkcs1_5_pad(input, input_len, signature, *signature_len, 0x01)) != HAL_OK ||
- (err = hal_rsa_decrypt(NULL, key, signature, *signature_len, signature, *signature_len)) != HAL_OK)
+ if ((err = pkcs1_5_pad(input, input_len, signature, *signature_len, 0x01)) != HAL_OK ||
+ (err = hal_rsa_decrypt(NULL, NULL, key, signature, *signature_len, signature, *signature_len)) != HAL_OK)
return err;
+ if (hal_rsa_key_needs_saving(key)) {
+ uint8_t pkcs8[hal_rsa_private_key_to_der_extra_len(key)];
+ size_t pkcs8_len = 0;
+ if ((err = hal_rsa_private_key_to_der_extra(key, pkcs8, &pkcs8_len, sizeof(pkcs8))) == HAL_OK)
+ err = hal_ks_rewrite_der(ks_from_flags(slot->flags), slot, pkcs8, pkcs8_len);
+ memset(pkcs8, 0, sizeof(pkcs8));
+ if (err != HAL_OK)
+ return err;
+ }
+
return HAL_OK;
}
-static hal_error_t pkey_local_sign_ecdsa(uint8_t *keybuf, const size_t keybuf_len,
+static hal_error_t pkey_local_sign_ecdsa(hal_pkey_slot_t *slot,
+ uint8_t *keybuf, const size_t keybuf_len,
const uint8_t * const der, const size_t der_len,
const hal_hash_handle_t hash,
const uint8_t * input, size_t input_len,
@@ -826,6 +914,44 @@ static hal_error_t pkey_local_sign_ecdsa(uint8_t *keybuf, const size_t keybuf_le
return HAL_OK;
}
+static hal_error_t pkey_local_sign_hashsig(hal_pkey_slot_t *slot,
+ uint8_t *keybuf, const size_t keybuf_len,
+ const uint8_t * const der, const size_t der_len,
+ const hal_hash_handle_t hash,
+ const uint8_t * input, size_t input_len,
+ uint8_t * signature, size_t *signature_len, const size_t signature_max)
+{
+ hal_hashsig_key_t *key = NULL;
+ hal_error_t err;
+
+ assert(signature != NULL && signature_len != NULL);
+ assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+
+ if ((err = hal_hashsig_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
+ return err;
+
+ if (input == NULL || input_len == 0) {
+ hal_digest_algorithm_t alg;
+
+ if ((err = hal_rpc_hash_get_algorithm(hash, &alg)) != HAL_OK ||
+ (err = hal_rpc_hash_get_digest_length(alg, &input_len)) != HAL_OK)
+ return err;
+
+ if (input_len > signature_max)
+ return HAL_ERROR_RESULT_TOO_LONG;
+
+ if ((err = hal_rpc_hash_finalize(hash, signature, input_len)) != HAL_OK)
+ return err;
+
+ input = signature;
+ }
+
+ if ((err = hal_hashsig_sign(NULL, key, input, input_len, signature, signature_len, signature_max)) != HAL_OK)
+ return err;
+
+ return HAL_OK;
+}
+
static hal_error_t pkey_local_sign(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
@@ -836,18 +962,26 @@ static hal_error_t pkey_local_sign(const hal_pkey_handle_t pkey,
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- hal_error_t (*signer)(uint8_t *keybuf, const size_t keybuf_len,
+ hal_error_t (*signer)(hal_pkey_slot_t *slot,
+ uint8_t *keybuf, const size_t keybuf_len,
const uint8_t * const der, const size_t der_len,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
uint8_t * signature, size_t *signature_len, const size_t signature_max);
+ size_t keybuf_size;
switch (slot->type) {
case HAL_KEY_TYPE_RSA_PRIVATE:
signer = pkey_local_sign_rsa;
+ keybuf_size = hal_rsa_key_t_size;
break;
case HAL_KEY_TYPE_EC_PRIVATE:
signer = pkey_local_sign_ecdsa;
+ keybuf_size = hal_ecdsa_key_t_size;
+ break;
+ case HAL_KEY_TYPE_HASHSIG_PRIVATE:
+ signer = pkey_local_sign_hashsig;
+ keybuf_size = hal_hashsig_key_t_size;
break;
default:
return HAL_ERROR_UNSUPPORTED_KEY;
@@ -856,14 +990,13 @@ static hal_error_t pkey_local_sign(const hal_pkey_handle_t pkey,
if ((slot->flags & HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE) == 0)
return HAL_ERROR_FORBIDDEN;
- uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size
- ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
+ uint8_t keybuf[keybuf_size];
uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
size_t der_len;
hal_error_t err;
if ((err = ks_fetch_from_flags(slot, der, &der_len, sizeof(der))) == HAL_OK)
- err = signer(keybuf, sizeof(keybuf), der, der_len, hash, input, input_len,
+ err = signer(slot, keybuf, sizeof(keybuf), der, der_len, hash, input, input_len,
signature, signature_len, signature_max);
memset(keybuf, 0, sizeof(keybuf));
@@ -917,7 +1050,7 @@ static hal_error_t pkey_local_verify_rsa(uint8_t *keybuf, const size_t keybuf_le
return err;
unsigned diff = 0;
- for (int i = 0; i < signature_len; i++)
+ for (size_t i = 0; i < signature_len; i++)
diff |= expected[i] ^ received[i + sizeof(received) - sizeof(expected)];
if (diff != 0)
@@ -970,6 +1103,40 @@ static hal_error_t pkey_local_verify_ecdsa(uint8_t *keybuf, const size_t keybuf_
return HAL_OK;
}
+static hal_error_t pkey_local_verify_hashsig(uint8_t *keybuf, const size_t keybuf_len, const hal_key_type_t type,
+ const uint8_t * const der, const size_t der_len,
+ const hal_hash_handle_t hash,
+ const uint8_t * input, size_t input_len,
+ const uint8_t * const signature, const size_t signature_len)
+{
+ uint8_t digest[signature_len];
+ hal_hashsig_key_t *key = NULL;
+ hal_error_t err;
+
+ assert(signature != NULL && signature_len > 0);
+ assert((hash.handle == HAL_HANDLE_NONE) != (input == NULL || input_len == 0));
+
+ if ((err = hal_hashsig_public_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
+ return err;
+
+ if (input == NULL || input_len == 0) {
+ hal_digest_algorithm_t alg;
+
+ // ???
+ if ((err = hal_rpc_hash_get_algorithm(hash, &alg)) != HAL_OK ||
+ (err = hal_rpc_hash_get_digest_length(alg, &input_len)) != HAL_OK ||
+ (err = hal_rpc_hash_finalize(hash, digest, sizeof(digest))) != HAL_OK)
+ return err;
+
+ input = digest;
+ }
+
+ if ((err = hal_hashsig_verify(NULL, key, input, input_len, signature, signature_len)) != HAL_OK)
+ return err;
+
+ return HAL_OK;
+}
+
static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
@@ -985,15 +1152,22 @@ static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
const uint8_t * const signature, const size_t signature_len);
+ size_t keybuf_size;
switch (slot->type) {
case HAL_KEY_TYPE_RSA_PRIVATE:
case HAL_KEY_TYPE_RSA_PUBLIC:
verifier = pkey_local_verify_rsa;
+ keybuf_size = hal_rsa_key_t_size;
break;
case HAL_KEY_TYPE_EC_PRIVATE:
case HAL_KEY_TYPE_EC_PUBLIC:
verifier = pkey_local_verify_ecdsa;
+ keybuf_size = hal_ecdsa_key_t_size;
+ break;
+ case HAL_KEY_TYPE_HASHSIG_PUBLIC:
+ verifier = pkey_local_verify_hashsig;
+ keybuf_size = hal_hashsig_key_t_size;
break;
default:
return HAL_ERROR_UNSUPPORTED_KEY;
@@ -1002,8 +1176,7 @@ static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
if ((slot->flags & HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE) == 0)
return HAL_ERROR_FORBIDDEN;
- uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size
- ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
+ uint8_t keybuf[keybuf_size];
uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
size_t der_len;
hal_error_t err;
@@ -1018,7 +1191,7 @@ static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
return err;
}
-static inline hal_error_t match_one_keystore(const hal_ks_driver_t * const driver,
+static inline hal_error_t match_one_keystore(hal_ks_t *ks,
const hal_client_handle_t client,
const hal_session_handle_t session,
const hal_key_type_t type,
@@ -1032,21 +1205,12 @@ static inline hal_error_t match_one_keystore(const hal_ks_driver_t * const drive
const unsigned result_max,
const hal_uuid_t * const previous_uuid)
{
- hal_ks_t *ks = NULL;
hal_error_t err;
unsigned len;
- if ((err = hal_ks_open(driver, &ks)) != HAL_OK)
- return err;
-
if ((err = hal_ks_match(ks, client, session, type, curve,
mask, flags, attributes, attributes_len,
- *result, &len, result_max, previous_uuid)) != HAL_OK) {
- (void) hal_ks_close(ks);
- return err;
- }
-
- if ((err = hal_ks_close(ks)) != HAL_OK)
+ *result, &len, result_max, previous_uuid)) != HAL_OK)
return err;
*result += len;
@@ -1097,7 +1261,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client,
case MATCH_STATE_TOKEN:
if (((mask & HAL_KEY_FLAG_TOKEN) == 0 || (mask & flags & HAL_KEY_FLAG_TOKEN) != 0) &&
- (err = match_one_keystore(hal_ks_token_driver, client, session, type, curve,
+ (err = match_one_keystore(hal_ks_token, client, session, type, curve,
mask, flags, attributes, attributes_len,
&result, result_len, result_max - *result_len, prev)) != HAL_OK)
return err;
@@ -1108,7 +1272,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client,
case MATCH_STATE_VOLATILE:
if (((mask & HAL_KEY_FLAG_TOKEN) == 0 || (mask & flags & HAL_KEY_FLAG_TOKEN) == 0) &&
- (err = match_one_keystore(hal_ks_volatile_driver, client, session, type, curve,
+ (err = match_one_keystore(hal_ks_volatile, client, session, type, curve,
mask, flags, attributes, attributes_len,
&result, result_len, result_max - *result_len, prev)) != HAL_OK)
return err;
@@ -1133,19 +1297,12 @@ static hal_error_t pkey_local_set_attributes(const hal_pkey_handle_t pkey,
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- hal_ks_t *ks = NULL;
hal_error_t err;
- if ((err = check_writable(slot->client_handle, slot->flags)) != HAL_OK)
+ if ((err = check_writable(slot->client, slot->flags)) != HAL_OK)
return err;
- if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
- (err = hal_ks_set_attributes(ks, slot, attributes, attributes_len)) == HAL_OK)
- err = hal_ks_close(ks);
- else if (ks != NULL)
- (void) hal_ks_close(ks);
-
- return err;
+ return hal_ks_set_attributes(ks_from_flags(slot->flags), slot, attributes, attributes_len);
}
static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey,
@@ -1159,17 +1316,8 @@ static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey,
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- hal_ks_t *ks = NULL;
- hal_error_t err;
-
- if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
- (err = hal_ks_get_attributes(ks, slot, attributes, attributes_len,
- attributes_buffer, attributes_buffer_len)) == HAL_OK)
- err = hal_ks_close(ks);
- else if (ks != NULL)
- (void) hal_ks_close(ks);
-
- return err;
+ return hal_ks_get_attributes(ks_from_flags(slot->flags), slot, attributes, attributes_len,
+ attributes_buffer, attributes_buffer_len);
}
static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
@@ -1311,7 +1459,7 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client,
goto fail;
}
- if ((err = hal_rsa_decrypt(NULL, rsa, data, data_len, der, data_len)) != HAL_OK)
+ if ((err = hal_rsa_decrypt(NULL, NULL, rsa, data, data_len, der, data_len)) != HAL_OK)
goto fail;
if ((err = hal_get_random(NULL, kek, sizeof(kek))) != HAL_OK)
@@ -1352,6 +1500,7 @@ const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch = {
.open = pkey_local_open,
.generate_rsa = pkey_local_generate_rsa,
.generate_ec = pkey_local_generate_ec,
+ .generate_hashsig = pkey_local_generate_hashsig,
.close = pkey_local_close,
.delete = pkey_local_delete,
.get_key_type = pkey_local_get_key_type,