aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkcs11.c1106
-rw-r--r--schema.sql59
2 files changed, 373 insertions, 792 deletions
diff --git a/pkcs11.c b/pkcs11.c
index 433e7ab..b1aac5f 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -6,7 +6,7 @@
* libhal library connecting to the Cryptech FPGA cores.
*
* Author: Rob Austein
- * Copyright (c) 2015, NORDUnet A/S
+ * Copyright (c) 2015-2016, NORDUnet A/S
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -153,17 +153,17 @@ typedef struct p11_session {
CK_VOID_PTR application; /* Application data */
sqlite3_stmt *find_query; /* FindObject*() query state */
int find_query_done; /* find_query has terminated */
- const hal_hash_descriptor_t
- *digest_descriptor, /* Hash for C_Digest*() */
- *sign_digest_descriptor, /* Hash for C_Sign*() */
- *verify_digest_descriptor; /* Hash for C_Verify*() */
+ hal_digest_algorithm_t
+ digest_algorithm, /* Hash algorithm for C_Digest*() */
+ sign_digest_algorithm, /* Hash algorithm for C_Sign*() */
+ verify_digest_algorithm; /* Hash algorithm for C_Verify*() */
CK_OBJECT_HANDLE
- sign_key_handle, /* Key for C_Sign*() */
- verify_key_handle; /* Key for C_Verify() */
- hal_hash_state_t
- *digest_state, /* Hash state for C_Digest*() */
- *sign_digest_state, /* Hash state for C_Sign*() */
- *verify_digest_state; /* Hash state for C_Verify*() */
+ sign_key_handle, /* Private key for C_Sign*() */
+ verify_key_handle; /* Public key for C_Verify() */
+ hal_hash_handle_t
+ digest_handle, /* Hash state for C_Digest*() */
+ sign_digest_handle, /* Hash state for C_Sign*() */
+ verify_digest_handle; /* Hash state for C_Verify*() */
} p11_session_t;
/*
@@ -505,6 +505,28 @@ static int ec_curve_oid_to_name(const uint8_t * const oid, const size_t oid_len,
return 1;
}
+/*
+ * Extract libhal-compatible client and session identifiers from a session.
+ *
+ * libhal's session identifiers are deliberately chosen to be in the same
+ * numeric range as PKCS #11's, so we can just use them directly.
+ *
+ * libhal's client identifiers are multiplexing extension handled elsewhere,
+ * for our purposes using constant client identifier of zero will do.
+ */
+
+static inline hal_client_handle_t p11_session_hal_client(const p11_session_t * const session)
+{
+ hal_client_handle_t handle = {0};
+ return handle;
+}
+
+static inline hal_session_handle_t p11_session_hal_session(const p11_session_t * const session)
+{
+ hal_session_handle_t handle = {session->handle};
+ return handle;
+}
+
/*
@@ -1173,302 +1195,99 @@ static CK_OBJECT_HANDLE p11_object_create(const p11_session_t *session,
}
/*
- * Store a private key.
- *
- * Write the key as DER, encrypt that using AES key wrap, and store
- * the result as an SQL blob.
- *
- * We jump through a few minor hoops to let us do all the encoding and
- * wrapping in place in a single buffer.
+ * Construct libhal type code for a key object.
*/
-static int p11_object_set_generic_private_key(const CK_OBJECT_HANDLE object_handle,
- const void * const key,
- const size_t key_der_len,
- hal_error_t (*to_der)(const void * const, uint8_t *, size_t *, const size_t))
+static int p11_object_pkey_type(const CK_OBJECT_HANDLE object_handle,
+ hal_key_type_t *pkey_type)
{
- static const char select_kek[] =
- " SELECT kek FROM global";
-
- static const char update_format[] =
- " UPDATE %s_object SET private_key = ?1"
- " WHERE %s_object_id = (SELECT %s_object_id FROM object WHERE object_handle = ?2)";
+ static const char update_pkey_type[] =
+ " UPDATE object SET hal_pkey_type = ?2 WHERE object_handle = ?1";
- uint8_t wrapbuf[hal_aes_keywrap_ciphertext_length(key_der_len)];
- const char *flavor = is_token_handle(object_handle) ? "token" : "session";
- size_t der_len, wrapbuf_len = sizeof(wrapbuf);
- sqlite3_stmt *q = NULL;
- int ok = 0;
+ assert(pkey_type != NULL);
- assert(to_der);
-
- if (!sql_check_ok(sql_prepare(&q, select_kek)) ||
- !sql_check_row(sqlite3_step(q)) ||
- sqlite3_column_type(q, 0) == SQLITE_NULL ||
- !hal_check(to_der(key, wrapbuf + 8, &der_len, sizeof(wrapbuf) - 8)) ||
- !hal_check(hal_aes_keywrap(NULL,
- sqlite3_column_blob(q, 0),
- sqlite3_column_bytes(q, 0),
- wrapbuf+8, der_len, wrapbuf, &wrapbuf_len)) ||
- !sql_check_ok(sql_finalize_and_clear(&q)) ||
- !sql_check_ok(sql_prepare(&q, update_format, flavor, flavor, flavor)) ||
- !sql_check_ok(sqlite3_bind_blob( q, 1, wrapbuf, wrapbuf_len, NULL)) ||
- !sql_check_ok(sqlite3_bind_int64(q, 2, object_handle)) ||
- !sql_check_done(sqlite3_step(q)))
- goto fail;
-
- ok = 1;
+ CK_OBJECT_CLASS cka_class;
+ CK_KEY_TYPE cka_key_type;
- fail:
- memset(wrapbuf, 0, sizeof(wrapbuf));
- sqlite3_finalize(q);
- return ok;
-}
+ if (!p11_attribute_get_ulong(object_handle, CKA_CLASS, &cka_class) ||
+ !p11_attribute_get_ulong(object_handle, CKA_KEY_TYPE, &cka_key_type))
+ return 0;
+
+ else if (cka_class == CKO_PRIVATE_KEY && cka_key_type == CKK_RSA)
+ *pkey_type = HAL_KEY_TYPE_RSA_PRIVATE;
-/*
- * Store an RSA private key.
- *
- * Use p11_object_set_generic_private_key() to wrap the PKCS #1.5
- * RSAPrivateKey encoding of the private key.
- */
+ else if (cka_class == CKO_PRIVATE_KEY && cka_key_type == CKK_EC)
+ *pkey_type = HAL_KEY_TYPE_EC_PRIVATE;
-static hal_error_t p11_object_encode_rsa_key(const void * const key,
- uint8_t * der,
- size_t *der_len,
- const size_t der_max)
-{
- return hal_rsa_private_key_to_der(key, der, der_len, der_max);
-}
+ else if (cka_class == CKO_PUBLIC_KEY && cka_key_type == CKK_RSA)
+ *pkey_type = HAL_KEY_TYPE_RSA_PUBLIC;
-static int p11_object_set_rsa_private_key(const CK_OBJECT_HANDLE object_handle,
- const hal_rsa_key_t * const key)
-{
- return p11_object_set_generic_private_key(object_handle,
- key,
- hal_rsa_private_key_to_der_len(key),
- p11_object_encode_rsa_key);
-}
+ else if (cka_class == CKO_PUBLIC_KEY && cka_key_type == CKK_EC)
+ *pkey_type = HAL_KEY_TYPE_EC_PUBLIC;
-/*
- * Store an EC private key.
- *
- * Use p11_object_set_generic_private_key() to wrap the RFC 5915
- * ECPrivateKey encoding of the private key.
- */
+ else
+ *pkey_type = HAL_KEY_TYPE_NONE;
-static hal_error_t p11_object_encode_ec_key(const void * const key,
- uint8_t * der,
- size_t *der_len,
- const size_t der_max)
-{
- return hal_ecdsa_private_key_to_der(key, der, der_len, der_max);
-}
+ sqlite3_stmt *q = NULL;
-static int p11_object_set_ec_private_key(const CK_OBJECT_HANDLE object_handle,
- const hal_ecdsa_key_t * const key)
-{
- return p11_object_set_generic_private_key(object_handle,
- key,
- hal_ecdsa_private_key_to_der_len(key),
- p11_object_encode_ec_key);
+ return (sql_check_ok(sql_prepare(&q, update_pkey_type)) &&
+ sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) &&
+ sql_check_ok(sqlite3_bind_int64(q, 2, *pkey_type)) &&
+ sql_check_done(sqlite3_step(q)) &&
+ sql_check_ok(sqlite3_finalize(q)));
}
/*
- * Fetch a private key.
- *
- * Retrieve SQL blob from the object, unwrap that to get the DER
- * encoding, load the key from that.
- *
- * If the key isn't set, we return success with null key.
+ * Fetch the libhal pkey handle for a key object.
*/
-static int p11_object_get_generic_private_key(const CK_OBJECT_HANDLE object_handle,
- void **key,
- uint8_t *keybuf, const size_t keybuf_len,
- hal_error_t (*from_der)(void **, void *,
- const size_t, const uint8_t * const, const size_t))
+static int p11_object_get_pkey_handle(const p11_session_t * const session,
+ const CK_OBJECT_HANDLE object_handle,
+ hal_pkey_handle_t *pkey_handle)
{
static const char select_format[] =
- " SELECT kek, private_key FROM global, %s_object NATURAL JOIN object WHERE object_handle = ?1";
+ " SELECT value, hal_pkey_type FROM %s_attribute NATURAL JOIN object"
+ " WHERE object_handle = ?1 AND type = %u";
const char *flavor = is_token_handle(object_handle) ? "token" : "session";
+
+ hal_key_type_t pkey_type;
sqlite3_stmt *q = NULL;
int ok;
- assert(key != NULL && keybuf != NULL);
+ assert(pkey_handle != NULL);
- /*
- * Pull everything we need from the database.
- */
+ ok = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_ID)) &&
+ sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) &&
+ sql_check_row(sqlite3_step(q)));
- if (!sql_check_ok(sql_prepare(&q, select_format, flavor)) ||
- !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) ||
- !sql_check_row(sqlite3_step(q)) ||
- sqlite3_column_type(q, 0) == SQLITE_NULL) {
- ok = 0;
- }
+ if (!ok)
+ goto fail;
- else if (sqlite3_column_type(q, 1) == SQLITE_NULL) {
- *key = NULL;
- ok = 1;
- }
+ switch (sqlite3_column_type(q, 1)) {
- else {
- const uint8_t * const kek = sqlite3_column_blob(q, 0);
- const uint8_t * const pkey = sqlite3_column_blob(q, 1);
- const size_t kek_len = sqlite3_column_bytes(q, 0);
- const size_t pkey_len = sqlite3_column_bytes(q, 1);
- size_t wrapbuf_len = pkey_len;
- uint8_t wrapbuf[pkey_len];
+ case SQLITE_INTEGER:
+ pkey_type = (hal_key_type_t) sqlite3_column_int64(q, 1);
+ break;
- ok = (hal_check(hal_aes_keyunwrap(NULL, kek, kek_len, pkey, pkey_len, wrapbuf, &wrapbuf_len)) &&
- hal_check(from_der(key, keybuf, keybuf_len, wrapbuf, wrapbuf_len)));
+ case SQLITE_NULL:
+ ok = p11_object_pkey_type(object_handle, &pkey_type);
+ if (!ok)
+ goto fail;
+ break;
- memset(wrapbuf, 0, sizeof(wrapbuf));
+ default:
+ ok = 0;
+ goto fail;
}
- if (!ok || *key == NULL)
- memset(keybuf, 0, keybuf_len);
-
- sqlite3_finalize(q);
- return ok;
-}
-
-/*
- * Fetch an RSA private key.
- *
- * Use p11_object_get_generic_private_key() to unwrap the DER encoding
- * of a PKCS #1.5 RSAPrivateKey object.
- */
-
-static hal_error_t p11_object_decode_rsa_key(void **key_,
- void *keybuf, const size_t keybuf_len,
- const uint8_t * const der, const size_t der_len)
-{
- assert(key_ != NULL);
- hal_rsa_key_t *key = NULL;
- hal_error_t err = hal_rsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len);
- *key_ = key;
- return err;
-}
-
-static int p11_object_get_rsa_private_key(const CK_OBJECT_HANDLE object_handle,
- hal_rsa_key_t **key,
- uint8_t *keybuf, const size_t keybuf_len)
-{
- assert(key != NULL);
- void *key_ = NULL;
- int ok = p11_object_get_generic_private_key(object_handle, &key_, keybuf, keybuf_len, p11_object_decode_rsa_key);
- *key = key_;
- return ok;
-}
-
-/*
- * Fetch an EC private key.
- *
- * Use p11_object_get_generic_private_key() to unwrap the DER encoding
- * of an RFC 5915 ECPrivateKey object.
- */
-
-static hal_error_t p11_object_decode_ec_key(void **key_,
- void *keybuf, const size_t keybuf_len,
- const uint8_t * const der, const size_t der_len)
-{
- assert(key_ != NULL);
- hal_ecdsa_key_t *key = NULL;
- hal_error_t err = hal_ecdsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len);
- *key_ = key;
- return err;
-}
-
-static int p11_object_get_ec_private_key(const CK_OBJECT_HANDLE object_handle,
- hal_ecdsa_key_t **key,
- uint8_t *keybuf, const size_t keybuf_len)
-{
- assert(key != NULL);
- void *key_ = NULL;
- int ok = p11_object_get_generic_private_key(object_handle, &key_, keybuf, keybuf_len, p11_object_decode_ec_key);
- *key = key_;
- return ok;
-}
-
-#warning Revisit return semantics of p11_object_get_*_private_key() and p11_object_*_rsa_public_key()
-
-/*
- * Fetch an RSA public key.
- *
- * Public keys aren't stored separately the way that private keys are,
- * so we're looking for the public components so we can load them into
- * a key object.
- */
-
-static int p11_object_get_rsa_public_key(const CK_OBJECT_HANDLE object_handle,
- hal_rsa_key_t **key,
- uint8_t *keybuf, const size_t keybuf_len)
-{
- static const char select_format[] =
- " WITH a (type, value) "
- " AS (SELECT type, value FROM %s_attribute NATURAL JOIN object WHERE object_handle = ?1)"
- " SELECT a1.value, a2.value FROM a AS a1, a AS a2 WHERE a1.type = %u AND a2.type = %u";
-
- const char *flavor = is_token_handle(object_handle) ? "token" : "session";
- sqlite3_stmt *q = NULL;
-
- assert(key != NULL && keybuf != NULL);
-
- const int ok = (sql_check_ok(sql_prepare(&q, select_format, flavor,
- CKA_MODULUS, CKA_PUBLIC_EXPONENT)) &&
- sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) &&
- sql_check_row(sqlite3_step(q)) &&
- sqlite3_column_type(q, 0) == SQLITE_BLOB &&
- sqlite3_column_type(q, 1) == SQLITE_BLOB &&
- hal_check(hal_rsa_key_load_public(key, keybuf, keybuf_len,
- sqlite3_column_blob( q, 0),
- sqlite3_column_bytes(q, 0),
- sqlite3_column_blob( q, 1),
- sqlite3_column_bytes(q, 1))));
-
- sqlite3_finalize(q);
- return ok;
-}
-
-/*
- * Fetch an EC public key.
- *
- * Public keys aren't stored separately the way that private keys are,
- * so we're looking for the public components so we can load them into
- * a key object.
- */
-
-static int p11_object_get_ec_public_key(const CK_OBJECT_HANDLE object_handle,
- hal_ecdsa_key_t **key,
- uint8_t *keybuf, const size_t keybuf_len)
-{
- static const char select_format[] =
- " WITH a (type, value) "
- " AS (SELECT type, value FROM %s_attribute NATURAL JOIN object WHERE object_handle = ?1)"
- " SELECT a1.value, a2.value FROM a AS a1, a AS a2 WHERE a1.type = %u AND a2.type = %u";
-
- const char *flavor = is_token_handle(object_handle) ? "token" : "session";
- sqlite3_stmt *q = NULL;
- hal_curve_name_t curve;
-
- assert(key != NULL && keybuf != NULL);
-
- const int ok = (sql_check_ok(sql_prepare(&q, select_format, flavor,
- CKA_EC_PARAMS, CKA_EC_POINT)) &&
- sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) &&
- sql_check_row(sqlite3_step(q)) &&
- sqlite3_column_type(q, 0) == SQLITE_BLOB &&
- sqlite3_column_type(q, 1) == SQLITE_BLOB &&
- ec_curve_oid_to_name(sqlite3_column_blob( q, 0),
- sqlite3_column_bytes(q, 0),
- &curve) &&
- hal_check(hal_ecdsa_key_from_ecpoint(key, keybuf, keybuf_len,
- sqlite3_column_blob( q, 1),
- sqlite3_column_bytes(q, 1),
- curve)));
+ ok = hal_check(hal_rpc_pkey_find(p11_session_hal_client(session),
+ p11_session_hal_session(session),
+ pkey_handle, pkey_type,
+ sqlite3_column_blob(q, 0),
+ sqlite3_column_bytes(q, 0)));
+ fail:
sqlite3_finalize(q);
return ok;
}
@@ -1502,9 +1321,9 @@ static void p11_session_free(p11_session_t *session)
return;
sql_finalize_and_clear(&session->find_query);
- hal_hash_cleanup(&session->digest_state);
- hal_hash_cleanup(&session->sign_digest_state);
- hal_hash_cleanup(&session->verify_digest_state);
+ (void) hal_rpc_hash_finalize(session->digest_handle, NULL, 0);
+ (void) hal_rpc_hash_finalize(session->sign_digest_handle, NULL, 0);
+ (void) hal_rpc_hash_finalize(session->verify_digest_handle, NULL, 0);
free(session);
}
@@ -1917,14 +1736,13 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
const CK_ULONG ulPrivateKeyAttributeCount,
const CK_OBJECT_HANDLE private_handle,
- const CK_OBJECT_HANDLE public_handle)
+ const CK_OBJECT_HANDLE public_handle,
+ const uint8_t * const id, const size_t id_len)
{
const uint8_t *public_exponent = const_0x010001;
size_t public_exponent_len = sizeof(const_0x010001);
- uint8_t keybuf[hal_rsa_key_t_size];
- hal_rsa_key_t *key = NULL;
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
CK_ULONG keysize = 0;
- size_t modulus_len;
CK_RV rv;
int i;
@@ -1950,26 +1768,31 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
}
}
- if (keysize == 0)
+ if (keysize == 0 || id == NULL)
return CKR_TEMPLATE_INCOMPLETE;
- memset(keybuf, 0, sizeof(keybuf));
+#warning Should do something here with pkey flags
- if (!hal_check(hal_rsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), keysize / 8,
- public_exponent, public_exponent_len)))
+ if (!hal_check(hal_rpc_pkey_generate_rsa(p11_session_hal_client(session),
+ p11_session_hal_session(session),
+ &pkey, id, id_len, keysize / 8,
+ public_exponent, public_exponent_len, 0)))
lose(CKR_FUNCTION_FAILED);
- if (!p11_object_set_rsa_private_key(private_handle, key))
- lose(CKR_FUNCTION_FAILED);
+ {
+ uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_rsa_key_t_size];
+ size_t der_len, modulus_len;
+ hal_rsa_key_t *key = NULL;
- if (!hal_check(hal_rsa_key_get_modulus(key, NULL, &modulus_len, 0)))
- lose(CKR_FUNCTION_FAILED);
+ if (!hal_check(hal_rpc_pkey_get_public_key(pkey, der, &der_len, sizeof(der))) ||
+ !hal_check(hal_rsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)) ||
+ !hal_check(hal_rsa_key_get_modulus(key, NULL, &modulus_len, 0)))
+ lose(CKR_FUNCTION_FAILED);
- {
uint8_t modulus[modulus_len];
- if (!hal_check(hal_rsa_key_get_modulus(key, modulus, &modulus_len, sizeof(modulus))) ||
- !p11_attribute_set(public_handle, CKA_MODULUS, modulus, modulus_len) ||
+ if (!hal_check(hal_rsa_key_get_modulus(key, modulus, NULL, sizeof(modulus))) ||
+ !p11_attribute_set(public_handle, CKA_MODULUS, modulus, modulus_len) ||
!p11_attribute_set(private_handle, CKA_MODULUS, modulus, modulus_len))
lose(CKR_FUNCTION_FAILED);
}
@@ -1977,7 +1800,7 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
rv = CKR_OK;
fail:
- hal_rsa_key_clear(key);
+ hal_rpc_pkey_close(pkey);
return rv;
}
@@ -1986,15 +1809,15 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
*/
static CK_RV generate_keypair_ec(p11_session_t *session,
- const CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- const CK_ULONG ulPublicKeyAttributeCount,
- const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- const CK_ULONG ulPrivateKeyAttributeCount,
- const CK_OBJECT_HANDLE private_handle,
- const CK_OBJECT_HANDLE public_handle)
+ const CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ const CK_ULONG ulPublicKeyAttributeCount,
+ const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ const CK_ULONG ulPrivateKeyAttributeCount,
+ const CK_OBJECT_HANDLE private_handle,
+ const CK_OBJECT_HANDLE public_handle,
+ const uint8_t * const id, const size_t id_len)
{
- uint8_t keybuf[hal_ecdsa_key_t_size];
- hal_ecdsa_key_t *key = NULL;
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
const CK_BYTE *params = NULL;
hal_curve_name_t curve;
size_t params_len;
@@ -2017,18 +1840,25 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
}
}
- if (!ec_curve_oid_to_name(params, params_len, &curve))
+ if (!ec_curve_oid_to_name(params, params_len, &curve) || id == NULL)
return CKR_TEMPLATE_INCOMPLETE;
- memset(keybuf, 0, sizeof(keybuf));
-
- if (!hal_check(hal_ecdsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), curve)) ||
- !p11_object_set_ec_private_key(private_handle, key) ||
+ if (!hal_check(hal_rpc_pkey_generate_ec(p11_session_hal_client(session),
+ p11_session_hal_session(session),
+ &pkey, id, id_len, curve, 0)) ||
!p11_attribute_set(public_handle, CKA_EC_PARAMS, params, params_len) ||
!p11_attribute_set(private_handle, CKA_EC_PARAMS, params, params_len))
lose(CKR_FUNCTION_FAILED);
{
+ uint8_t der[hal_rpc_pkey_get_public_key_len(pkey)], keybuf[hal_ecdsa_key_t_size];
+ hal_ecdsa_key_t *key = NULL;
+ size_t der_len;
+
+ if (!hal_check(hal_rpc_pkey_get_public_key(pkey, der, &der_len, sizeof(der))) ||
+ !hal_check(hal_ecdsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)))
+ lose(CKR_FUNCTION_FAILED);
+
uint8_t point[hal_ecdsa_key_to_ecpoint_len(key)];
if (!hal_check(hal_ecdsa_key_to_ecpoint(key, point, NULL, sizeof(point))) ||
@@ -2039,7 +1869,7 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
rv = CKR_OK;
fail:
- hal_ecdsa_key_clear(key);
+ hal_rpc_pkey_close(pkey);
return rv;
}
@@ -2062,7 +1892,8 @@ static CK_RV generate_keypair(p11_session_t *session,
const CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
const CK_ULONG ulPrivateKeyAttributeCount,
const CK_OBJECT_HANDLE private_handle,
- const CK_OBJECT_HANDLE public_handle),
+ const CK_OBJECT_HANDLE public_handle,
+ const uint8_t * const id, const size_t id_len),
const p11_descriptor_t * const public_descriptor,
const p11_descriptor_t * const private_descriptor)
{
@@ -2104,11 +1935,29 @@ static CK_RV generate_keypair(p11_session_t *session,
private_descriptor, pMechanism)) == CK_INVALID_HANDLE)
lose(CKR_FUNCTION_FAILED);
- if ((rv = mechanism_handler(session,
- pPublicKeyTemplate, ulPublicKeyAttributeCount,
- pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
- private_handle, public_handle)) != CKR_OK)
- goto fail;
+ {
+ size_t public_id_len = 0, private_id_len = 0;
+
+ if (!p11_attribute_get(public_handle, CKA_ID, NULL, &public_id_len, 0) ||
+ !p11_attribute_get(private_handle, CKA_ID, NULL, &public_id_len, 0))
+ lose(CKR_TEMPLATE_INCOMPLETE);
+
+ uint8_t public_id[public_id_len], private_id[private_id_len];
+
+ if (!p11_attribute_get(public_handle, CKA_ID, public_id, NULL, public_id_len) ||
+ !p11_attribute_get(private_handle, CKA_ID, private_id, NULL, public_id_len))
+ lose(CKR_TEMPLATE_INCOMPLETE);
+
+ if (public_id_len != private_id_len || memcmp(public_id, private_id, public_id_len) != 0)
+ lose(CKR_TEMPLATE_INCONSISTENT);
+
+ if ((rv = mechanism_handler(session,
+ pPublicKeyTemplate, ulPublicKeyAttributeCount,
+ pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
+ private_handle, public_handle,
+ public_id, public_id_len)) != CKR_OK)
+ goto fail;
+ }
if (!sql_exec("COMMIT"))
lose(CKR_FUNCTION_FAILED);
@@ -2192,14 +2041,17 @@ static CK_RV p11_check_create_attributes(const p11_session_t *session,
* Add data to a digest.
*/
-static CK_RV digest_update(const hal_hash_descriptor_t * const descriptor,
- hal_hash_state_t **state,
+static CK_RV digest_update(const p11_session_t * const session,
+ const hal_digest_algorithm_t algorithm,
+ hal_hash_handle_t *handle,
const uint8_t * const data, const size_t data_len)
{
- assert(descriptor != NULL && state != NULL && data != NULL);
+ assert(algorithm != hal_digest_algorithm_none && handle != NULL && data != NULL);
- if (*state == NULL) {
- switch (hal_hash_initialize(NULL, descriptor, state, NULL, 0)) {
+ if (handle->handle == HAL_HANDLE_NONE) {
+ switch (hal_rpc_hash_initialize(p11_session_hal_client(session),
+ p11_session_hal_session(session),
+ handle, algorithm, NULL, 0)) {
case HAL_OK:
break;
case HAL_ERROR_ALLOCATION_FAILURE:
@@ -2209,130 +2061,88 @@ static CK_RV digest_update(const hal_hash_descriptor_t * const descriptor,
}
}
- if (!hal_check(hal_hash_update(*state, data, data_len)))
+ if (!hal_check(hal_rpc_hash_update(*handle, data, data_len)))
return CKR_FUNCTION_FAILED;
return CKR_OK;
}
/*
- * Construct a PKCS #1 DigestInfo object. This requires some (very
- * basic) ASN.1 encoding, which we perform inline.
+ * Finish using a digest context, if we haven't already.
*/
-static int pkcs1_construct_digestinfo(const hal_hash_descriptor_t * const desc,
- hal_hash_state_t *state,
- uint8_t *digest_info, const size_t digest_info_len)
+static void digest_cleanup(hal_hash_handle_t *handle)
{
- assert(desc != NULL && state != NULL && digest_info != NULL);
-
- /*
- * Make sure size of output buffer is right. Caller is responsible
- * for supplying the right length, the check here is just paranoia.
- *
- * This encoder will fail if the DigestInfo object is more than
- * 129 octets long. Rewrite if and when we need to support
- * digests or OIDs long enough for that to be an issue.
- */
-
- assert(digest_info_len == desc->digest_length + desc->digest_algorithm_id_length + 4);
- assert(digest_info_len < 130);
-
- uint8_t *d = digest_info;
-
- *d++ = 0x30; /* SEQUENCE */
- *d++ = (uint8_t) (digest_info_len - 2);
-
- memcpy(d, desc->digest_algorithm_id, desc->digest_algorithm_id_length);
- d += desc->digest_algorithm_id_length;
-
- *d++ = 0x04; /* OCTET STRING */
- *d++ = (uint8_t) desc->digest_length;
-
- assert(digest_info + digest_info_len == d + desc->digest_length);
-
- return hal_check(hal_hash_finalize(state, d, desc->digest_length));
+ assert(handle != NULL);
+ if (handle->handle == HAL_HANDLE_NONE)
+ return;
+ (void) hal_rpc_hash_finalize(*handle, NULL, 0);
+ handle->handle = HAL_HANDLE_NONE;
}
/*
- * Pad an octet string with PKCS #1.5 padding for use with RSA.
- *
- * For the moment, this only handles type 01 encryption blocks, thus
- * is only suitable for use with signature and verification. If and
- * when we add support for encryption and decryption, this function
- * should be extended to take an argument specifying the block type
- * and include support for generating type 02 encryption blocks.
- * Other than the block type code, the only difference is the padding
- * value: for type 01 it's constant (0xFF), for type 02 it should be
- * non-zero random bytes from the CSPRNG.
+ * Compute the length of a signature based on the key. We could get
+ * this via the RPC API, but its probably faster to look in the local
+ * attribute database. Rewrite this later if this proves incorrect.
*/
-static int pkcs1_5_pad(const uint8_t * const data, const size_t data_len,
- uint8_t *block, const size_t block_len)
+static int get_signature_len(const CK_OBJECT_HANDLE object_handle,
+ const hal_pkey_handle_t pkey,
+ size_t *signature_len)
{
- assert(data != NULL && block != NULL);
+ assert(signature_len != NULL);
- /*
- * Congregation will now please turn to RFC 2313 8.1 as we
- * construct a PKCS #1.5 type 01 encryption block.
- */
+ CK_KEY_TYPE cka_key_type;
+ hal_curve_name_t curve;
+ CK_BYTE oid[20];
+ CK_ULONG len;
- if (data_len > block_len - 11)
+ if (!p11_attribute_get_ulong(object_handle, CKA_KEY_TYPE, &cka_key_type))
return 0;
- block[0] = 0x00;
- block[1] = 0x01;
+ switch (cka_key_type) {
- /* This is where we'd use non-zero random bytes if constructing a type 02 block. */
- memset(block + 2, 0xFF, block_len - 3 - data_len);
-
- block[block_len - data_len - 1] = 0x00;
- memcpy(block + block_len - data_len, data, data_len);
+ case CKK_RSA:
+ if (!p11_attribute_get(object_handle, CKA_MODULUS, NULL, &len, 0))
+ return 0;
+ *signature_len = len;
+ return 1;
-#if DEBUG_PKCS11 > 1
- fprintf(stderr, "[PKCS #1.5 block_len %lu data_len %lu block ",
- (unsigned long) block_len, (unsigned long) data_len);
- for (int i = 0; i < block_len; i++)
- fprintf(stderr, "%s%02x", i == 0 ? "" : ":", block[i]);
- fprintf(stderr, "]\n");
-#endif
+ case CKK_EC:
+ if (!p11_attribute_get(object_handle, CKA_EC_PARAMS, oid, &len, sizeof(oid)) ||
+ !ec_curve_oid_to_name(oid, len, &curve))
+ return 0;
+ switch (curve) {
+ case HAL_CURVE_P256: *signature_len = 64; return 1;
+ case HAL_CURVE_P384: *signature_len = 96; return 1;
+ case HAL_CURVE_P521: *signature_len = 132; return 1;
+ default: return 0;
+ }
+ }
- return 1;
+ return 0;
}
/*
- * Generate an RSA PKCS #1.5 signature.
- *
- * As explained in RFC 3447, the RSASP1 (signature generation)
- * operation is the same mathematical operation as the RSADP
- * (decryption) operation (both use the private key as exponent).
+ * Generate a signature using the libhal RPC API.
*/
-static CK_RV sign_rsa_pkcs(p11_session_t *session,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
+static CK_RV sign_hal_rpc(p11_session_t *session,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen)
{
- uint8_t keybuf[hal_rsa_key_t_size];
- hal_rsa_key_t *key = NULL;
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
size_t signature_len;
CK_RV rv;
assert(session != NULL && pulSignatureLen != NULL);
- const hal_hash_descriptor_t * const descriptor = session->sign_digest_descriptor;
- uint8_t digest_info[descriptor == NULL ? 1 : descriptor->digest_length + 4 + descriptor->digest_algorithm_id_length];
-
- if (!p11_object_get_rsa_private_key(session->sign_key_handle,
- &key, keybuf, sizeof(keybuf)))
+ if (!p11_object_get_pkey_handle(session, session->sign_key_handle, &pkey))
lose(CKR_FUNCTION_FAILED);
- /*
- * Retrieve signature length, which is just the the modulus length.
- */
-
- if (!hal_check(hal_rsa_key_get_modulus(key, NULL, &signature_len, 0)))
+ if (!get_signature_len(session->sign_key_handle, pkey, &signature_len))
lose(CKR_FUNCTION_FAILED);
rv = signature_len > *pulSignatureLen ? CKR_BUFFER_TOO_SMALL : CKR_OK;
@@ -2342,205 +2152,53 @@ static CK_RV sign_rsa_pkcs(p11_session_t *session,
if (pSignature != NULL && rv == CKR_BUFFER_TOO_SMALL)
lose(CKR_BUFFER_TOO_SMALL);
- if (pSignature != NULL && descriptor != NULL) {
-
- if (!pkcs1_construct_digestinfo(descriptor, session->sign_digest_state, digest_info, sizeof(digest_info)))
- lose(CKR_FUNCTION_FAILED);
-
- pData = digest_info;
- ulDataLen = sizeof(digest_info);
- }
-
- if (pSignature != NULL) {
-
- if (!pkcs1_5_pad(pData, ulDataLen, pSignature, signature_len))
- lose(CKR_DATA_LEN_RANGE);
-
- if (!hal_check(hal_rsa_decrypt(NULL, key, pSignature, signature_len, pSignature, signature_len)))
- lose(CKR_FUNCTION_FAILED);
- }
+#warning Should pay more attention to translating error codes here
+ if (pSignature != NULL &&
+ !hal_check(hal_rpc_pkey_sign(p11_session_hal_session(session), pkey, session->sign_digest_handle,
+ pData, ulDataLen, pSignature, pulSignatureLen, signature_len)))
+ lose(CKR_FUNCTION_FAILED);
rv = CKR_OK; /* Fall through */
fail:
- hal_rsa_key_clear(key);
+ hal_rpc_pkey_close(pkey);
return rv;
}
/*
- * Verify a PKCS #1.5 padded RSA signature.
- *
- * We don't bother decoding the ASN.1, we just generate the type 01
- * encryption block we expect and compare it with what we got.
- *
- * Using constant-time comparision code for this is probably
- * unnecessary, but it's also harmless.
+ * Verify a signature using the libhal RPC API.
*/
-static CK_RV verify_rsa_pkcs(p11_session_t *session,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen)
+static CK_RV verify_hal_rpc(p11_session_t *session,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
{
- uint8_t keybuf[hal_rsa_key_t_size];
- hal_rsa_key_t *key = NULL;
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
CK_RV rv;
assert(session != NULL);
- const hal_hash_descriptor_t * const descriptor = session->verify_digest_descriptor;
- uint8_t digest_info[descriptor == NULL ? 1 : descriptor->digest_length + 4 + descriptor->digest_algorithm_id_length];
- uint8_t expected[ulSignatureLen], received[ulSignatureLen];
- unsigned diff = 0;
-
- if (!p11_object_get_rsa_public_key(session->verify_key_handle,
- &key, keybuf, sizeof(keybuf)))
+ if (!p11_object_get_pkey_handle(session, session->verify_key_handle, &pkey))
lose(CKR_FUNCTION_FAILED);
- if (session->verify_digest_descriptor != NULL) {
-
- if (!pkcs1_construct_digestinfo(session->verify_digest_descriptor,
- session->verify_digest_state,
- digest_info, sizeof(digest_info)))
- lose(CKR_FUNCTION_FAILED);
-
- pData = digest_info;
- ulDataLen = sizeof(digest_info);
-
- }
-
- if (!pkcs1_5_pad(pData, ulDataLen, expected, sizeof(expected)))
- lose(CKR_DATA_LEN_RANGE);
+#warning Should pay more attention to translating error codes here
- if (!hal_check(hal_rsa_encrypt(NULL, key, pSignature, ulSignatureLen, received, sizeof(received))))
+ if (!hal_check(hal_rpc_pkey_verify(p11_session_hal_session(session), pkey, session->verify_digest_handle,
+ pData, ulDataLen, pSignature, ulSignatureLen)))
lose(CKR_FUNCTION_FAILED);
-
- for (int i = 0; i < ulSignatureLen; i++)
- diff |= expected[i] ^ received[i];
-
- if (diff != 0)
- lose(CKR_SIGNATURE_INVALID);
+ /* lose(CKR_SIGNATURE_INVALID); */
rv = CKR_OK; /* Fall through */
fail:
- hal_rsa_key_clear(key);
+ hal_rpc_pkey_close(pkey);
return rv;
}
#warning May need to do something about truncating oversized hashes for ECDSA, see PKCS11 spec
-/*
- * Generate an ECDSA signature.
- */
-
-static CK_RV sign_ecdsa(p11_session_t *session,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
-{
- uint8_t keybuf[hal_ecdsa_key_t_size];
- hal_ecdsa_key_t *key = NULL;
- hal_curve_name_t curve;
- size_t signature_len;
- CK_RV rv;
-
- assert(session != NULL && pulSignatureLen != NULL);
-
- const hal_hash_descriptor_t * const descriptor = session->sign_digest_descriptor;
- uint8_t digest[descriptor == NULL ? 1 : descriptor->digest_length];
-
- if (!p11_object_get_ec_private_key(session->sign_key_handle, &key, keybuf, sizeof(keybuf)))
- lose(CKR_FUNCTION_FAILED);
-
- /*
- * Signature length is determined by curve parameters.
- */
-
- if (!hal_check(hal_ecdsa_key_get_curve(key, &curve)))
- lose(CKR_FUNCTION_FAILED);
-
- switch (curve) {
- case HAL_CURVE_P256: signature_len = 256; break;
- case HAL_CURVE_P384: signature_len = 384; break;
- case HAL_CURVE_P521: signature_len = 521; break;
- default: lose(CKR_FUNCTION_FAILED);
- }
-
- signature_len = ((signature_len + 7) / 8) * 2;
-
- rv = signature_len > *pulSignatureLen ? CKR_BUFFER_TOO_SMALL : CKR_OK;
-
- *pulSignatureLen = signature_len;
-
- if (pSignature != NULL && rv == CKR_BUFFER_TOO_SMALL)
- lose(CKR_BUFFER_TOO_SMALL);
-
- if (pSignature != NULL && descriptor != NULL) {
-
- if (!hal_check(hal_hash_finalize(session->sign_digest_state, digest, sizeof(digest))))
- lose(CKR_FUNCTION_FAILED);
-
- pData = digest;
- ulDataLen = sizeof(digest);
- }
-
- if (pSignature != NULL && !hal_check(hal_ecdsa_sign(NULL, key, pData, ulDataLen,
- pSignature, &signature_len, *pulSignatureLen)))
- lose(CKR_FUNCTION_FAILED);
-
- assert(signature_len == *pulSignatureLen);
-
- rv = CKR_OK; /* Fall through */
-
- fail:
- hal_ecdsa_key_clear(key);
- return rv;
-}
-
-/*
- * Verify an ECDSA signature.
- */
-
-static CK_RV verify_ecdsa(p11_session_t *session,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen)
-{
- uint8_t keybuf[hal_ecdsa_key_t_size];
- hal_ecdsa_key_t *key = NULL;
- CK_RV rv;
-
- assert(session != NULL && pSignature != NULL);
-
- const hal_hash_descriptor_t * const descriptor = session->verify_digest_descriptor;
- uint8_t digest[descriptor == NULL ? 1 : descriptor->digest_length];
-
- if (!p11_object_get_ec_public_key(session->verify_key_handle, &key, keybuf, sizeof(keybuf)))
- lose(CKR_FUNCTION_FAILED);
-
- if (session->verify_digest_descriptor != NULL) {
-
- if (!hal_check(hal_hash_finalize(session->verify_digest_state, digest, sizeof(digest))))
- lose(CKR_FUNCTION_FAILED);
-
- pData = digest;
- ulDataLen = sizeof(digest);
- }
-
- if (!hal_check(hal_ecdsa_verify(NULL, key, pData, ulDataLen, pSignature, ulSignatureLen)))
- lose(CKR_SIGNATURE_INVALID);
-
- rv = CKR_OK; /* Fall through */
-
- fail:
- hal_ecdsa_key_clear(key);
- return rv;
-}
-
/*
@@ -2958,13 +2616,11 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_Login);
- static const char pin_query_format[] =
- " SELECT pbkdf2_iterations, %s_pin, %s_pin_salt FROM global";
-
+ const hal_client_handle_t client = {HAL_HANDLE_NONE};
p11_session_t *session;
- sqlite3_stmt *q = NULL;
- const char *pin_type;
+ hal_user_t user = HAL_USER_NONE;
CK_RV rv = CKR_OK;
+ hal_error_t err;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -2998,13 +2654,13 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession,
switch (userType) {
case CKU_USER:
- pin_type = "user";
+ user = HAL_USER_NORMAL;
break;
case CKU_SO:
for (session = p11_sessions; session != NULL; session = session->link)
if (session->state == CKS_RO_PUBLIC_SESSION)
lose(CKR_SESSION_READ_ONLY_EXISTS);
- pin_type = "so";
+ user = HAL_USER_SO;
break;
case CKU_CONTEXT_SPECIFIC:
lose(CKR_OPERATION_NOT_INITIALIZED);
@@ -3013,53 +2669,15 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession,
}
/*
- * Look up the PIN and make sure it's set.
- *
- * Not obvious what error we should return if SO PIN isn't set, for
- * now consider this state "locked" (because it hasn't been set yet).
- */
-
- if (!sql_check_ok(sql_prepare(&q, pin_query_format, pin_type, pin_type)) ||
- !sql_check_row(sqlite3_step(q)))
- lose(CKR_FUNCTION_FAILED);
-
- if (sqlite3_column_type(q, 1) == SQLITE_NULL ||
- sqlite3_column_type(q, 2) == SQLITE_NULL) {
- switch (userType) {
- case CKU_USER:
- lose(CKR_USER_PIN_NOT_INITIALIZED);
- case CKU_SO:
- lose(CKR_PIN_LOCKED);
- default:
- lose(CKR_USER_TYPE_INVALID);
- }
- }
-
- /*
- * Run PBKDF2 over the supplied PIN and compare results.
- *
- * Probably not really necessary to use constant-time string
- * comparison, but it's harmless and cheap, so we might as well.
+ * Try to log in the HSM.
*/
- {
- const unsigned iterations = sqlite3_column_int(q, 0);
- const uint8_t * const pin = sqlite3_column_blob(q, 1);
- const uint8_t * const salt = sqlite3_column_blob(q, 2);
- const size_t pin_len = sqlite3_column_bytes(q, 1);
- const size_t salt_len = sqlite3_column_bytes(q, 2);
- uint8_t pinbuf[pin_len];
- unsigned diff = 0;
-
- if (!hal_check(hal_pbkdf2(NULL, hal_hash_sha256, pPin, ulPinLen, salt, salt_len,
- pinbuf, sizeof(pinbuf), iterations)))
- lose(CKR_FUNCTION_FAILED);
-
- for (int i = 0; i < pin_len; i++)
- diff |= pin[i] ^ pinbuf[i];
-
- if (diff != 0)
+#warning Might need better error code translation here
+ if (!hal_check((err = hal_rpc_login(client, user, (char *) pPin, ulPinLen)))) {
+ if (err == HAL_ERROR_PIN_INCORRECT)
lose(CKR_PIN_INCORRECT);
+ else
+ lose(CKR_FUNCTION_FAILED);
}
/*
@@ -3089,7 +2707,6 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession,
assert(p11_session_consistent_login());
fail:
- sqlite3_finalize(q);
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3097,6 +2714,7 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
{
ENTER_PUBLIC_FUNCTION(C_Logout);
+ const hal_client_handle_t client = {HAL_HANDLE_NONE};
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3121,6 +2739,10 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
assert(p11_session_consistent_login());
+#warning Might want better error translation here
+ if (!hal_check(hal_rpc_logout(client)))
+ lose(CKR_FUNCTION_FAILED);
+
logged_in_as = not_logged_in;
p11_object_delete_all_private();
@@ -3153,6 +2775,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_CreateObject);
+ CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE;
p11_session_t *session;
CK_RV rv;
@@ -3205,7 +2828,8 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
const handle_flavor_t flavor
= cka_token == NULL ? handle_flavor_session_object : p11_handle_flavor_from_cka_token(cka_token);
- CK_OBJECT_HANDLE handle = p11_object_create(session, flavor, pTemplate, ulCount, descriptor, NULL);
+ if ((handle = p11_object_create(session, flavor, pTemplate, ulCount, descriptor, NULL)) == CK_INVALID_HANDLE)
+ lose(CKR_FUNCTION_FAILED);
if (!p11_attribute_set_bbool(handle, CKA_LOCAL, CK_FALSE))
lose(CKR_FUNCTION_FAILED);
@@ -3218,6 +2842,8 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
lose(CKR_FUNCTION_FAILED);
}
+#warning Somewhere around here we need to create a libhal key object from supplied components
+
if (!sql_exec("COMMIT"))
lose(CKR_FUNCTION_FAILED);
@@ -3244,6 +2870,7 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession,
" WHERE token_object_id = (SELECT token_object_id FROM object WHERE object_handle = ?)";
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
p11_session_t *session;
sqlite3_stmt *q = NULL;
CK_RV rv = CKR_OK;
@@ -3255,6 +2882,9 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession,
if ((rv = p11_object_check_rights(session, hObject, p11_object_access_write)) != CKR_OK)
goto fail;
+ if (p11_object_get_pkey_handle(session, hObject, &pkey) && !hal_check(hal_rpc_pkey_delete(pkey)))
+ lose(CKR_FUNCTION_FAILED);
+
if (is_token_handle(hObject) &&
(!sql_check_ok(sql_prepare(&q, delete_token_object)) ||
!sql_check_ok(sqlite3_bind_int64(q, 1, hObject)) ||
@@ -3604,6 +3234,7 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_DigestInit);
+ hal_digest_algorithm_t algorithm;
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3615,22 +3246,18 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession,
if (pMechanism == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->digest_descriptor != NULL)
+ if (session->digest_algorithm != hal_digest_algorithm_none)
lose(CKR_OPERATION_ACTIVE);
switch (pMechanism->mechanism) {
- case CKM_SHA_1: session->digest_descriptor = hal_hash_sha1; break;
- case CKM_SHA256: session->digest_descriptor = hal_hash_sha256; break;
- case CKM_SHA384: session->digest_descriptor = hal_hash_sha384; break;
- case CKM_SHA512: session->digest_descriptor = hal_hash_sha512; break;
+ case CKM_SHA_1: algorithm = hal_digest_algorithm_sha1; break;
+ case CKM_SHA256: algorithm = hal_digest_algorithm_sha256; break;
+ case CKM_SHA384: algorithm = hal_digest_algorithm_sha384; break;
+ case CKM_SHA512: algorithm = hal_digest_algorithm_sha512; break;
default: lose(CKR_MECHANISM_INVALID);
}
- if (hal_core_find(session->digest_descriptor->core_name, NULL) == NULL) {
- session->digest_descriptor = NULL;
- lose(CKR_MECHANISM_INVALID);
- }
-
+ session->digest_algorithm = algorithm;
return mutex_unlock(p11_global_mutex);
fail:
@@ -3646,6 +3273,7 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession,
ENTER_PUBLIC_FUNCTION(C_Digest);
p11_session_t *session;
+ size_t digest_len;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3656,15 +3284,18 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession,
if (pData == NULL || pulDigestLen == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->digest_descriptor == NULL)
+ if (session->digest_algorithm == hal_digest_algorithm_none)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (session->digest_state != NULL)
+ if (session->digest_handle.handle != HAL_HANDLE_NONE)
lose(CKR_OPERATION_ACTIVE);
- rv = *pulDigestLen < session->digest_descriptor->digest_length ? CKR_BUFFER_TOO_SMALL : CKR_OK;
+ if (!hal_check(hal_rpc_hash_get_digest_length(session->digest_algorithm, &digest_len)))
+ lose(CKR_FUNCTION_FAILED);
- *pulDigestLen = session->digest_descriptor->digest_length;
+ rv = *pulDigestLen < digest_len ? CKR_BUFFER_TOO_SMALL : CKR_OK;
+
+ *pulDigestLen = digest_len;
if (pDigest == NULL)
return mutex_unlock(p11_global_mutex);
@@ -3672,19 +3303,19 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession,
if (rv == CKR_BUFFER_TOO_SMALL)
lose(CKR_BUFFER_TOO_SMALL);
- if ((rv = digest_update(session->digest_descriptor, &session->digest_state,
- pData, ulDataLen)) != CKR_OK)
+ if ((rv = digest_update(session, session->digest_algorithm,
+ &session->digest_handle, pData, ulDataLen)) != CKR_OK)
goto fail;
- if (!hal_check(hal_hash_finalize(session->digest_state, pDigest, *pulDigestLen)))
+ if (!hal_check(hal_rpc_hash_finalize(session->digest_handle, pDigest, *pulDigestLen)))
lose(CKR_FUNCTION_FAILED);
rv = CKR_OK; /* Fall through */
fail:
if (session != NULL) {
- hal_hash_cleanup(&session->digest_state);
- session->digest_descriptor = NULL;
+ digest_cleanup(&session->digest_handle);
+ session->digest_algorithm = hal_digest_algorithm_none;
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3706,23 +3337,19 @@ CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession,
if (pPart == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->digest_descriptor == NULL)
+ if (session->digest_algorithm == hal_digest_algorithm_none)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (!session->digest_descriptor->can_restore_state)
- lose(CKR_FUNCTION_FAILED);
-
- if ((rv = digest_update(session->digest_descriptor,
- &session->digest_state,
- pPart, ulPartLen)) != CKR_OK)
+ if ((rv = digest_update(session, session->digest_algorithm,
+ &session->digest_handle, pPart, ulPartLen)) != CKR_OK)
goto fail;
return mutex_unlock(p11_global_mutex);
fail:
if (session != NULL) {
- hal_hash_cleanup(&session->digest_state);
- session->digest_descriptor = NULL;
+ digest_cleanup(&session->digest_handle);
+ session->digest_algorithm = hal_digest_algorithm_none;
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3734,6 +3361,7 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession,
ENTER_PUBLIC_FUNCTION(C_DigestFinal);
p11_session_t *session;
+ size_t digest_len;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3744,12 +3372,15 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession,
if (pulDigestLen == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->digest_descriptor == NULL || session->digest_state == NULL)
+ if (session->digest_algorithm == hal_digest_algorithm_none || session->digest_handle.handle == HAL_HANDLE_NONE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- rv = *pulDigestLen < session->digest_descriptor->digest_length ? CKR_BUFFER_TOO_SMALL : CKR_OK;
+ if (!hal_check(hal_rpc_hash_get_digest_length(session->digest_algorithm, &digest_len)))
+ lose(CKR_FUNCTION_FAILED);
+
+ rv = *pulDigestLen < digest_len ? CKR_BUFFER_TOO_SMALL : CKR_OK;
- *pulDigestLen = session->digest_descriptor->digest_length;
+ *pulDigestLen = digest_len;
if (pDigest == NULL)
return mutex_unlock(p11_global_mutex);
@@ -3757,15 +3388,15 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession,
if (rv == CKR_BUFFER_TOO_SMALL)
lose(CKR_BUFFER_TOO_SMALL);
- if (!hal_check(hal_hash_finalize(session->digest_state, pDigest, *pulDigestLen)))
+ if (!hal_check(hal_rpc_hash_finalize(session->digest_handle, pDigest, *pulDigestLen)))
lose(CKR_FUNCTION_FAILED);
rv = CKR_OK; /* Fall through */
fail:
if (session != NULL) {
- hal_hash_cleanup(&session->digest_state);
- session->digest_descriptor = NULL;
+ digest_cleanup(&session->digest_handle);
+ session->digest_algorithm = hal_digest_algorithm_none;
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3790,7 +3421,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
if (pMechanism == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->sign_key_handle != CK_INVALID_HANDLE || session->sign_digest_descriptor != NULL)
+ if (session->sign_key_handle != CK_INVALID_HANDLE || session->sign_digest_algorithm != hal_digest_algorithm_none)
lose(CKR_OPERATION_ACTIVE);
if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK)
@@ -3830,22 +3461,22 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
switch (pMechanism->mechanism) {
case CKM_RSA_PKCS:
case CKM_ECDSA:
- session->sign_digest_descriptor = NULL;
+ session->sign_digest_algorithm = hal_digest_algorithm_none;
break;
case CKM_SHA1_RSA_PKCS:
- session->sign_digest_descriptor = hal_hash_sha1;
+ session->sign_digest_algorithm = hal_digest_algorithm_sha1;
break;
case CKM_SHA256_RSA_PKCS:
case CKM_ECDSA_SHA256:
- session->sign_digest_descriptor = hal_hash_sha256;
+ session->sign_digest_algorithm = hal_digest_algorithm_sha256;
break;
case CKM_SHA384_RSA_PKCS:
case CKM_ECDSA_SHA384:
- session->sign_digest_descriptor = hal_hash_sha384;
+ session->sign_digest_algorithm = hal_digest_algorithm_sha384;
break;
case CKM_SHA512_RSA_PKCS:
case CKM_ECDSA_SHA512:
- session->sign_digest_descriptor = hal_hash_sha512;
+ session->sign_digest_algorithm = hal_digest_algorithm_sha512;
break;
default:
return CKR_MECHANISM_INVALID;
@@ -3856,7 +3487,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL) {
session->sign_key_handle = CK_INVALID_HANDLE;
- session->sign_digest_descriptor = NULL;
+ session->sign_digest_algorithm = hal_digest_algorithm_none;
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3884,25 +3515,25 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
if (session->sign_key_handle == CK_INVALID_HANDLE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (session->sign_digest_state != NULL)
+ if (session->sign_digest_handle.handle != HAL_HANDLE_NONE)
lose(CKR_OPERATION_ACTIVE);
- if (session->sign_digest_descriptor != NULL && pSignature != NULL &&
- (rv = digest_update(session->sign_digest_descriptor,
- &session->sign_digest_state, pData, ulDataLen)) != CKR_OK)
- goto fail;
-
if (!p11_attribute_get_ulong(session->sign_key_handle, CKA_KEY_TYPE, &key_type))
lose(CKR_FUNCTION_FAILED);
+ if (session->sign_digest_algorithm != hal_digest_algorithm_none && pSignature != NULL) {
+ if ((rv = digest_update(session, session->sign_digest_algorithm,
+ &session->sign_digest_handle, pData, ulDataLen)) != CKR_OK)
+ goto fail;
+ pData = NULL;
+ ulDataLen = 0;
+ }
+
switch (key_type) {
case CKK_RSA:
- rv = sign_rsa_pkcs(session, pData, ulDataLen, pSignature, pulSignatureLen);
- break;
-
case CKK_EC:
- rv = sign_ecdsa(session, pData, ulDataLen, pSignature, pulSignatureLen);
+ rv = sign_hal_rpc(session, pData, ulDataLen, pSignature, pulSignatureLen);
break;
default:
@@ -3912,8 +3543,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL && pSignature != NULL) {
session->sign_key_handle = CK_INVALID_HANDLE;
- session->sign_digest_descriptor = NULL;
- hal_hash_cleanup(&session->sign_digest_state);
+ session->sign_digest_algorithm = hal_digest_algorithm_none;
+ digest_cleanup(&session->sign_digest_handle);
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
@@ -3939,12 +3570,11 @@ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
if (session->sign_key_handle == CK_INVALID_HANDLE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (session->sign_digest_descriptor == NULL || !session->sign_digest_descriptor->can_restore_state)
+ if (session->sign_digest_algorithm == hal_digest_algorithm_none)
lose(CKR_FUNCTION_FAILED);
- if ((rv = digest_update(session->sign_digest_descriptor,
- &session->sign_digest_state,
- pPart, ulPartLen)) != CKR_OK)
+ if ((rv = digest_update(session, session->sign_digest_algorithm,
+ &session->sign_digest_handle, pPart, ulPartLen)) != CKR_OK)
goto fail;
return mutex_unlock(p11_global_mutex);
@@ -3952,8 +3582,8 @@ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL) {
session->sign_key_handle = CK_INVALID_HANDLE;
- session->sign_digest_descriptor = NULL;
- hal_hash_cleanup(&session->sign_digest_state);
+ session->sign_digest_algorithm = hal_digest_algorithm_none;
+ digest_cleanup(&session->sign_digest_handle);
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
@@ -3977,7 +3607,7 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
if (pulSignatureLen == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->sign_key_handle == CK_INVALID_HANDLE || session->sign_digest_state == NULL)
+ if (session->sign_key_handle == CK_INVALID_HANDLE || session->sign_digest_handle.handle == HAL_HANDLE_NONE)
lose(CKR_OPERATION_NOT_INITIALIZED);
if (!p11_attribute_get_ulong(session->sign_key_handle, CKA_KEY_TYPE, &key_type))
@@ -3986,11 +3616,8 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
switch (key_type) {
case CKK_RSA:
- rv = sign_rsa_pkcs(session, NULL, 0, pSignature, pulSignatureLen);
- break;
-
case CKK_EC:
- rv = sign_ecdsa(session, NULL, 0, pSignature, pulSignatureLen);
+ rv = sign_hal_rpc(session, NULL, 0, pSignature, pulSignatureLen);
break;
default:
@@ -4000,8 +3627,8 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL && pSignature != NULL) {
session->sign_key_handle = CK_INVALID_HANDLE;
- session->sign_digest_descriptor = NULL;
- hal_hash_cleanup(&session->sign_digest_state);
+ session->sign_digest_algorithm = hal_digest_algorithm_none;
+ digest_cleanup(&session->sign_digest_handle);
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
@@ -4027,7 +3654,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
if (pMechanism == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->verify_key_handle != CK_INVALID_HANDLE || session->verify_digest_descriptor != NULL)
+ if (session->verify_key_handle != CK_INVALID_HANDLE || session->verify_digest_algorithm != hal_digest_algorithm_none)
lose(CKR_OPERATION_ACTIVE);
if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK)
@@ -4067,22 +3694,22 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
switch (pMechanism->mechanism) {
case CKM_RSA_PKCS:
case CKM_ECDSA:
- session->verify_digest_descriptor = NULL;
+ session->verify_digest_algorithm = hal_digest_algorithm_none;
break;
case CKM_SHA1_RSA_PKCS:
- session->verify_digest_descriptor = hal_hash_sha1;
+ session->verify_digest_algorithm = hal_digest_algorithm_sha1;
break;
case CKM_SHA256_RSA_PKCS:
case CKM_ECDSA_SHA256:
- session->verify_digest_descriptor = hal_hash_sha256;
+ session->verify_digest_algorithm = hal_digest_algorithm_sha256;
break;
case CKM_SHA384_RSA_PKCS:
case CKM_ECDSA_SHA384:
- session->verify_digest_descriptor = hal_hash_sha384;
+ session->verify_digest_algorithm = hal_digest_algorithm_sha384;
break;
case CKM_SHA512_RSA_PKCS:
case CKM_ECDSA_SHA512:
- session->verify_digest_descriptor = hal_hash_sha512;
+ session->verify_digest_algorithm = hal_digest_algorithm_sha512;
break;
default:
return CKR_MECHANISM_INVALID;
@@ -4093,7 +3720,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL) {
session->verify_key_handle = CK_INVALID_HANDLE;
- session->verify_digest_descriptor = NULL;
+ session->verify_digest_algorithm = hal_digest_algorithm_none;
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -4121,10 +3748,13 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
if (session->verify_key_handle == CK_INVALID_HANDLE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (session->verify_digest_descriptor != NULL &&
- (rv = digest_update(session->verify_digest_descriptor,
- &session->verify_digest_state, pData, ulDataLen)) != CKR_OK)
- goto fail;
+ if (session->verify_digest_algorithm != hal_digest_algorithm_none) {
+ if ((rv = digest_update(session, session->verify_digest_algorithm,
+ &session->verify_digest_handle, pData, ulDataLen)) != CKR_OK)
+ goto fail;
+ pData = NULL;
+ ulDataLen = 0;
+ }
if (!p11_attribute_get_ulong(session->verify_key_handle, CKA_KEY_TYPE, &key_type))
lose(CKR_FUNCTION_FAILED);
@@ -4132,11 +3762,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
switch (key_type) {
case CKK_RSA:
- rv = verify_rsa_pkcs(session, pData, ulDataLen, pSignature, ulSignatureLen);
- break;
-
case CKK_EC:
- rv = verify_ecdsa(session, pData, ulDataLen, pSignature, ulSignatureLen);
+ rv = verify_hal_rpc(session, pData, ulDataLen, pSignature, ulSignatureLen);
break;
default:
@@ -4147,8 +3774,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
if (session != NULL) {
session->verify_key_handle = CK_INVALID_HANDLE;
- session->verify_digest_descriptor = NULL;
- hal_hash_cleanup(&session->verify_digest_state);
+ session->verify_digest_algorithm = hal_digest_algorithm_none;
+ digest_cleanup(&session->verify_digest_handle);
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
@@ -4174,12 +3801,11 @@ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
if (session->verify_key_handle == CK_INVALID_HANDLE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (session->verify_digest_descriptor == NULL || !session->verify_digest_descriptor->can_restore_state)
+ if (session->verify_digest_algorithm == hal_digest_algorithm_none)
lose(CKR_FUNCTION_FAILED);
- if ((rv = digest_update(session->verify_digest_descriptor,
- &session->verify_digest_state,
- pPart, ulPartLen)) != CKR_OK)
+ if ((rv = digest_update(session, session->verify_digest_algorithm,
+ &session->verify_digest_handle, pPart, ulPartLen)) != CKR_OK)
goto fail;
return mutex_unlock(p11_global_mutex);
@@ -4187,8 +3813,8 @@ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL) {
session->verify_key_handle = CK_INVALID_HANDLE;
- session->verify_digest_descriptor = NULL;
- hal_hash_cleanup(&session->verify_digest_state);
+ session->verify_digest_algorithm = hal_digest_algorithm_none;
+ digest_cleanup(&session->verify_digest_handle);
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
@@ -4212,7 +3838,7 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
if (pSignature == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->verify_key_handle == CK_INVALID_HANDLE || session->verify_digest_state == NULL)
+ if (session->verify_key_handle == CK_INVALID_HANDLE || session->verify_digest_handle.handle == HAL_HANDLE_NONE)
lose(CKR_OPERATION_NOT_INITIALIZED);
if (!p11_attribute_get_ulong(session->verify_key_handle, CKA_KEY_TYPE, &key_type))
@@ -4221,11 +3847,8 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
switch (key_type) {
case CKK_RSA:
- rv = verify_rsa_pkcs(session, NULL, 0, pSignature, ulSignatureLen);
- break;
-
case CKK_EC:
- rv = verify_ecdsa(session, NULL, 0, pSignature, ulSignatureLen);
+ rv = verify_hal_rpc(session, NULL, 0, pSignature, ulSignatureLen);
break;
default:
@@ -4236,8 +3859,8 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
if (session != NULL) {
session->verify_key_handle = CK_INVALID_HANDLE;
- session->verify_digest_descriptor = NULL;
- hal_hash_cleanup(&session->verify_digest_state);
+ session->verify_digest_algorithm = hal_digest_algorithm_none;
+ digest_cleanup(&session->verify_digest_handle);
}
mutex_unlock_return_with_rv(rv, p11_global_mutex);
@@ -4321,7 +3944,7 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession,
if (RandomData == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (!hal_check(hal_get_random(NULL, RandomData, ulRandomLen)))
+ if (!hal_check(hal_rpc_get_random(RandomData, ulRandomLen)))
lose(CKR_FUNCTION_FAILED);
fail:
@@ -4361,44 +3984,55 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
if (slotID != P11_ONE_AND_ONLY_SLOT)
return CKR_SLOT_ID_INVALID;
+#if 0
+ /*
+ * Perhaps revisit this after adding an RPC call to let us check
+ * which cores are available. For now, given that we now have
+ * software core support for these hash algorithms, this test isn't
+ * particularly useful.
+ */
+
+ hal_digest_algorithm_t algorithm = hal_digest_algorithm_none;
+ CK_RV rv = CKR_OK;
+
switch (type) {
case CKM_SHA_1:
case CKM_SHA1_RSA_PKCS:
case CKM_SHA_1_HMAC:
case CKM_ECDSA_SHA1:
- if (hal_core_find(hal_hash_sha1->core_name, NULL) == NULL)
- return CKR_MECHANISM_INVALID;
+ algorithm = hal_digest_algorithm_sha1;
break;
case CKM_SHA256:
case CKM_SHA256_RSA_PKCS:
case CKM_SHA256_HMAC:
case CKM_ECDSA_SHA256:
- if (hal_core_find(hal_hash_sha256->core_name, NULL) == NULL)
- return CKR_MECHANISM_INVALID;
+ algorithm = hal_digest_algorithm_sha256;
break;
case CKM_SHA384:
case CKM_SHA384_RSA_PKCS:
case CKM_SHA384_HMAC:
case CKM_ECDSA_SHA384:
- if (hal_core_find(hal_hash_sha384->core_name, NULL) == NULL)
- return CKR_MECHANISM_INVALID;
+ algorithm = hal_digest_algorithm_sha384;
break;
case CKM_SHA512:
case CKM_SHA512_RSA_PKCS:
case CKM_SHA512_HMAC:
case CKM_ECDSA_SHA512:
- if (hal_core_find(hal_hash_sha512->core_name, NULL) == NULL)
- return CKR_MECHANISM_INVALID;
+ algorithm = hal_digest_algorithm_sha512;
break;
default:
break;
}
+ if (algorithm != hal_digest_algorithm_none && (rv = digest_available(algorithm)) != CKR_OK)
+ return rv;
+#endif
+
switch (type) {
case CKM_RSA_PKCS_KEY_PAIR_GEN:
diff --git a/schema.sql b/schema.sql
index ab09529..8a81505 100644
--- a/schema.sql
+++ b/schema.sql
@@ -1,7 +1,7 @@
-- SQLite3 schema for Cryptech PKCS #11 implementation.
--
-- Author: Rob Austein
--- Copyright (c) 2015, NORDUnet A/S
+-- Copyright (c) 2015-2016, NORDUnet A/S
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
@@ -53,58 +53,6 @@
PRAGMA foreign_keys = ON;
--- Values we have to store somewhere and for which we have no better
--- place. This is a table with exactly one row (enforced by the CHECK
--- clause on the primary index). All columns must either allow NULL
--- or provide default values.
-
-CREATE TABLE IF NOT EXISTS global (
- global_id INTEGER PRIMARY KEY NOT NULL DEFAULT 1 CHECK (global_id = 1),
-
- -- Key-encryption-key (KEK)
- --
- -- The KEK **really** should be somewhere else, like in RAM
- -- protected by tamper detection circuitry, but we don't have
- -- that yet. Not obvious that a separate file would be more
- -- secure, so keep it here until we do have a better place.
-
- kek BLOB CHECK (kek IS NULL OR (typeof(kek) = "blob" AND length(kek) IN (16, 32))),
-
- -- PBKDF2-based PIN storage and check values.
- --
- -- "so_pin" and "user_pin" are PBKDF2 output, so only
- -- moderately sensitive.
- --
- -- Not obvious that PKCS #11 ever really allows "so_pin" to be
- -- unset, so it may want a NOT NULL constraint, but in that
- -- case we'll need to provide a default value, which doesn't
- -- seem like much of an improvement. "so_pin" probably
- -- requires out-of-band initialization. "user-pin" is allowed
- -- to be unset, there's an error code specifically for that
- -- situation.
- --
- -- Numeric minima for PBKDF2 iterations, length of PIN, and
- -- length of PBKDF2 salt are somewhat arbitrary, and will
- -- probably change over time (which is why they are minima).
- -- Initial testing was with 100000, which takes about 8 seconds
- -- on a Novena with the current SHA256 and PBKDF2
- -- implementation, which seems a bit slow, so backed that down
- -- a bit. Feel free to suggest better minima.
-
- pbkdf2_iterations INTEGER NOT NULL DEFAULT 20000,
- so_pin BLOB,
- user_pin BLOB,
- so_pin_salt, BLOB,
- user_pin_salt BLOB,
- CHECK ((pbkdf2_iterations >= 10000) AND
- (so_pin IS NULL OR (typeof(so_pin) = "blob" AND length(so_pin) >= 32)) AND
- (user_pin IS NULL OR (typeof(user_pin) = "blob" AND length(user_pin) >= 32)) AND
- (so_pin_salt IS NULL OR (typeof(so_pin_salt) = "blob" AND length(so_pin_salt) >= 16)) AND
- (user_pin_salt IS NULL OR (typeof(user_pin_salt) = "blob" AND length(user_pin_salt) >= 16)))
-);
-
-INSERT OR IGNORE INTO global DEFAULT VALUES;
-
CREATE TEMPORARY TABLE IF NOT EXISTS session (
session_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
session_handle INTEGER NOT NULL UNIQUE
@@ -115,6 +63,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object (
object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
object_handle INTEGER NOT NULL UNIQUE
CHECK (object_handle > 0 AND object_handle <= 0xFFFFFFFF),
+ hal_pkey_type INTEGER,
session_id INTEGER REFERENCES session
ON DELETE CASCADE ON UPDATE CASCADE
DEFERRABLE INITIALLY DEFERRED,
@@ -129,7 +78,6 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object (
CREATE TEMPORARY TABLE IF NOT EXISTS session_object (
session_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
- private_key BLOB UNIQUE,
object_id INTEGER NOT NULL UNIQUE
REFERENCES object
ON DELETE CASCADE ON UPDATE CASCADE
@@ -145,8 +93,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS session_attribute (
);
CREATE TABLE IF NOT EXISTS token_object (
- token_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
- private_key BLOB UNIQUE
+ token_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
);
CREATE TABLE IF NOT EXISTS token_attribute (