aboutsummaryrefslogtreecommitdiff
path: root/pkcs11.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-06-24 13:39:01 -0400
committerRob Austein <sra@hactrn.net>2015-06-24 13:39:01 -0400
commite5b169b8fcec4be52ba3957a1154beaca2a14384 (patch)
tree56c081f3d0b1320a9e0488a69e793a7ae80a21d6 /pkcs11.c
parent5479e522a5fc375a107d88452d95a6035152975e (diff)
Refactor PKCS #1.5 code, add C_Verify*() functions. Tidy up and
extend debug-by-printf() support, given all the fun we've been having with gdb and threads on the Novena.
Diffstat (limited to 'pkcs11.c')
-rw-r--r--pkcs11.c643
1 files changed, 524 insertions, 119 deletions
diff --git a/pkcs11.c b/pkcs11.c
index f99face..0be7489 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -112,7 +112,7 @@
#endif
#ifndef DEBUG_PKCS11
-#define DEBUG_PKCS11 1
+#define DEBUG_PKCS11 2
#endif
/*
@@ -188,10 +188,12 @@ typedef struct p11_session {
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*() */
- CK_OBJECT_HANDLE sign_key_handle; /* Key for C_Sign*() */
-
+ *digest_descriptor, /* Hash for C_Digest*() */
+ *sign_digest_descriptor, /* Hash for C_Sign*() */
+ *verify_digest_descriptor; /* Hash for C_Verify*() */
+ CK_OBJECT_HANDLE
+ sign_key_handle, /* Key for C_Sign*() */
+ verify_key_handle; /* Key for C_Verify() */
} p11_session_t;
/*
@@ -284,6 +286,8 @@ static pid_t initialized_pid;
* readable without significantly reducing the voodoo factor.
*/
+#if DEBUG_PKCS11
+
#define lose(_ck_rv_code_) \
do { \
rv = (_ck_rv_code_); \
@@ -291,6 +295,33 @@ static pid_t initialized_pid;
goto fail; \
} while (0)
+#else /* DEBUG_PKCS11 */
+
+#define lose(_ck_rv_code_) \
+ do { \
+ rv = (_ck_rv_code_); \
+ goto fail; \
+ } while (0)
+
+#endif /* DEBUG_PKCS11 */
+
+/*
+ * More debug-by-printf() support. One would like to consider this a
+ * relic of the previous millenium, but, sadly, broken debugging
+ * environments are still all too common.
+ */
+
+#if DEBUG_PKCS11 > 1
+
+#define ENTER_PUBLIC_FUNCTION(_name_) \
+ fprintf(stderr, "Call to unsupported function %s\n", #_name_)
+
+#else /* DEBUG_PKCS11 > 1 */
+
+#define ENTER_PUBLIC_FUNCTION(_name_)
+
+#endif /* DEBUG_PKCS11 > 1 */
+
/*
* Error checking for SQLite calls.
*/
@@ -1723,7 +1754,9 @@ static CK_RV p11_check_keypair_attributes_check_template_2(const p11_session_t *
/* Required attribute missing from template */
if (!forbidden_by_api && (required_by_api || !in_descriptor) && pos_in_template < 0) {
- fprintf(stderr, "[Missing attribute 0x%lx]\n", atd->type); /* XXX */
+#if DEBUG_PKCS11
+ fprintf(stderr, "[Missing attribute 0x%lx]\n", atd->type);
+#endif
lose(CKR_TEMPLATE_INCOMPLETE);
}
}
@@ -1980,6 +2013,97 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
}
/*
+ * Construct a PKCS #1 DigestInfo object. This requires some (very
+ * basic) ASN.1 encoding, which we perform inline.
+ */
+
+static int pkcs1_construct_digestinfo(const hal_hash_descriptor_t * const desc,
+ const uint8_t * const data, const size_t data_len,
+ uint8_t *digest_info, const size_t digest_info_len)
+{
+ uint8_t statebuf[desc->hash_state_length];
+ hal_hash_state_t state = { NULL };
+ uint8_t *d = digest_info;
+
+ /*
+ * 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);
+
+ *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);
+
+ const int ok = (hal_check(hal_hash_initialize(desc, &state, statebuf, sizeof(statebuf))) &&
+ hal_check(hal_hash_update(state, data, data_len)) &&
+ hal_check(hal_hash_finalize(state, d, desc->digest_length)));
+
+ memset(statebuf, 0, sizeof(statebuf));
+ if (!ok)
+ memset(digest_info, 0, digest_info_len);
+ return ok;
+}
+
+/*
+ * 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.
+ */
+
+static int pkcs1_5_pad(const uint8_t * const data, const size_t data_len,
+ uint8_t *block, const size_t block_len)
+{
+ assert(data != NULL && block != NULL);
+
+ /*
+ * Congregation will now please turn to RFC 2313 8.1 as we
+ * construct a PKCS #1.5 type 01 encryption block.
+ */
+
+ if (data_len > block_len - 11)
+ return 0;
+
+ block[0] = 0x00;
+ block[1] = 0x01;
+
+ /* 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);
+
+#if DEBUG_PKCS11 > 1
+ fprintf(stderr, "[PKCS #1.5 block_len %lu data_len %lu block ", block_len, data_len);
+ for (int i = 0; i < block_len; i++)
+ fprintf(stderr, "%s%02x", i == 0 ? "" : ":", block[i]);
+ fprintf(stderr, "]\n");
+#endif
+
+ return 1;
+}
+
+/*
* Sign a PKCS #1 DigestInfo using an RSA key and PKCS #1.5 padding.
*
* As explained in RFC 3447, the RSASP1 (signature generation)
@@ -1995,27 +2119,9 @@ static CK_RV sign_rsa_pkcs(hal_rsa_key_t key,
assert(digest_info != NULL && signature != NULL);
- /*
- * Congregation will now please turn to RFC 2313 8.1 as we
- * construct a PKCS #1.5 type 01 encryption block.
- */
-
- if (digest_info_len > signature_len - 11)
+ if (!pkcs1_5_pad(digest_info, digest_info_len, signature, signature_len))
lose(CKR_DATA_LEN_RANGE);
- signature[0] = 0x00;
- signature[1] = 0x01;
- memset(signature + 2, 0xFF, signature_len - 3 - digest_info_len);
- signature[signature_len - digest_info_len - 1] = 0x00;
- memcpy(signature + signature_len - digest_info_len, digest_info, digest_info_len);
-
-#if 0
- fprintf(stderr, "[PKCS #1.5 signature_len %lu digest_info_len %lu block ", signature_len, digest_info_len);
- for (int i = 0; i < signature_len; i++)
- fprintf(stderr, "%s%02x", i == 0 ? "" : ":", signature[i]);
- fprintf(stderr, "]\n");
-#endif
-
if (!hal_check(hal_rsa_decrypt(key, signature, signature_len, signature, signature_len)))
lose(CKR_FUNCTION_FAILED);
@@ -2026,6 +2132,46 @@ static CK_RV sign_rsa_pkcs(hal_rsa_key_t key,
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.
+ */
+
+static CK_RV verify_rsa_pkcs(hal_rsa_key_t key,
+ const uint8_t * const digest_info, const size_t digest_info_len,
+ const uint8_t * const signature, const size_t signature_len)
+{
+ assert(digest_info != NULL && signature != NULL);
+
+ uint8_t expected[signature_len], received[signature_len];
+ unsigned diff = 0;
+ CK_RV rv;
+
+ if (!pkcs1_5_pad(digest_info, digest_info_len, expected, sizeof(expected)))
+ lose(CKR_DATA_LEN_RANGE);
+
+ if (!hal_check(hal_rsa_encrypt(key, signature, signature_len, received, sizeof(received))))
+ lose(CKR_FUNCTION_FAILED);
+
+ for (int i = 0; i < signature_len; i++)
+ diff |= expected[i] ^ received[i];
+
+ if (diff != 0)
+ lose(CKR_SIGNATURE_INVALID);
+
+ rv = CKR_OK;
+
+ fail:
+ memset(expected, 0, sizeof(expected));
+ memset(received, 0, sizeof(received));
+ return rv;
+}
+
@@ -2035,6 +2181,8 @@ static CK_RV sign_rsa_pkcs(hal_rsa_key_t key,
CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
{
+ ENTER_PUBLIC_FUNCTION(C_Initialize);
+
CK_C_INITIALIZE_ARGS_PTR a = pInitArgs;
int initialized_sql = 0;
CK_RV rv;
@@ -2158,6 +2306,8 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
CK_RV C_Finalize(CK_VOID_PTR pReserved)
{
+ ENTER_PUBLIC_FUNCTION(C_Finalize);
+
CK_RV rv = CKR_OK;
if (pReserved != NULL)
@@ -2195,6 +2345,8 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
{
+ ENTER_PUBLIC_FUNCTION(C_GetFunctionList);
+
/*
* Use pkcs11f.h to build dispatch vector for C_GetFunctionList().
* This should be const, but that's not what PKCS #11 says, oh well.
@@ -2221,6 +2373,8 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList,
CK_ULONG_PTR pulCount)
{
+ ENTER_PUBLIC_FUNCTION(C_GetSlotList);
+
/*
* We only have one slot, and it's hardwired.
* No locking required here as long as this holds.
@@ -2243,6 +2397,8 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent,
CK_RV C_GetTokenInfo(CK_SLOT_ID slotID,
CK_TOKEN_INFO_PTR pInfo)
{
+ ENTER_PUBLIC_FUNCTION(C_GetTokenInfo);
+
/*
* No locking required here as long as we're just returning constants.
*/
@@ -2338,6 +2494,8 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID,
CK_NOTIFY Notify,
CK_SESSION_HANDLE_PTR phSession)
{
+ ENTER_PUBLIC_FUNCTION(C_OpenSession);
+
const int parallel_session = (flags & CKF_SERIAL_SESSION) == 0;
const int read_only_session = (flags & CKF_RW_SESSION) == 0;
p11_session_t *session = NULL;
@@ -2396,6 +2554,8 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID,
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
{
+ ENTER_PUBLIC_FUNCTION(C_CloseSession);
+
CK_RV rv;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -2407,6 +2567,8 @@ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
CK_RV C_CloseAllSessions(CK_SLOT_ID slotID)
{
+ ENTER_PUBLIC_FUNCTION(C_CloseAllSessions);
+
if (slotID != P11_ONE_AND_ONLY_SLOT)
return CKR_SLOT_ID_INVALID;
@@ -2422,6 +2584,8 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen)
{
+ ENTER_PUBLIC_FUNCTION(C_Login);
+
static const char pin_query_format[] =
" SELECT pbkdf2_iterations, %s_pin, %s_pin_salt from global";
@@ -2559,6 +2723,8 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession,
CK_RV C_Logout(CK_SESSION_HANDLE hSession)
{
+ ENTER_PUBLIC_FUNCTION(C_Logout);
+
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -2611,6 +2777,8 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject)
{
+ ENTER_PUBLIC_FUNCTION(C_DestroyObject);
+
static const char delete_object[] =
" DELETE FROM object WHERE object_handle = ?";
@@ -2652,6 +2820,8 @@ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount)
{
+ ENTER_PUBLIC_FUNCTION(C_GetAttributeValue);
+
static const char select_format[] =
" SELECT value FROM %s_attribute NATURAL JOIN object"
" WHERE object_handle = ?1 AND type = ?2";
@@ -2746,6 +2916,8 @@ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount)
{
+ ENTER_PUBLIC_FUNCTION(C_FindObjectsInit);
+
static const char select_missing[] =
" WITH"
" known AS (SELECT token_object_id FROM object WHERE token_object_id IS NOT NULL)"
@@ -2887,6 +3059,8 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession,
CK_ULONG ulMaxObjectCount,
CK_ULONG_PTR pulObjectCount)
{
+ ENTER_PUBLIC_FUNCTION(C_FindObjects);
+
p11_session_t *session;
int i, ret = SQLITE_OK;
CK_RV rv = CKR_OK;
@@ -2937,6 +3111,8 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession,
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
{
+ ENTER_PUBLIC_FUNCTION(C_FindObjectsFinal);
+
static const char drop_format[] =
" DROP TABLE IF EXISTS findobjects_%lu";
@@ -2969,6 +3145,8 @@ CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism)
{
+ ENTER_PUBLIC_FUNCTION(C_DigestInit);
+
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3008,6 +3186,8 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pDigest,
CK_ULONG_PTR pulDigestLen)
{
+ ENTER_PUBLIC_FUNCTION(C_Digest);
+
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3055,6 +3235,8 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
{
+ ENTER_PUBLIC_FUNCTION(C_SignInit);
+
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3104,6 +3286,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen)
{
+ ENTER_PUBLIC_FUNCTION(C_Sign);
+
uint8_t keybuf[hal_rsa_key_t_size];
hal_rsa_key_t key = { NULL };
p11_session_t *session;
@@ -3154,57 +3338,157 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
/*
* Caller wanted a hash-and-sign operation. We need to hash the
* caller's data and construct a DigestInfo SEQUENCE.
- *
- * This probably ought to be a library function somewhere.
*/
- const hal_hash_descriptor_t *desc = session->sign_digest_descriptor;
- uint8_t digest_info[desc->digest_length + desc->digest_algorithm_id_length + 4];
- uint8_t statebuf[session->digest_descriptor->hash_state_length];
- hal_hash_state_t state = { NULL };
- uint8_t *d = digest_info;
+ uint8_t digest_info[session->sign_digest_descriptor->digest_length + 4 +
+ session->sign_digest_descriptor->digest_algorithm_id_length];
+
+ if (!pkcs1_construct_digestinfo(session->sign_digest_descriptor,
+ pData, ulDataLen, digest_info, sizeof(digest_info)))
+ lose(CKR_FUNCTION_FAILED);
+ rv = sign_rsa_pkcs(key, digest_info, sizeof(digest_info), pSignature, signature_len);
+ memset(digest_info, 0, sizeof(digest_info));
+ if (rv != CKR_OK)
+ goto fail;
+ }
+
+ else {
/*
- * 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.
+ * Caller wanted a pure-signature operation. We assume that the
+ * input is a valid DigestInfo SEQUENCE: since we've never seen
+ * the original plaintext, we can't check the hash, thus there's
+ * little point in checking the ASN.1 structure.
*/
- assert(sizeof(digest_info) < 130);
- *d++ = 0x30; /* SEQUENCE */
- *d++ = (uint8_t) (sizeof(digest_info) - 2);
+ if ((rv = sign_rsa_pkcs(key, pData, ulDataLen, pSignature, signature_len)) != CKR_OK)
+ goto fail;
+ }
+
+ rv = CKR_OK; /* Fall through */
+
+ fail:
+
+ if (session != NULL) {
+ session->sign_key_handle = CK_INVALID_HANDLE;
+ session->sign_digest_descriptor = NULL;
+ }
+
+ hal_rsa_key_clear(key);
+
+ mutex_unlock_return_with_rv(rv, p11_global_mutex);
+}
+
+CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey )
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyInit);
+
+ p11_session_t *session;
+ CK_RV rv = CKR_OK;
+
+ mutex_lock_or_return_failure(p11_global_mutex);
+
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
- memcpy(d, desc->digest_algorithm_id, desc->digest_algorithm_id_length);
- d += desc->digest_algorithm_id_length;
+ if (pMechanism == NULL)
+ lose(CKR_ARGUMENTS_BAD);
- *d++ = 0x04; /* OCTET STRING */
- *d++ = (uint8_t) desc->digest_length;
+ if (session->verify_key_handle != CK_INVALID_HANDLE || session->verify_digest_descriptor != NULL)
+ lose(CKR_OPERATION_ACTIVE);
- assert(digest_info + sizeof(digest_info) == d + desc->digest_length);
+ if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK)
+ goto fail;
- if (!hal_check(hal_hash_initialize(desc, &state, statebuf, sizeof(statebuf))) ||
- !hal_check(hal_hash_update(state, pData, ulDataLen)) ||
- !hal_check(hal_hash_finalize(state, d, desc->digest_length))) {
- memset(digest_info, 0, sizeof(digest_info));
+ /*
+ * Will need to check key algorithm type here once we add support
+ * for signature algorithms other than RSA.
+ */
+
+ session->verify_key_handle = hKey;
+
+ switch (pMechanism->mechanism) {
+ case CKM_RSA_PKCS: session->verify_digest_descriptor = NULL; break;
+ case CKM_SHA1_RSA_PKCS: session->verify_digest_descriptor = hal_hash_sha1; break;
+ case CKM_SHA256_RSA_PKCS: session->verify_digest_descriptor = hal_hash_sha256; break;
+ case CKM_SHA384_RSA_PKCS: session->verify_digest_descriptor = hal_hash_sha384; break;
+ case CKM_SHA512_RSA_PKCS: session->verify_digest_descriptor = hal_hash_sha512; break;
+ default: return CKR_MECHANISM_INVALID;
+ }
+
+ return mutex_unlock(p11_global_mutex);
+
+ fail:
+ if (session != NULL) {
+ session->verify_key_handle = CK_INVALID_HANDLE;
+ session->verify_digest_descriptor = NULL;
+ }
+ mutex_unlock_return_with_rv(rv, p11_global_mutex);
+}
+
+CK_RV C_Verify(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
+{
+ ENTER_PUBLIC_FUNCTION(C_Verify);
+
+ uint8_t keybuf[hal_rsa_key_t_size];
+ hal_rsa_key_t key = { NULL };
+ p11_session_t *session;
+ CK_RV rv;
+
+ mutex_lock_or_return_failure(p11_global_mutex);
+
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
+
+ if (pData == NULL)
+ lose(CKR_ARGUMENTS_BAD);
+
+ if (session->verify_key_handle == CK_INVALID_HANDLE)
+ lose(CKR_OPERATION_NOT_INITIALIZED);
+
+ /*
+ * From here down this function is RSA-specific, and will need
+ * rewriting when we add support for other algorithms.
+ */
+
+ if (!p11_object_get_rsa_private_key(session->verify_key_handle,
+ &key, keybuf, sizeof(keybuf)))
+ lose(CKR_FUNCTION_FAILED);
+
+ if (session->verify_digest_descriptor != NULL) {
+ /*
+ * Caller wanted a hash-and-verify operation. We need to hash the
+ * caller's data and construct a DigestInfo SEQUENCE.
+ */
+
+ uint8_t digest_info[session->verify_digest_descriptor->digest_length + 4 +
+ session->verify_digest_descriptor->digest_algorithm_id_length];
+
+ if (!pkcs1_construct_digestinfo(session->verify_digest_descriptor,
+ pData, ulDataLen, digest_info, sizeof(digest_info)))
lose(CKR_FUNCTION_FAILED);
- }
- rv = sign_rsa_pkcs(key, digest_info, sizeof(digest_info), pSignature, signature_len);
+ rv = verify_rsa_pkcs(key, digest_info, sizeof(digest_info), pSignature, ulSignatureLen);
memset(digest_info, 0, sizeof(digest_info));
if (rv != CKR_OK)
goto fail;
}
else {
-
/*
- * Caller wanted a pure-signature operation. We assume that input
- * is a valid DigestInfo SEQUENCE: we've never seen the original
- * plaintext, thus can't check the hash, so there's not much point
- * in checking the ASN.1 structure.
+ * Caller wanted a pure-verification operation. We assume that
+ * the input is a valid DigestInfo SEQUENCE: since we've never
+ * seen the original plaintext, we can't check the hash, thus
+ * there's little point in checking the ASN.1 structure.
*/
- if ((rv = sign_rsa_pkcs(key, pData, ulDataLen, pSignature, signature_len)) != CKR_OK)
+ if ((rv = verify_rsa_pkcs(key, pData, ulDataLen, pSignature, ulSignatureLen)) != CKR_OK)
goto fail;
}
@@ -3213,8 +3497,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
fail:
if (session != NULL) {
- session->sign_key_handle = CK_INVALID_HANDLE;
- session->sign_digest_descriptor = NULL;
+ session->verify_key_handle = CK_INVALID_HANDLE;
+ session->verify_digest_descriptor = NULL;
}
hal_rsa_key_clear(key);
@@ -3238,6 +3522,8 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE_PTR phPublicKey,
CK_OBJECT_HANDLE_PTR phPrivateKey)
{
+ ENTER_PUBLIC_FUNCTION(C_GenerateKeyPair);
+
p11_session_t *session;
CK_RV rv;
@@ -3272,6 +3558,8 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR RandomData,
CK_ULONG ulRandomLen)
{
+ ENTER_PUBLIC_FUNCTION(C_GenerateRandom);
+
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3290,12 +3578,6 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession,
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
-
-
-/*
- * hsmbully wants additional methods, no real surprise.
- */
-
/*
* Supply information about a particular mechanism. We may want a
* more generic structure for this, for the moment, just answer the
@@ -3312,6 +3594,8 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR pInfo)
{
+ ENTER_PUBLIC_FUNCTION(C_GetMechanismInfo);
+
/*
* No locking here, no obvious need for it.
*/
@@ -3343,6 +3627,7 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID,
return CKR_OK;
}
+
/*
@@ -3363,223 +3648,322 @@ CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GenerateKey);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetInfo(CK_INFO_PTR pInfo)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetInfo);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetSlotInfo(CK_SLOT_ID slotID,
CK_SLOT_INFO_PTR pInfo)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetSlotInfo);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetMechanismList(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE_PTR pMechanismList,
CK_ULONG_PTR pulCount)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetMechanismList);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_InitToken(CK_SLOT_ID slotID,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen,
CK_UTF8CHAR_PTR pLabel)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_InitToken);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_InitPIN(CK_SESSION_HANDLE hSession,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_InitPIN);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SetPIN(CK_SESSION_HANDLE hSession,
CK_UTF8CHAR_PTR pOldPin,
CK_ULONG ulOldLen,
CK_UTF8CHAR_PTR pNewPin,
CK_ULONG ulNewLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SetPIN);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession,
CK_SESSION_INFO_PTR pInfo)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetSessionInfo);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState,
CK_ULONG_PTR pulOperationStateLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetOperationState);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState,
CK_ULONG ulOperationStateLen,
CK_OBJECT_HANDLE hEncryptionKey,
CK_OBJECT_HANDLE hAuthenticationKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SetOperationState);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phObject)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_CreateObject);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_CopyObject(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_OBJECT_HANDLE_PTR phNewObject)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_CopyObject);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ULONG_PTR pulSize)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetObjectSize);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SetAttributeValue);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_EncryptInit);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_Encrypt(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pEncryptedData,
CK_ULONG_PTR pulEncryptedDataLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_Encrypt);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_EncryptUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pLastEncryptedPart,
CK_ULONG_PTR pulLastEncryptedPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_EncryptFinal);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DecryptInit);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_Decrypt(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedData,
CK_ULONG ulEncryptedDataLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_Decrypt);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DecryptUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pLastPart,
CK_ULONG_PTR pulLastPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DecryptFinal);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DigestUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DigestKey(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DigestKey);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pDigest,
CK_ULONG_PTR pulDigestLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DigestFinal);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SignUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SignFinal);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SignRecoverInit);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SignRecover(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pData,
CK_ULONG ulDataLen,
CK_BYTE_PTR pSignature,
CK_ULONG_PTR pulSignatureLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
-
-CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey )
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
-
-CK_RV C_Verify(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SignRecover);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG ulSignatureLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyFinal);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyRecoverInit);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSignature,
CK_ULONG ulSignatureLen,
CK_BYTE_PTR pData,
CK_ULONG_PTR pulDataLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyRecover);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DigestEncryptUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DecryptDigestUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pPart,
CK_ULONG ulPartLen,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG_PTR pulEncryptedPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SignEncryptUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DecryptVerifyUpdate);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_WrapKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -3587,7 +3971,10 @@ CK_RV C_WrapKey(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hKey,
CK_BYTE_PTR pWrappedKey,
CK_ULONG_PTR pulWrappedKeyLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_WrapKey);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -3597,7 +3984,10 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_UnwrapKey);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -3605,23 +3995,38 @@ CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulAttributeCount,
CK_OBJECT_HANDLE_PTR phKey)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_DeriveKey);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pSeed,
CK_ULONG ulSeedLen)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_SeedRandom);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_GetFunctionStatus);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_CancelFunction);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
CK_RV C_WaitForSlotEvent(CK_FLAGS flags,
CK_SLOT_ID_PTR pSlot,
CK_VOID_PTR pRserved)
-{ return CKR_FUNCTION_NOT_SUPPORTED; }
+{
+ ENTER_PUBLIC_FUNCTION(C_WaitForSlotEvent);
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
/*
* "Any programmer who fails to comply with the standard naming, formatting,