### Link Libraries and Install Target Source: https://github.com/qualcomm/minkipc/blob/main/optee-test/CMakeLists.txt Configures the libraries to link against and defines the installation path for the generated binary. ```cmake target_link_libraries (${PROJECT_NAME} PRIVATE m PRIVATE xtest-ta-headers PRIVATE ckqteec PRIVATE minkteec PRIVATE minkadaptor PRIVATE ${CMAKE_THREAD_LIBS_INIT} PRIVATE ${OPENSSL_PRIVATE_LINK} ) ################################################################################ # Install targets ################################################################################ install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) ``` -------------------------------- ### Build and Install RPMB Service Source: https://github.com/qualcomm/minkipc/blob/main/listeners/librpmbservice/README.md Commands to configure, build, and install the RPMB service library. ```bash # Configure with RPMB listener enabled cmake .. -DBUILD_RPMB_LISTENER=ON # Build the service make rpmbservice ``` ```bash # Install service library make install # The service will be installed as: # - /usr/local/lib/librpmbservice.so.1 # - /usr/local/include/rpmb_msg.h ``` -------------------------------- ### Project and Library Setup Source: https://github.com/qualcomm/minkipc/blob/main/libmink/Credentials/CMakeLists.txt Defines the project name, version, and language. Sets up an interface library for headers and a static library for the main source files. ```cmake project(minkcredentials VERSION 1.0.0 LANGUAGES C ) add_compile_options( -Wstrict-prototypes -Wmissing-prototypes -Wbad-function-cast -Wswitch-default ) add_library(credentialsHeaders INTERFACE) target_include_directories(credentialsHeaders INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/inc ) add_library(libminkcredentials STATIC src/osIndCredentials.c ) ``` -------------------------------- ### Include Header Order Example Source: https://github.com/qualcomm/minkipc/blob/main/CODING-STYLE.md Demonstrates the recommended order for including header files: standard, C system, other libraries, and local project headers. Headers within each group should be alphabetized. ```c #include #include #include #include #include #include #include "qcbor.h" #include "MinkCom.h" #include "object.h" ... ``` -------------------------------- ### Start Service with IModule Interface Source: https://context7.com/qualcomm/minkipc/llms.txt Starts a MinkIPC service that supports credential forwarding using the IModule interface on a UNIX socket. The service must be joined and then released. ```c // Start a service with IModule interface (supports credential forwarding) void start_module_service() { Object moduleEndpoint = { .invoke = ModuleObject_invoke, // IModule implementation .context = NULL }; // Start IModule service on UNIX socket MinkIPC *ipc = MinkIPC_startServiceModule("/dev/socket/my_module", moduleEndpoint); if (ipc != NULL) { MinkIPC_join(ipc); MinkIPC_release(ipc); } } ``` -------------------------------- ### Initialize and Manage MinkSocket Source: https://context7.com/qualcomm/minkipc/llms.txt Demonstrates creating a MinkSocket instance, initializing the object table, and starting the socket. Ensure the endpoint object is valid before initialization. ```c #include "minksocket.h" #include "SockAgnostic.h" #include "object.h" #include // Create MinkSocket with endpoint object void setup_mink_socket() { Object endpoint = create_service_endpoint(); // Create socket for UNIX domain MinkSocket *mSock = MinkSocket_new( endpoint, UNIX, // Socket type: UNIX, QIPCRTR, VSOCK, QMSGQ -1, // Socket fd (-1 to create new) 0, // Node (for QRTR/VSOCK) 0 // Port ); if (mSock != NULL) { // Initialize object table with the endpoint int32_t result = MinkSocket_initObjectTable(mSock, endpoint, false); if (result == Object_OK) { // Start handling connections MinkSocket_start(mSock, -1); // Check if socket is alive if (MinkSocket_isAlive(mSock)) { printf("MinkSocket is running\n"); } } // Cleanup MinkSocket_release(mSock); } } ``` -------------------------------- ### Build MINK IPC Project Source: https://github.com/qualcomm/minkipc/blob/main/README.md Instructions for cloning, building, and installing the MINK IPC package using CMake. Requires QCBOR and QCOMTEE dependencies. ```bash git clone https://github.com/qualcomm/minkipc.git cd minkipc mkdir build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=CMakeToolchain.txt -DBUILD_UNITTEST=ON && cmake --build . --target install --config Release ``` -------------------------------- ### Perform RPMB Operations in QTEE Application Source: https://github.com/qualcomm/minkipc/blob/main/listeners/librpmbservice/README.md Examples for programming keys, writing secure data, and reading data using the RPMB service structures. ```c // Program RPMB key (one-time operation) tz_rpmb_program_key_req_t key_req; key_req.cmd_id = TZ_RPMB_MSG_CMD_RPMB_PROGRAM_KEY; strncpy(key_req.device_path, "/dev/mmcblk0rpmb", sizeof(key_req.device_path)-1); memcpy(key_req.key, authentication_key, RPMB_KEY_SIZE); // Send via MINK IPC to RPMB service // Write secure data tz_rpmb_write_data_req_t write_req; write_req.cmd_id = TZ_RPMB_MSG_CMD_RPMB_WRITE_DATA; strncpy(write_req.device_path, "/dev/mmcblk0rpmb", sizeof(write_req.device_path)-1); write_req.address = 0; write_req.block_count = 1; memcpy(write_req.data, secure_data, RPMB_DATA_SIZE); memcpy(write_req.key, authentication_key, RPMB_KEY_SIZE); // Send via MINK IPC to RPMB service // Read secure data tz_rpmb_read_data_req_t read_req; read_req.cmd_id = TZ_RPMB_MSG_CMD_RPMB_READ_DATA; strncpy(read_req.device_path, "/dev/mmcblk0rpmb", sizeof(read_req.device_path)-1); read_req.address = 0; read_req.block_count = 1; generate_nonce(read_req.nonce); // Send via MINK IPC to RPMB service ``` -------------------------------- ### Start Service on Existing Socket Descriptor Source: https://context7.com/qualcomm/minkipc/llms.txt Starts a MinkIPC service on an already open socket descriptor. Supports various IPC types like UNIX, VSOCK, QRTR, and QMSGQ. ```c // Start service on existing socket descriptor void start_service_on_socket(int sockFd) { Object endpoint = { .invoke = ServiceObject_invoke, .context = NULL }; // For UNIX socket MinkIPC *ipc = MinkIPC_startServiceOnSocket(sockFd, endpoint); // For VSOCK (inter-VM) // MinkIPC *ipc = MinkIPC_startServiceOnSocket_vsock(sockFd, endpoint); // For QIPCRTR (inter-VM via QRTR) // MinkIPC *ipc = MinkIPC_startServiceOnSocket_QRTR(sockFd, endpoint); // For QMSGQ // MinkIPC *ipc = MinkIPC_startServiceModuleOnSocket_QMSGQ(sockFd, endpoint); if (ipc) { MinkIPC_join(ipc); MinkIPC_release(ipc); } } ``` -------------------------------- ### Connect to MinkIPC Services Source: https://context7.com/qualcomm/minkipc/llms.txt Examples of establishing connections to remote services using different transport protocols and handling proxy objects. ```c #include "minkipc.h" #include "object.h" #include // Connect to a UNIX socket service int connect_to_unix_service() { Object proxy = Object_NULL; // Connect and get proxy object MinkIPC *ipc = MinkIPC_connect("/tmp/my_mink_service", &proxy); if (ipc == NULL || Object_isNull(proxy)) { printf("Failed to connect to service\n"); return -1; } printf("Connected to service\n"); // Invoke methods on the proxy object // The proxy transparently marshals calls to the remote service ObjectArg args[2]; char request[] = "get_data"; char response[256] = {0}; args[0].b.ptr = request; args[0].b.size = sizeof(request); args[1].b.ptr = response; args[1].b.size = sizeof(response); int32_t result = Object_invoke(proxy, 1, args, ObjectCounts_pack(1, 1, 0, 0)); if (Object_isOK(result)) { printf("Response: %s\n", response); } // Cleanup Object_release(proxy); MinkIPC_release(ipc); return 0; } // Connect to IModule service (with credential support) int connect_to_module_service() { Object proxy = Object_NULL; MinkIPC *ipc = MinkIPC_connectModule("/dev/socket/my_module", &proxy); if (ipc != NULL && !Object_isNull(proxy)) { // Use the module proxy for credential-aware operations // IModule extends IOpener with caller credential forwarding Object_release(proxy); MinkIPC_release(ipc); return 0; } return -1; } // Connect via QIPCRTR (for inter-VM communication) int connect_via_qrtr(int qrtrPort) { Object proxy = Object_NULL; // Connect to service on QRTR port (e.g., 5008 for QTVM) MinkIPC *ipc = MinkIPC_connect_QRTR(qrtrPort, &proxy); if (ipc && !Object_isNull(proxy)) { // Invoke remote VM service Object_release(proxy); MinkIPC_release(ipc); return 0; } return -1; } // Connect via VSOCK (for hypervisor-based inter-VM) int connect_via_vsock(int vsockPort) { Object proxy = Object_NULL; MinkIPC *ipc = MinkIPC_connect_vsock(vsockPort, &proxy); if (ipc && !Object_isNull(proxy)) { Object_release(proxy); MinkIPC_release(ipc); return 0; } return -1; } // Connect with IModule via different transports int connect_module_variants() { Object proxy = Object_NULL; MinkIPC *ipc; // QRTR with credential forwarding ipc = MinkIPC_connectModule_QRTR(5008, &proxy); // Or VSOCK with credential forwarding // ipc = MinkIPC_connectModule_vsock(1234, &proxy); // Or QMSGQ with credential forwarding // ipc = MinkIPC_connectModule_QMSGQ(port, &proxy); // Or simulated (for testing) // ipc = MinkIPC_connectModule_simulated("/tmp/sim_service", &proxy); if (ipc && !Object_isNull(proxy)) { Object_release(proxy); MinkIPC_release(ipc); return 0; } return -1; } ``` -------------------------------- ### Start UNIX Socket Service with IOpener Source: https://context7.com/qualcomm/minkipc/llms.txt Initiates a MinkIPC service on a UNIX socket using the IOpener interface. Requires the service to be joined and then released. ```c // Start a UNIX socket service with IOpener interface void start_unix_service() { Object endpoint = { .invoke = ServiceObject_invoke, .context = NULL }; // Start service on UNIX socket MinkIPC *ipc = MinkIPC_startService("/tmp/my_mink_service", endpoint); if (ipc != NULL) { printf("Service started on /tmp/my_mink_service\n"); // Wait for service to finish MinkIPC_join(ipc); // Cleanup MinkIPC_release(ipc); } } ``` -------------------------------- ### Establish QTEE Communication with Auto-Generated Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt Use this function to get the root environment, register a client environment with auto-generated credentials, and allocate shared memory for QTEE interaction. Ensure all allocated objects are released. ```c #include "MinkCom.h" #include "object.h" #include int communicate_with_qtee() { Object rootEnv = Object_NULL; Object clientEnv = Object_NULL; Object memObj = Object_NULL; int32_t result; // Step 1: Get the Root Environment Object // This is the entry point for all QTEE communication result = MinkCom_getRootEnvObject(&rootEnv); if (result != Object_OK) { printf("Failed to get root environment: %d\n", result); return -1; } // Step 2: Get a Client Environment with auto-generated credentials // The ClientEnv is registered with QTEE for subsequent operations result = MinkCom_getClientEnvObject(rootEnv, &clientEnv); if (result != Object_OK) { printf("Failed to get client environment: %d\n", result); Object_release(rootEnv); return -1; } // Step 3: Allocate a Memory Object for sharing data with QTEE // Memory objects represent physically contiguous memory size_t memSize = 4096; // 4KB shared buffer result = MinkCom_getMemoryObject(rootEnv, memSize, &memObj); if (result != Object_OK) { printf("Failed to allocate memory object: %d\n", result); Object_release(clientEnv); Object_release(rootEnv); return -1; } // Step 4: Get memory object info (virtual address and actual size) void *memAddr = NULL; size_t actualSize = 0; result = MinkCom_getMemoryObjectInfo(memObj, &memAddr, &actualSize); if (result != Object_OK) { printf("Failed to get memory info: %d\n", result); } else { // Write data to shared memory snprintf((char*)memAddr, actualSize, "Data for QTEE processing"); printf("Shared memory at %p, size: %zu\n", memAddr, actualSize); } // Use clientEnv to invoke QTEE services... // The clientEnv object can be used with IDL-generated stubs // Cleanup - release all objects in reverse order Object_release(memObj); Object_release(clientEnv); Object_release(rootEnv); return 0; } ``` -------------------------------- ### Advanced Generic Service Start Source: https://context7.com/qualcomm/minkipc/llms.txt A generic function to start a MinkIPC service with all parameters, including address, socket descriptor, IPC type, endpoint, and endpoint type. Handles success and failure reporting. ```c // Advanced: Generic service start with all parameters void start_advanced_service(const char *address, int sockFd, int ipcType, Object endpoint, int endpointType) { MinkIPC *ipc = NULL; // ipcType: UNIX, QIPCRTR, VSOCK, QMSGQ, SIMULATED // endpointType: OPENER (IOpener) or MODULE (IModule) int32_t result = MinkIPC_beginService(address, sockFd, ipcType, endpoint, endpointType, &ipc); if (result == Object_OK && ipc != NULL) { printf("Advanced service started successfully\n"); MinkIPC_join(ipc); MinkIPC_release(ipc); } else { printf("Failed to start service: %d\n", result); } } ``` -------------------------------- ### Clone MinkIPC Repository Source: https://github.com/qualcomm/minkipc/blob/main/CONTRIBUTING.md Clone the MinkIPC repository to your local machine to begin contributing. Ensure you have Git installed. ```bash git clone https://github.com/qualcomm/minkipc.git ``` -------------------------------- ### Block Comment for Calculation Source: https://github.com/qualcomm/minkipc/blob/main/CODING-STYLE.md Example of using a block comment to explain a simple calculation. This style is allowed for both short and detailed explanations. ```c /* Calculate the cube of z */ if (z > 0) { return z * z * z; } ... ``` -------------------------------- ### Configure Project and Dependencies Source: https://github.com/qualcomm/minkipc/blob/main/libminkadaptor/tests/smcinvoke_client/CMakeLists.txt Initializes the project, sets the module path, and locates the required QCBOR package. ```cmake project(smcinvoke_client CXX) # ''Packages''. # Append modules directory. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(QCBOR_DIR_HINT "" CACHE PATH "Hint path for QCBOR directory") find_package(QCBOR REQUIRED) if(NOT QCBOR_FOUND) message(FATAL_ERROR "QCBOR not found") endif() include_directories(${QCBOR_INCLUDE_DIRS}) ``` -------------------------------- ### Initialize and Configure MinkHub Source: https://context7.com/qualcomm/minkipc/llms.txt Sets up the MinkHub instance with remote socket addresses for various domains and registers local services via a session. ```c #include "MinkHub.h" #include "object.h" #include // Initialize MinkHub with remote connections int setup_mink_hub() { MinkHub *hub = NULL; Object envCred = Object_NULL; // Environment credentials // Define remote socket addresses for different domains RemoteSocketAddrInfo remoteInfo[] = { // QTEE connection (via smcinvoke driver) { .ipcType = MINKHUB_QTEE, .openerType = IMODULE, .addr = "" // Not used for QTEE }, // QTVM connection via QIPCRTR { .ipcType = MINKHUB_QIPCRTR, .openerType = IMODULE, .addr = "5008" // QRTR port }, // OEM VM connection via VSOCK { .ipcType = MINKHUB_VSOCK, .openerType = IMODULE, .addr = "5010" }, // Local UNIX socket for intra-VM { .ipcType = MINKHUB_UNIX, .openerType = IOPENER, .addr = "/dev/socket/local_mink" } }; // Create MinkHub instance int32_t result = MinkHub_new(remoteInfo, 4, envCred, &hub); if (result != MINKHUB_OK) { printf("Failed to create MinkHub: %d\n", result); return -1; } printf("MinkHub created successfully\n"); // Create a session for service registration MinkHubSession *session = NULL; result = MinkHub_createSession(hub, &session); if (result == MINKHUB_OK) { // Register local services with the hub uint32_t serviceUids[] = {0x1000, 0x1001, 0x1002}; // Service UIDs Object moduleObj = create_module_object(); // IModule implementation result = MinkHub_registerServices(session, serviceUids, 3, moduleObj); if (result == MINKHUB_OK) { printf("Services registered successfully\n"); } } return 0; } ``` -------------------------------- ### Establish QTEE Communication with Custom Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt This function demonstrates how to obtain a client environment using custom credentials, after first acquiring the root environment object. Remember to release all acquired objects. ```c // Alternative: Get ClientEnv with custom credentials int communicate_with_custom_credentials(Object customCreds) { Object rootEnv = Object_NULL; Object clientEnv = Object_NULL; if (MinkCom_getRootEnvObject(&rootEnv) != Object_OK) { return -1; } // Use self-generated credentials for registration int32_t result = MinkCom_getClientEnvObjectWithCreds(rootEnv, customCreds, &clientEnv); if (result == Object_OK) { // Client is now registered with QTEE using custom credentials // Proceed with secure operations... } Object_RELEASE_IF(clientEnv); Object_release(rootEnv); return (result == Object_OK) ? 0 : -1; } ``` -------------------------------- ### Define Executable and Include Directories Source: https://github.com/qualcomm/minkipc/blob/main/optee-test/CMakeLists.txt Sets up the project executable and specifies the private include directories required for compilation. ```cmake add_executable (${PROJECT_NAME} ${SRC}) target_include_directories(${PROJECT_NAME} PRIVATE optee_test/host/xtest PRIVATE optee_test/host/supp_plugin/include PRIVATE optee_test/host/xtest/adbg/include PRIVATE ${CMAKE_SOURCE_DIR}/optee-client/optee_client/libteec/include PRIVATE optee_os/lib/libutee/include PRIVATE optee_os/lib/libutils/ext/include PRIVATE optee_os/core/include PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${GP_INCLUDES} ) ``` -------------------------------- ### Build Binary and Link Dependencies Source: https://github.com/qualcomm/minkipc/blob/main/libminkadaptor/tests/smcinvoke_client/CMakeLists.txt Defines the source files, creates the executable, and configures include directories and library linking. ```cmake set(SRC src/smcinvoke_client.cpp src/CTestCallable.cpp src/CIO.c ) add_executable(${PROJECT_NAME} ${SRC}) # The binary depends on the MINK-IDLs add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_MINKHEADERS) # ''Headers and dependencies''. target_include_directories(${PROJECT_NAME} PRIVATE src PRIVATE include PRIVATE idl ) target_link_libraries(${PROJECT_NAME} PRIVATE minkadaptor PRIVATE ${QCBOR_LIBRARIES} ) install(TARGETS ${PROJECT_NAME} DESTINATION "${CMAKE_INSTALL_BINDIR}") ``` -------------------------------- ### Open Local and Remote Services Source: https://context7.com/qualcomm/minkipc/llms.txt Demonstrates how to open services using local resolution or remote routing through the MinkHub broker. ```c // Open a service via MinkHub (local resolution) int open_local_service(MinkHub *hub, uint32_t serviceUid) { Object cred = Object_NULL; // Caller credentials Object service = Object_NULL; // Open service for local caller int32_t result = MinkHub_localOpen(hub, true, cred, serviceUid, &service); if (result == MINKHUB_OK && !Object_isNull(service)) { printf("Local service 0x%x opened successfully\n", serviceUid); // Use the service object... Object_release(service); return 0; } printf("Failed to open service 0x%x: %d\n", serviceUid, result); return -1; } // Open a remote service (routes to QTEE/QTVM/OEM VM) int open_remote_service(MinkHub *hub, MinkHubSession *session, Object procCred, uint32_t serviceUid) { Object service = Object_NULL; // Open service - hub routes to appropriate remote domain int32_t result = MinkHub_remoteOpen(hub, session, procCred, serviceUid, &service); if (result == MINKHUB_OK && !Object_isNull(service)) { printf("Remote service 0x%x opened\n", serviceUid); // The returned service is a proxy to the remote domain // All invocations are transparently forwarded Object_release(service); return 0; } if (result == MINKHUB_ERROR_SERVICE_NOT_FOUND) { printf("Service 0x%x not found in any domain\n", serviceUid); } return -1; } ``` -------------------------------- ### Run QTEE Diagnostics with smcinvoke_client Source: https://github.com/qualcomm/minkipc/blob/main/libminkadaptor/README.md Execute QTEE diagnostics by running the smcinvoke_client binary with the -d flag, specifying the number of iterations. ```bash smcinvoke_client -d ``` -------------------------------- ### Communicate with a Trusted Application using TEEC Source: https://context7.com/qualcomm/minkipc/llms.txt Demonstrates the standard workflow of initializing a context, opening a session, and invoking a command with temporary memory references and value parameters. ```c #include "tee_client_api.h" #include #include // UUID for the target Trusted Application static const TEEC_UUID ta_uuid = { 0x12345678, 0x1234, 0x1234, {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0} }; int communicate_with_trusted_app() { TEEC_Context ctx; TEEC_Session session; TEEC_Operation operation; TEEC_Result result; uint32_t returnOrigin; // Initialize context - connects to TEE result = TEEC_InitializeContext(NULL, &ctx); // NULL = default QTEE if (result != TEEC_SUCCESS) { printf("Failed to initialize context: 0x%x\n", result); return -1; } // Open session with the Trusted Application memset(&operation, 0, sizeof(operation)); operation.paramTypes = TEEC_PARAM_TYPES( TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE ); result = TEEC_OpenSession(&ctx, &session, &ta_uuid, TEEC_LOGIN_PUBLIC, NULL, &operation, &returnOrigin); if (result != TEEC_SUCCESS) { printf("Failed to open session: 0x%x (origin: %u)\n", result, returnOrigin); TEEC_FinalizeContext(&ctx); return -1; } printf("Session opened with TA\n"); // Invoke a command with parameters char inputBuffer[256] = "Hello from HLOS"; char outputBuffer[256] = {0}; TEEC_Value valueParam; memset(&operation, 0, sizeof(operation)); operation.started = 0; operation.paramTypes = TEEC_PARAM_TYPES( TEEC_MEMREF_TEMP_INPUT, // Input buffer TEEC_MEMREF_TEMP_OUTPUT, // Output buffer TEEC_VALUE_INOUT, // Value parameter TEEC_NONE ); // Set up temporary memory references operation.params[0].tmpref.buffer = inputBuffer; operation.params[0].tmpref.size = strlen(inputBuffer) + 1; operation.params[1].tmpref.buffer = outputBuffer; operation.params[1].tmpref.size = sizeof(outputBuffer); operation.params[2].value.a = 42; operation.params[2].value.b = 0; // Invoke command ID 1 in the TA result = TEEC_InvokeCommand(&session, 1, &operation, &returnOrigin); if (result == TEEC_SUCCESS) { printf("TA response: %s\n", outputBuffer); printf("Value result: a=%u, b=%u\n", operation.params[2].value.a, operation.params[2].value.b); } else { printf("Command failed: 0x%x (origin: %u)\n", result, returnOrigin); } // Close session and finalize context TEEC_CloseSession(&session); TEEC_FinalizeContext(&ctx); return (result == TEEC_SUCCESS) ? 0 : -1; } ``` -------------------------------- ### Build MINK IPC framework Source: https://context7.com/qualcomm/minkipc/llms.txt Commands to clone, configure, and build the MINK IPC repository using CMake. ```bash # Clone the repository git clone https://github.com/qualcomm/minkipc.git cd minkipc # Create build directory mkdir build && cd build # Configure with CMake cmake .. \ -DCMAKE_TOOLCHAIN_FILE=CMakeToolchain.txt \ -DBUILD_UNITTEST=ON \ -DBUILD_MINKTEEC=ON \ -DQCBOR_DIR_HINT=/path/to/qcbor/install \ -DQCOMTEE_DIR_HINT=/path/to/qcomtee/install \ -DCMAKE_INSTALL_PREFIX=/path/to/minkipc/install # Build cmake --build . --target install --config Release # Optional: Build RPMB listener cmake .. -DBUILD_RPMB_LISTENER=ON make rpmbservice ``` -------------------------------- ### Create Environment Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt Generates credentials for VM identification, requiring a VM UUID and domain information. ```c int create_environment_credentials() { Object envCred = Object_NULL; uint8_t vmUUID[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; uint8_t vmHash[32] = {0}; // SHA256 of VM binary int32_t result = OSIndCredentials_newEnvCred( "Android", // OS ID vmUUID, // VM UUID vmHash, // VM hash (optional) "oem", // VM domain 1, // VM version &envCred ); if (result == Object_OK) { printf("Environment credentials created\n"); Object_release(envCred); return 0; } return -1; } ``` -------------------------------- ### Run Global Platform compliance tests via C API Source: https://context7.com/qualcomm/minkipc/llms.txt Iterates through a directory of TAs, initializes a TEE context, and invokes basic commands to verify compliance. ```c #include "tee_client_api.h" #include "gp_load_ta.h" #include #include #include // Test multiple TAs from a directory int run_gp_tests(const char *taDirectory) { DIR *dir = opendir(taDirectory); if (!dir) { printf("Cannot open TA directory: %s\n", taDirectory); return -1; } TEEC_Context ctx; TEEC_Result result = TEEC_InitializeContext(NULL, &ctx); if (result != TEEC_SUCCESS) { closedir(dir); return -1; } struct dirent *entry; int testsPassed = 0; int testsFailed = 0; while ((entry = readdir(dir)) != NULL) { // Skip non-TA files if (strstr(entry->d_name, ".ta") == NULL) { continue; } char taPath[512]; snprintf(taPath, sizeof(taPath), "%s/%s", taDirectory, entry->d_name); printf("Testing TA: %s\n", entry->d_name); // Load and test the TA TEEC_UUID uuid; if (gp_load_ta_get_uuid(taPath, &uuid) == 0) { TEEC_Session session; uint32_t returnOrigin; result = TEEC_OpenSession(&ctx, &session, &uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, &returnOrigin); if (result == TEEC_SUCCESS) { // Run standard GP test commands TEEC_Operation op; memset(&op, 0, sizeof(op)); // Test command 0: Basic invoke result = TEEC_InvokeCommand(&session, 0, &op, &returnOrigin); if (result == TEEC_SUCCESS) { printf(" PASS: %s\n", entry->d_name); testsPassed++; } else { printf(" FAIL: %s (invoke error 0x%x)\n", entry->d_name, result); testsFailed++; } TEEC_CloseSession(&session); } else { printf(" FAIL: %s (session error 0x%x)\n", entry->d_name, result); testsFailed++; } } } closedir(dir); TEEC_FinalizeContext(&ctx); printf("\nTest Results: %d passed, %d failed\n", testsPassed, testsFailed); return (testsFailed == 0) ? 0 : -1; } ``` -------------------------------- ### Create Vendor Client Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt Generates simple process credentials for a vendor client using process and user IDs. ```c int create_vendor_credentials() { Object procCred = Object_NULL; // Simple vendor client credentials int32_t result = OSIndCredentials_newLAVendor( "my_vendor_app", // Application name getpid(), // Process ID getuid(), // User ID &procCred ); if (result == Object_OK) { printf("Vendor credentials created\n"); // Use procCred with MinkHub or other services Object_release(procCred); return 0; } return -1; } ``` -------------------------------- ### Run Global Platform TEE Client Tests Source: https://github.com/qualcomm/minkipc/blob/main/libminkteec/README.md Execute the `gp_test_client` binary with the path to Global Platform Trust Anchor Services (TAS) to run tests. ```bash gp_test_client /path/to/gp/tas ``` -------------------------------- ### Create Full Process Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt Generates comprehensive process credentials including permission bitmasks, application hashes, and domain information. ```c int create_full_process_credentials() { Object procCred = Object_NULL; SHA256Hash appHash = {0}; // SHA256 of application binary uint8_t legacyCBOR[256]; // Legacy CBOR credentials blob size_t cborLen = 0; int32_t result = OSIndCredentials_newProcessCred( 0x0001 | 0x0002, // Permission bitmask "secure_app", // Application name &appHash, // Application hash (optional) 0, // Debug flag 1, // Application version legacyCBOR, // Legacy CBOR blob (optional) cborLen, // CBOR blob length "oem", // Domain: "qti", "oem", "alt", "isv", "unk" getpid(), // Process ID getuid(), // User ID &procCred ); if (result == Object_OK) { printf("Full process credentials created\n"); Object_release(procCred); return 0; } return -1; } ``` -------------------------------- ### Register Existing Application Memory as Shared Memory Source: https://context7.com/qualcomm/minkipc/llms.txt Demonstrates how to register pre-allocated application memory for use within TEE operations. ```c // Register existing memory as shared memory int register_existing_memory() { TEEC_Context ctx; TEEC_SharedMemory sharedMem; char myBuffer[1024]; TEEC_InitializeContext(NULL, &ctx); // Register application-owned memory sharedMem.buffer = myBuffer; sharedMem.size = sizeof(myBuffer); sharedMem.flags = TEEC_MEM_INPUT; TEEC_Result result = TEEC_RegisterSharedMemory(&ctx, &sharedMem); if (result == TEEC_SUCCESS) { // Memory is now available for TEE operations // Use in TEEC_MEMREF_WHOLE, TEEC_MEMREF_PARTIAL_* params ``` -------------------------------- ### Run QTEE Diagnostics Source: https://context7.com/qualcomm/minkipc/llms.txt Executes diagnostic commands on a Trusted Application. Requires the tzecotestapp.mbn TA to be loaded. ```c #include "MinkCom.h" #include "object.h" #include // Example: Run QTEE diagnostics int run_qtee_diagnostics(int iterations) { Object rootEnv = Object_NULL; Object clientEnv = Object_NULL; // Get root and client environment if (MinkCom_getRootEnvObject(&rootEnv) != Object_OK) { return -1; } if (MinkCom_getClientEnvObject(rootEnv, &clientEnv) != Object_OK) { Object_release(rootEnv); return -1; } // Run diagnostic invocations for (int i = 0; i < iterations; i++) { struct qsc_send_cmd cmd = { .cmd_id = 0, // Diagnostic command .data = i, .len = 0 }; struct qsc_send_cmd_rsp rsp = {0}; ObjectArg args[2]; args[0].bi.ptr = &cmd; args[0].bi.size = sizeof(cmd); args[1].b.ptr = &rsp; args[1].b.size = sizeof(rsp); int32_t result = Object_invoke(clientEnv, 1, args, ObjectCounts_pack(1, 1, 0, 0)); if (Object_isOK(result)) { printf("Iteration %d: status=%d\n", i, rsp.status); } } Object_release(clientEnv); Object_release(rootEnv); return 0; } ``` -------------------------------- ### Wrap Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt Combines separate process and environment credentials into a single wrapped credentials object. ```c int create_wrapped_credentials() { Object procCred = Object_NULL; Object envCred = Object_NULL; Object wrappedCred = Object_NULL; // Create process credentials OSIndCredentials_newLAVendor("app", getpid(), getuid(), &procCred); // Create environment credentials uint8_t vmUUID[16] = {0}; OSIndCredentials_newEnvCred("Android", vmUUID, NULL, "oem", 1, &envCred); // Wrap both into a single credentials object int32_t result = OSIndCredentials_WrapCredentials( &procCred, &envCred, &wrappedCred ); if (result == Object_OK) { printf("Wrapped credentials created\n"); // wrappedCred contains both process and environment info Object_release(wrappedCred); } Object_RELEASE_IF(procCred); Object_RELEASE_IF(envCred); return (result == Object_OK) ? 0 : -1; } ``` -------------------------------- ### Configure Ccache and Dependencies Source: https://github.com/qualcomm/minkipc/blob/main/optee-test/CMakeLists.txt Enables ccache for faster builds if available and locates required system packages. ```cmake find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) endif(CCACHE_FOUND) add_subdirectory (optee_test/ta) ################################################################################ # Packages ################################################################################ find_package(Threads REQUIRED) if(NOT THREADS_FOUND) message(FATAL_ERROR "Threads not found") endif() find_package(OpenSSL) if(OPENSSL_FOUND) add_compile_options(-DOPENSSL_FOUND=1 -DOPENSSL_API_COMPAT=10100) set (OPENSSL_PRIVATE_LINK OpenSSL::Crypto) endif() find_package(Python REQUIRED) ``` -------------------------------- ### Create System Application Credentials Source: https://context7.com/qualcomm/minkipc/llms.txt Generates credentials specifically for system-level applications (APK clients) with defined permissions. ```c int create_system_app_credentials() { Object procCred = Object_NULL; SHA256Hash appHash; uint8_t legacyCBOR[512]; // Compute app hash and legacy CBOR... memset(&appHash, 0xAB, sizeof(appHash)); int32_t result = OSIndCredentials_newLASystem( "com.example.secureapp", // Package name &appHash, // App signature hash 0, // Debug flag (0 = release) 100, // Version code legacyCBOR, // Legacy CBOR 0, // CBOR length "isv", // Domain getpid(), getuid(), 0xFFFF, // Permissions &procCred ); if (result == Object_OK) { Object_release(procCred); return 0; } return -1; } ``` -------------------------------- ### Run smcinvoke Test Client Source: https://context7.com/qualcomm/minkipc/llms.txt Executes diagnostic tests or callback object tests using the smcinvoke_client binary. ```bash # Run QTEE diagnostics test smcinvoke_client -d # Test callback objects - requires tzecotestapp.mbn TA smcinvoke_client -c /path/to/tzecotestapp.mbn ``` -------------------------------- ### Configure Project and Compiler Flags Source: https://github.com/qualcomm/minkipc/blob/main/optee-test/CMakeLists.txt Sets project options and applies a comprehensive set of compiler warnings and flags to ensure code quality. ```cmake project (xtest_qtee C) option(CFG_WERROR "Build with -Werror" FALSE) option(CFG_PKCS11_TA "Build with PKCS11" TRUE) set (OPTEE_TEST_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/optee_test) ################################################################################ # Compiler flags: # We want to use the same flags in the entire optee_client git ################################################################################ add_compile_options ( -Wall -Wbad-function-cast -Wcast-align -Werror-implicit-function-declaration -Wextra -Wfloat-equal -Wformat-nonliteral -Wformat-security -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wshadow -Wstrict-prototypes -Wswitch-default -Wunsafe-loop-optimizations -Wwrite-strings -fPIC -Wno-missing-field-initializers -Wno-unused-parameter -Wno-alloc-size -Wno-unterminated-string-initialization ) if(CFG_WERROR) add_compile_options(-Werror) endif(CFG_WERROR) ``` -------------------------------- ### Run Callback Objects test with smcinvoke_client Source: https://github.com/qualcomm/minkipc/blob/main/libminkadaptor/README.md Test callback object functionality by running smcinvoke_client with the -c flag, providing the path to the Tzeco test application binary and the number of iterations. ```bash smcinvoke_client -c /path/to/tzecotestapp.mbn ``` -------------------------------- ### smcinvoke_client Command Source: https://context7.com/qualcomm/minkipc/llms.txt Command-line utility to invoke Trusted Applications. Used for testing memory objects and requires the tzecotestapp.mbn TA. ```bash smcinvoke_client -m /path/to/tzecotestapp.mbn ``` -------------------------------- ### Configure SockAgnostic for Multi-Protocol Support Source: https://context7.com/qualcomm/minkipc/llms.txt Initializes a protocol-agnostic socket layer for server-side operations. Handles binding, listening, and peer identity retrieval. ```c // Socket agnostic layer for multi-protocol support void setup_socket_agnostic() { SockAgnostic sockAgn; // Initialize for UNIX socket int32_t result = SockAgnostic_new( "/tmp/mink_socket", // Address (for UNIX) -1, // Socket fd (-1 to create) UNIX, // Socket type true, // Is server? &sockAgn ); if (result == 0) { // Bind and listen SockAgnostic_bind(&sockAgn); SockAgnostic_listen(&sockAgn, MAX_QUEUE_LENGTH); // Accept connections SockAgnostic newClient; if (SockAgnostic_accept(&sockAgn, &newClient) == 0) { // Handle client connection // Get peer identity (credentials) CredInfo credInfo; uint8_t *vmuuid = NULL; size_t vmuuidLen = 0; SockAgnostic_getPeerIdentity(&newClient, &credInfo, &vmuuid, &vmuuidLen); SockAgnostic_close(&newClient); } SockAgnostic_close(&sockAgn); } } ``` -------------------------------- ### Run Memory Objects test with smcinvoke_client Source: https://github.com/qualcomm/minkipc/blob/main/libminkadaptor/README.md Test memory object functionality by running smcinvoke_client with the -m flag, providing the path to the Tzeco test application binary and the number of iterations. ```bash smcinvoke_client -m /path/to/tzecotestapp.mbn ``` -------------------------------- ### ObjectCounts Packing Source: https://github.com/qualcomm/minkipc/blob/main/docs/mink-object.md Explains how to define the argument structure for an object invocation. ```APIDOC ## ObjectCounts_pack ### Description Constructs the ObjectCounts parameter to specify the number and type of arguments passed during an invocation. ### Parameters - **nBuffersIn** (uint32_t) - Required - Number of input buffers. - **nBuffersOut** (uint32_t) - Required - Number of output buffers. - **nObjectsIn** (uint32_t) - Required - Number of input objects. - **nObjectsOut** (uint32_t) - Required - Number of output objects. ### Request Example ObjectCounts k = ObjectCounts_pack(2, 0, 0, 1); ``` -------------------------------- ### Service Implementation Object Source: https://context7.com/qualcomm/minkipc/llms.txt Defines the invoke method for a service object, handling method calls and object creation for the IOpener interface. ```c #include "minkipc.h" #include "object.h" #include // Service implementation object static int32_t ServiceObject_invoke(ObjectCxt ctx, ObjectOp op, ObjectArg *args, ObjectCounts counts) { uint32_t methodId = ObjectOp_methodID(op); if (methodId == Object_OP_release) { return Object_OK; } // Handle service-specific methods switch (methodId) { case 0: // open() method for IOpener // Return a service object if (ObjectCounts_numOO(counts) > 0) { // Create and return a new service instance args[ObjectCounts_indexOO(counts)].o = create_service_instance(); } return Object_OK; default: return Object_ERROR_INVALID; } } ``` -------------------------------- ### Cleanup MinkHub Resources Source: https://context7.com/qualcomm/minkipc/llms.txt Properly destroys sessions and the MinkHub instance to free allocated resources. ```c // Cleanup MinkHub resources void cleanup_hub(MinkHub *hub, MinkHubSession *session) { if (session) { MinkHub_destroySession(session); } if (hub) { MinkHub_destroy(hub); } } ```