static uint32_t load_ta(size_t num_params, struct tee_ioctl_param *params) { int ta_found = 0; size_t size = 0; TEEC_UUID uuid; struct tee_ioctl_param_value *val_cmd; TEEC_SharedMemory shm_ta; memset(&shm_ta, 0, sizeof(shm_ta)); if (num_params != 2 || get_value(num_params, params, 0, &val_cmd) || get_param(num_params, params, 1, &shm_ta)) return TEEC_ERROR_BAD_PARAMETERS; uuid_from_octets(&uuid, (void *)val_cmd); size = shm_ta.size; ta_found = TEECI_LoadSecureModule(ta_dir, &uuid, shm_ta.buffer, &size); if (ta_found != TA_BINARY_FOUND) { EMSG(" TA not found"); return TEEC_ERROR_ITEM_NOT_FOUND; } params[1].u.memref.size = size; /* * If a buffer wasn't provided, just tell which size it should be. * If it was provided but isn't big enough, report an error. */ if (shm_ta.buffer && size > shm_ta.size) return TEEC_ERROR_SHORT_BUFFER; return TEEC_SUCCESS; }
/* * This function opens a new Session between the Client application and the * specified TEE application. * * Only connection_method == TEEC_LOGIN_PUBLIC is supported connection_data and * operation shall be set to NULL. */ TEEC_Result TEEC_OpenSession(TEEC_Context *context, TEEC_Session *session, const TEEC_UUID *destination, uint32_t connection_method, const void *connection_data, TEEC_Operation *operation, uint32_t *error_origin) { TEEC_Operation dummy_op; size_t ta_size = 0; struct tee_cmd tc; uint32_t origin = TEEC_ORIGIN_API; TEEC_Result res = TEEC_SUCCESS; void *ta = NULL; (void)connection_data; if (session != NULL) session->fd = -1; if ((context == NULL) || (session == NULL)) { res = TEEC_ERROR_BAD_PARAMETERS; goto error; } /* Check that context->fd is a valid file descriptor */ session->fd = dup(context->fd); if (session->fd == -1) { res = TEEC_ERROR_BAD_PARAMETERS; goto error; } close(session->fd); session->fd = -1; if (connection_method != TEEC_LOGIN_PUBLIC) { res = TEEC_ERROR_NOT_SUPPORTED; goto error; } memset(&tc, 0, sizeof(struct tee_cmd)); /* * Save the fd in the session for later use when invoke command and * close the session. */ session->fd = open(context->devname, O_RDWR); if (session->fd == -1) { res = TEEC_ERROR_BAD_PARAMETERS; goto error; } /* * Check if the TA binary is found on the filesystem. * If no, assume it is a static TA. */ if (TEECI_LoadSecureModule (get_tee_target(context), destination, &ta, &ta_size) == TA_BINARY_FOUND) { tc.uuid = (TEEC_UUID *)destination; tc.data = ta; tc.data_size = ta_size; } else { tc.uuid = (TEEC_UUID *)destination; tc.data = NULL; tc.data_size = 0; } if (operation == NULL) { /* * The code here exist because Global Platform API states that * it is allowed to give operation as a NULL pointer. In kernel * and secure world we in most cases don't want this to be NULL, * hence we use this dummy operation when a client doesn't * provide any operation. */ memset(&dummy_op, 0, sizeof(TEEC_Operation)); operation = &dummy_op; } tc.op = operation; if (ioctl(session->fd, TEE_OPEN_SESSION_IOC, &tc) != 0) { EMSG("Ioctl(TEE_OPEN_SESSION_IOC) failed! (%s)\n", strerror(errno)); origin = TEEC_ORIGIN_COMMS; res = TEEC_ERROR_COMMUNICATION; goto error; } if (tc.err != 0) { EMSG("UUID %x %x %x can't be loaded !!!\n", destination->timeLow, destination->timeMid, destination->timeHiAndVersion); } origin = tc.origin; res = tc.err; error: /* * We do this check at the end instead of checking on every place where * we set the error origin. */ if (res != TEEC_SUCCESS) { if (session != NULL && session->fd != -1) { close(session->fd); session->fd = -1; } } if (error_origin != NULL) *error_origin = origin; if (ta) free(ta); return res; }