TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context* context, TEEC_SharedMemory* sharedMem) { TEEC_Result ret; dprintk(KERN_DEBUG "TEEC_AllocateSharedMemory: requested=%lu", (unsigned long)sharedMem->size); if (sharedMem->size == 0) { /* Allocating 0 bytes must return a non-NULL pointer, but the pointer doesn't need to be to memory that is mapped anywhere. So we return a pointer into an unmapped page. */ sharedMem->buffer = TEEC_POINTER_TO_ZERO_SIZED_BUFFER; } else { sharedMem->buffer = internal_vmalloc(sharedMem->size); if (sharedMem->buffer == NULL) { dprintk(KERN_INFO "TEEC_AllocateSharedMemory: could not allocate %lu bytes", (unsigned long)sharedMem->size); return TEEC_ERROR_OUT_OF_MEMORY; } } ret = TEEC_RegisterSharedMemory(context, sharedMem); if (ret == TEEC_SUCCESS) { sharedMem->imp._allocated = 1; } else { internal_vfree(sharedMem->buffer); sharedMem->buffer = NULL; memset(&sharedMem->imp, 0, sizeof(sharedMem->imp)); } return ret; }
static TEEC_Result do_counter_tests(TEEC_Session *session, TEEC_Context *context) { TEEC_Result ret; uint64_t previous_value; TEEC_SharedMemory inout_mem = {0}; uint64_t value; inout_mem.buffer = &value; inout_mem.size = sizeof(value); inout_mem.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; ret = TEEC_RegisterSharedMemory(context, &inout_mem); if (ret != TEE_SUCCESS) { printf("Failed to register shared memory"); goto end; } /* Get and increment the counter for the first time */ ret = invoke_command(session, &inout_mem, CMD_GET_CTR); if (ret != TEEC_SUCCESS) goto end; previous_value = value; printf("Value after the first get_counter: %d\n", (int)value); /* Increment it again and check that the value has changed */ ret = invoke_command(session, &inout_mem, CMD_GET_CTR); if (ret != TEEC_SUCCESS) goto end; printf("Value after the second get_counter: %d\n", (int)value); if (++previous_value != value) ret = TEEC_ERROR_GENERIC; end: TEEC_ReleaseSharedMemory(&inout_mem); return ret; }
int main() { TEEC_Context context; TEEC_Session session; TEEC_Operation operation; TEEC_SharedMemory in_mem; TEEC_SharedMemory out_mem; TEEC_Result ret; uint32_t return_origin; uint32_t connection_method = TEEC_LOGIN_PUBLIC; char data[DATA_SIZE]; uint8_t sha1[SHA1_SIZE]; int i; printf("START: example SHA1 calc app\n"); memset((void *)&in_mem, 0, sizeof(in_mem)); memset((void *)&out_mem, 0, sizeof(out_mem)); memset((void *)&operation, 0, sizeof(operation)); memset(data, 'y', DATA_SIZE); memset(sha1, 0, SHA1_SIZE); /* Initialize context */ printf("Initializing context: "); ret = TEEC_InitializeContext(NULL, &context); if (ret != TEEC_SUCCESS) { printf("TEEC_InitializeContext failed: 0x%x\n", ret); goto end_1; } else { printf("initiliazed\n"); } /* Open session is expecting HASH algorithm */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].value.a = HASH_SHA1; /* Open session */ printf("Openning session: "); ret = TEEC_OpenSession(&context, &session, &uuid, connection_method, NULL, &operation, &return_origin); if (ret != TEEC_SUCCESS) { printf("TEEC_OpenSession failed: 0x%x\n", ret); goto end_2; } else { printf("opened\n"); } /* Register shared memory for initial hash */ /* Data */ in_mem.buffer = data; in_mem.size = DATA_SIZE; in_mem.flags = TEEC_MEM_INPUT; ret = TEEC_RegisterSharedMemory(&context, &in_mem); if (ret != TEE_SUCCESS) { printf("Failed to register DATA shared memory\n"); goto end_3; } printf("Registered in mem..\n"); /* Fill operation parameters */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); operation.params[0].memref.parent = &in_mem; /* Invoke command */ printf("Invoking command: Update sha1: "); ret = TEEC_InvokeCommand(&session, HASH_UPDATE, &operation, &return_origin); if (ret != TEEC_SUCCESS) { printf("TEEC_InvokeCommand failed: 0x%x\n", ret); goto end_3; } else { printf("done\n"); } /* register a shared memory region to hold the output of the sha1 operation */ out_mem.buffer = sha1; out_mem.size = SHA1_SIZE; out_mem.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; ret = TEEC_RegisterSharedMemory(&context, &out_mem); if (ret != TEE_SUCCESS) { printf("Failed to allocate SHA1 shared memory\n"); goto end_3; } printf("Registered out mem..\n"); /* * Send some more data to calculate the hash over, this will be added to the origional hash * . This is not strictly needed it is a test for passing 2 memref params in a single * operation */ memset(data, 'Z', DATA_SIZE); /* Fill operation parameters */ operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE); /* * reuse the origional input shared memory, because we have just updated the contents * of the buffer */ operation.params[0].memref.parent = &in_mem; operation.params[1].memref.parent = &out_mem; /* Invoke command */ printf("Invoking command: Do final sha1: "); ret = TEEC_InvokeCommand(&session, HASH_DO_FINAL, &operation, &return_origin); if (ret != TEEC_SUCCESS) { printf("TEEC_InvokeCommand failed: 0x%x\n", ret); goto end_4; } else { printf("done\n"); } /* Printf sha1 buf */ printf("Calculated sha1: "); for (i = 0; i < SHA1_SIZE; i++) printf("%02x", sha1[i]); printf("\n"); /* Cleanup used connection/resources */ end_4: printf("Releasing shared out memory..\n"); TEEC_ReleaseSharedMemory(&out_mem); end_3: printf("Releasing shared in memory..\n"); TEEC_ReleaseSharedMemory(&in_mem); printf("Closing session..\n"); TEEC_CloseSession(&session); end_2: printf("Finalizing ctx..\n"); TEEC_FinalizeContext(&context); end_1: printf("END: example SHA1 calc app\n"); exit(ret); }