/***************************************************************************** * * Copyright 2016 NXP * SPDX-License-Identifier: Apache-2.0 ****************************************************************************/ #include #include #include #include #ifdef __gnu_linux__ #include #endif #include #include /* For mode constants */ #ifdef __gnu_linux__ #include #endif #include /* For O_* constants */ #ifdef __gnu_linux__ #include #include #endif #include #include #include "sm_printf.h" #include "sm_types.h" #include "ax_cryptoIpc.h" /*Local Defines*/ #ifndef TGT_A71CH /************** Shared Mem for SCI2C Sequence Num *********/ static key_t Shmkey = 56789; /*TODO: Use ftok to get a unique ID, declared in sci2c.c*/ static int CryptoIpc_ShmId; static char *pShm = NULL; /************** Semaphore Mutex ************************/ static key_t Semkey = 12345; /*TODO: Use ftok to get a unique ID*/ static int CryptoIpc_SemId; static U16 CryptoIpc_SemVal; /* This flag marks if the application is currently holding the Mutex. Used before releasing the IPC resources when * CryptoIpc_Close is invoked */ static int CryptoIpc_SemLocked = AX_CI_FALSE; /* This flag is set when IPC cleanup has to be deferred as the app is holding the mutex. If this flag is set , then * upon invocation of CryptoIpc_MutexUnlock(), the IPC resouces are cleaned and application exits*/ static int CryptoIpc_FlagExit = AX_CI_FALSE; struct sembuf CryptoIpc_SemWait, CryptoIpc_SemSignal; #endif /** Initialization for Crypto Library Mutex. This should be invoked as part of App initialization. Note:- In a system only 1 application (and the first one to be launched) shall invoke this API with parameter AX_CI_TRUE. All other API's invoke with parameter AX_CI_FALSE. * @param bool - AX_CI_TRUE - set mutex value to 1, AX_CI_FALSE- Do not set Mutex val * @return 0 always */ int CryptoIpc_MutexInit(int setval) { #ifdef TGT_A71CH return 0; #else CryptoIpc_SemWait.sem_num = 0; CryptoIpc_SemWait.sem_op = -1; CryptoIpc_SemWait.sem_flg = SEM_UNDO; /*In case the application is terminated intentionally or unintentionally*/ CryptoIpc_SemSignal.sem_num = 0; CryptoIpc_SemSignal.sem_op = 1; CryptoIpc_SemSignal.sem_flg = SEM_UNDO; /*In case the application is terminated intentionally or unintentionally*/ // TODO: Investigate why the function argument is overruled setval = AX_CI_TRUE; CryptoIpc_SemId = semget(Semkey,1,IPC_CREAT|IPC_EXCL|777); if (CryptoIpc_SemId == -1) { if (errno == EEXIST) { printf("Semaphore already exists\n"); CryptoIpc_SemId = semget(Semkey, 1, IPC_CREAT|777); setval = AX_CI_FALSE; } else { printf("Semaphore Creation failed\n"); } return 1; } printf("Allocating the semaphore: %d %d\n",errno,CryptoIpc_SemId); if (setval == AX_CI_TRUE) { CryptoIpc_SemVal = 1; /*Mutex*/ semctl(CryptoIpc_SemId, 0, SETVAL, CryptoIpc_SemVal); printf("Setting semaphore value to %d: %d\n", CryptoIpc_SemVal, errno); } else { //printf("Initialized Semaphore value to %d: %d\n",CryptoIpc_SemVal,errno); } return 0; #endif } /** * Initialization for Crypto Library shared memory. * The sequence number used in the PCB byte of SCI2C is placed in this * shared memory as the Secure Element just goes by Command Response * Sequence and the number of applications on the host is transparent * to the Secure Element. * This API is invoked as part of SCI2C initialization. Not to be invoked by the app. * \note Not used. * * @return shared memory segment */ char *CryptoIpc_ShmInit(void) { #ifdef TGT_A71CH return NULL; #else /* create the segment */ if ((CryptoIpc_ShmId = shmget(Shmkey, 4, 0644 | IPC_CREAT)) == -1) { printf("CryptoIpc: shmget failed\n"); } else { //printf("CryptoIpc: SHMID is %d",shmid); } /* Now we attach the segment to our data space. */ if ((pShm = (char*)shmat(CryptoIpc_ShmId, NULL, 0)) == (char *) -1) { printf("CryptoIpc: shmat failed\n"); return NULL; } return pShm; #endif } /** * Grab mutex before entering Critical Section * @return void */ void CryptoIpc_MutexLock() { #ifdef TGT_A71CH return; #else CryptoIpc_SemLocked = AX_CI_TRUE; semop(CryptoIpc_SemId, &CryptoIpc_SemWait, 1); #endif } /** * Release mutex and after exit from Critical Section * @return void */ void CryptoIpc_MutexUnlock() { #ifdef TGT_A71CH return; #else CryptoIpc_SemLocked = AX_CI_FALSE; semop(CryptoIpc_SemId, &CryptoIpc_SemSignal, 1); if (CryptoIpc_FlagExit == AX_CI_TRUE) { if (AX_CI_TRUE == CryptoIpc_Close()) { printf("CryptoIpc: Cleaned..Good Bye...\n"); exit(0); } } #endif } /** * Clean up of IPC resources. API to be invoked at App exit * @retval AX_CI_TRUE: OK to exit application * @retval AX_CI_FALSE: Application is in Critical section and shall clean up upon out from Critical Section. And then invoke App exit(). */ int CryptoIpc_Close() { #ifdef TGT_A71CH return AX_CI_TRUE; #else /*Wait for the mutex to be released*/ if (CryptoIpc_SemLocked) { CryptoIpc_FlagExit = AX_CI_TRUE; return AX_CI_FALSE; } shmdt(pShm); /* Detach the shared memory */ shmctl (CryptoIpc_ShmId, IPC_RMID, 0); return AX_CI_TRUE; #endif }