summaryrefslogtreecommitdiff
path: root/security/tf_crypto_sst/pkcs11_global.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tf_crypto_sst/pkcs11_global.c')
-rw-r--r--security/tf_crypto_sst/pkcs11_global.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/security/tf_crypto_sst/pkcs11_global.c b/security/tf_crypto_sst/pkcs11_global.c
new file mode 100644
index 00000000..f7c491d7
--- /dev/null
+++ b/security/tf_crypto_sst/pkcs11_global.c
@@ -0,0 +1,275 @@
+/**
+ * Copyright(c) 2011 Trusted Logic. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Trusted Logic nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Implementation Notes:
+ *
+ * This API is NOT thread-safe. Indeed this Cryptoki implementation
+ * only supports option 1 defined in PKCS#11, section 6.5.2:
+ * "The application can specify that it will not be accessing the library concurrently
+ * from multiple threads, and so the library need not worry about performing any type
+ * of locking for the sake of thread-safety."
+ */
+
+#include "pkcs11_internal.h"
+
+/* ------------------------------------------------------------------------
+ System Service UUID
+------------------------------------------------------------------------- */
+const TEEC_UUID SERVICE_UUID = SERVICE_SYSTEM_UUID;
+
+/* ------------------------------------------------------------------------
+ Definition of the global TEE Context
+------------------------------------------------------------------------- */
+TEEC_Context g_sContext;
+/* A mutex that protects the access to the global context and to the
+ g_bContextRefCounter flag */
+LIB_MUTEX g_sContextMutex = LIB_MUTEX_INITIALIZER;
+/* Whether the context has already been initialized or not */
+uint32_t g_nContextRefCounter = 0;
+
+bool g_bCryptokiInitialized = false;
+
+/* ------------------------------------------------------------------------
+ Internal global TEE context management
+------------------------------------------------------------------------- */
+
+void stubMutexLock(void)
+{
+ libMutexLock(&g_sContextMutex);
+}
+
+void stubMutexUnlock(void)
+{
+ libMutexUnlock(&g_sContextMutex);
+}
+
+/* This API must be protected by stubMutexLock/Unlock */
+TEEC_Result stubInitializeContext(void)
+{
+ TEEC_Result nTeeError;
+
+ if (g_nContextRefCounter)
+ {
+ g_nContextRefCounter ++;
+ return TEEC_SUCCESS;
+ }
+
+ nTeeError = TEEC_InitializeContext(NULL, &g_sContext);
+ if (nTeeError == TEEC_SUCCESS)
+ {
+ g_nContextRefCounter = 1;
+ }
+
+ return nTeeError;
+}
+
+/* This API must be protected by stubMutexLock/Unlock */
+void stubFinalizeContext(void)
+{
+ if (g_nContextRefCounter > 0)
+ {
+ g_nContextRefCounter --;
+ }
+
+ if (g_nContextRefCounter == 0)
+ {
+ TEEC_FinalizeContext(&g_sContext);
+ memset(&g_sContext, 0, sizeof(TEEC_Context));
+ }
+}
+
+
+/* ------------------------------------------------------------------------
+ Internal monitor management
+------------------------------------------------------------------------- */
+/**
+* Check that hSession is a valid primary session,
+* or a valid secondary session attached to a valid primary session.
+*
+* input:
+* S_HANDLE hSession: the session handle to check
+* output:
+* bool* pBoolIsPrimarySession: a boolean set to true if the session is primary,
+* set to false if the session if the session is secondary
+* returned boolean: set to true iff :
+* - either hSession is a valid primary session
+* - or hSession is a valid secondary session attached to a valid primary session
+**/
+bool ckInternalSessionIsOpenedEx(S_HANDLE hSession, bool* pBoolIsPrimarySession)
+{
+ PPKCS11_SESSION_CONTEXT_HEADER pHeader = (PPKCS11_SESSION_CONTEXT_HEADER)hSession;
+ PPKCS11_PRIMARY_SESSION_CONTEXT pSession = NULL;
+
+ if ((pHeader == NULL) || (pHeader->nMagicWord != PKCS11_SESSION_MAGIC))
+ {
+ return FALSE;
+ }
+ if (pHeader->nSessionTag == PKCS11_PRIMARY_SESSION_TAG) /* primary session */
+ {
+ pSession = (PPKCS11_PRIMARY_SESSION_CONTEXT)pHeader;
+
+ *pBoolIsPrimarySession = true;
+
+ /* check that primary session is valid */
+ return (pSession->hCryptoSession != CK_INVALID_HANDLE);
+ }
+ else if (pHeader->nSessionTag == PKCS11_SECONDARY_SESSION_TAG) /*secondary session */
+ {
+ PPKCS11_SECONDARY_SESSION_CONTEXT pSecSession = (PPKCS11_SECONDARY_SESSION_CONTEXT)pHeader;
+
+ *pBoolIsPrimarySession = false;
+
+ /* check that primary session is still valid */
+ pSession = pSecSession->pPrimarySession;
+ if ( (pSession == NULL) ||
+ (pSession->sHeader.nMagicWord != PKCS11_SESSION_MAGIC) ||
+ (pSession->sHeader.nSessionTag != PKCS11_PRIMARY_SESSION_TAG))
+ {
+ return FALSE;
+ }
+
+ if (pSession->hCryptoSession == CK_INVALID_HANDLE)
+ {
+ return FALSE;
+ }
+
+ /* check that secondary session is valid */
+ return (pSecSession->hSecondaryCryptoSession != CK_INVALID_HANDLE);
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/* ------------------------------------------------------------------------
+ Internal error management
+------------------------------------------------------------------------- */
+
+CK_RV ckInternalTeeErrorToCKError(TEEC_Result nError)
+{
+ switch (nError)
+ {
+ case TEEC_SUCCESS:
+ return CKR_OK;
+
+ case TEEC_ERROR_BAD_PARAMETERS:
+ case TEEC_ERROR_BAD_FORMAT:
+ return CKR_ARGUMENTS_BAD;
+ case TEEC_ERROR_OUT_OF_MEMORY:
+ return CKR_HOST_MEMORY;
+ case TEEC_ERROR_ACCESS_DENIED:
+ return CKR_TOKEN_NOT_PRESENT;
+ default:
+ return CKR_DEVICE_ERROR;
+ }
+}
+
+/* ------------------------------------------------------------------------
+ Public Functions
+------------------------------------------------------------------------- */
+CK_RV PKCS11_EXPORT C_Initialize(CK_VOID_PTR pInitArgs)
+{
+ CK_RV nErrorCode;
+ TEEC_Result nTeeError;
+
+ if (pInitArgs != NULL_PTR)
+ {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ stubMutexLock();
+ if (g_bCryptokiInitialized)
+ {
+ nErrorCode = CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ }
+ else
+ {
+ nTeeError = stubInitializeContext();
+ if (nTeeError == TEEC_SUCCESS)
+ {
+ g_bCryptokiInitialized = true;
+ }
+ nErrorCode = ckInternalTeeErrorToCKError(nTeeError);
+ }
+ stubMutexUnlock();
+
+ return nErrorCode;
+}
+
+CK_RV PKCS11_EXPORT C_Finalize(CK_VOID_PTR pReserved)
+{
+ CK_RV nErrorCode;
+
+ if (pReserved != NULL_PTR)
+ {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ stubMutexLock();
+ if (g_bCryptokiInitialized)
+ {
+ stubFinalizeContext();
+ g_bCryptokiInitialized = false;
+ nErrorCode = CKR_OK;
+ }
+ else
+ {
+ nErrorCode = CKR_CRYPTOKI_NOT_INITIALIZED;
+ }
+ stubMutexUnlock();
+
+ return nErrorCode;
+}
+
+static const CK_INFO sImplementationInfo =
+{
+ {2, 20}, /* cryptokiVersion, spec 2.20 */
+ "Trusted Logic", /* manufacturerID */
+ 0, /* flags */
+ "PKCS#11", /* libraryDescription */
+ {3, 0} /* libraryVersion */
+};
+
+CK_RV PKCS11_EXPORT C_GetInfo(CK_INFO_PTR pInfo)
+{
+ if (!g_bCryptokiInitialized)
+ {
+ return CKR_CRYPTOKI_NOT_INITIALIZED;
+ }
+ if (pInfo == NULL_PTR)
+ {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ memcpy(pInfo, &sImplementationInfo, sizeof(CK_INFO));
+ return CKR_OK;
+}