static int file_to_uuid(const char *filename, uuid_t *uuid) { int i; int status = -EINVAL; for (i = 0; i < (sizeof(name_uuid) / sizeof(name_uuid[0])); i++) { if (strcmp(filename, name_uuid[i].name) == 0) { copy_uuid(uuid, &name_uuid[i].uuid); status = 0; break; } } return status; }
static int add_file_info_entry(entry_lookup_list_t *lookup_entry, char *filename) { file_info_t *file_info_entry; int error; struct stat file_status; bool is_new_entry = false; /* Check if the file already exists in the array */ file_info_entry = find_file_info_from_uuid(&lookup_entry->name_uuid); if (file_info_entry == NULL) { /* The file does not exist in the current list; take the next * one available in the file_info list. 'file_info_count' is * incremented in case of successful update at the end of the * function. */ file_info_entry = &files[file_info_count]; is_new_entry = true; /* Copy the uuid for the new entry */ copy_uuid(&file_info_entry->name_uuid, &lookup_entry->name_uuid); } /* Get the file information for entry */ error = stat(filename, &file_status); if (error != 0) { printf("Error: Cannot get information for file \"%s\": %s\n", filename, strerror(errno)); return errno; } file_info_entry->filename = filename; file_info_entry->size = (unsigned int)file_status.st_size; file_info_entry->entry = lookup_entry; /* Increment the file_info counter on success if it is new file entry */ if (is_new_entry) { file_info_count++; /* Ensure we do not overflow */ if (file_info_count > MAX_FILES) { printf("ERROR: Too many files in Package\n"); return 1; } } return 0; }
static int open_tee_device(struct tee_session *ts, struct tee_session *ku_buffer) { int ret; if (ku_buffer->driver_cmd != TEED_OPEN_SESSION) { set_emsg(ts, TEED_ERROR_BAD_STATE, __LINE__); return -EINVAL; } if (ku_buffer->ta) { ret = copy_ta(ts, ku_buffer); } else if (ku_buffer->uuid) { ret = copy_uuid(ts, ku_buffer); } else { set_emsg(ts, TEED_ERROR_COMMUNICATION, __LINE__); return -EINVAL; } ts->id = 0; ts->state = TEED_STATE_OPEN_SESSION; return ret; }
/* Read and load existing package into memory. */ static int parse_fip(const char *fip_filename) { FILE *fip; char *fip_buffer; char *fip_buffer_end; int fip_size, read_fip_size; fip_toc_header_t *toc_header; fip_toc_entry_t *toc_entry; bool found_last_toc_entry = false; file_info_t *file_info_entry; int status = -1; struct stat st; fip = fopen(fip_filename, "r"); if (fip == NULL) { /* If the fip does not exist just return, it should not be * considered as an error. The package will be created later */ status = 0; goto parse_fip_return; } if (stat(fip_filename, &st) != 0) { status = errno; goto parse_fip_fclose; } else { fip_size = (int)st.st_size; } /* Allocate a buffer to read the package */ fip_buffer = (char *)malloc(fip_size); if (fip_buffer == NULL) { printf("ERROR: Cannot allocate %d bytes.\n", fip_size); status = errno; goto parse_fip_fclose; } fip_buffer_end = fip_buffer + fip_size; /* Read the file */ read_fip_size = fread(fip_buffer, sizeof(char), fip_size, fip); if (read_fip_size != fip_size) { printf("ERROR: Cannot read the FIP.\n"); status = EIO; goto parse_fip_free; } fclose(fip); fip = NULL; /* The package must at least contain the ToC Header */ if (fip_size < sizeof(fip_toc_header_t)) { printf("ERROR: Given FIP is smaller than the ToC header.\n"); status = EINVAL; goto parse_fip_free; } /* Set the ToC Header at the base of the buffer */ toc_header = (fip_toc_header_t *)fip_buffer; /* The first toc entry should be just after the ToC header */ toc_entry = (fip_toc_entry_t *)(toc_header + 1); /* While the ToC entry is contained into the buffer */ int cnt = 0; while (((char *)toc_entry + sizeof(fip_toc_entry_t)) < fip_buffer_end) { cnt++; /* Check if the ToC Entry is the last one */ if (compare_uuids(&toc_entry->uuid, &uuid_null) == 0) { found_last_toc_entry = true; status = 0; break; } /* Add the entry into file_info */ /* Get the new entry in the array and clear it */ file_info_entry = &files[file_info_count++]; memset(file_info_entry, 0, sizeof(file_info_t)); /* Copy the info from the ToC entry */ copy_uuid(&file_info_entry->name_uuid, &toc_entry->uuid); file_info_entry->image_buffer = fip_buffer + toc_entry->offset_address; file_info_entry->size = toc_entry->size; /* Check if there is a corresponding entry in lookup table */ file_info_entry->entry = get_entry_lookup_from_uuid(&toc_entry->uuid); /* Go to the next ToC entry */ toc_entry++; } if (!found_last_toc_entry) { printf("ERROR: Given FIP does not have an end ToC entry.\n"); status = EINVAL; goto parse_fip_free; } else { /* All is well, we should not free any of the loaded images */ goto parse_fip_fclose; } parse_fip_free: if (fip_buffer != NULL) { free(fip_buffer); fip_buffer = NULL; } parse_fip_fclose: if (fip != NULL) { fclose(fip); } parse_fip_return: return status; }
/* Create the image package file */ static int pack_images(const char *fip_filename) { int status; uint8_t *fip_base_address; void *entry_address; fip_toc_header_t *toc_header; fip_toc_entry_t *toc_entry; unsigned int entry_index; unsigned int toc_size; unsigned int fip_size; unsigned int entry_offset_address; unsigned int payload_size = 0; /* Validate filename */ if ((fip_filename == NULL) || (strcmp(fip_filename, "") == 0)) { return EINVAL; } /* Payload size calculation */ for (entry_index = 0; entry_index < file_info_count; entry_index++) { payload_size += files[entry_index].size; } /* Allocate memory for entire package, including the final null entry */ toc_size = (sizeof(fip_toc_header_t) + (sizeof(fip_toc_entry_t) * (file_info_count + 1))); fip_size = toc_size + payload_size; fip_base_address = malloc(fip_size); if (fip_base_address == NULL) { printf("Error: Can't allocate enough memory to create package." "Process aborted.\n"); return ENOMEM; } memset(fip_base_address, 0, fip_size); /* Create ToC Header */ toc_header = (fip_toc_header_t *)fip_base_address; toc_header->name = TOC_HEADER_NAME; toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER; toc_header->flags = 0; toc_entry = (fip_toc_entry_t *)(fip_base_address + sizeof(fip_toc_header_t)); /* Calculate the starting address of the first image, right after the * toc header. */ entry_offset_address = toc_size; entry_index = 0; /* Create the package in memory. */ for (entry_index = 0; entry_index < file_info_count; entry_index++) { entry_address = (fip_base_address + entry_offset_address); status = read_file_to_memory(entry_address, &files[entry_index]); if (status != 0) { printf("Error: While reading \"%s\" from filesystem.\n", files[entry_index].filename); return status; } copy_uuid(&toc_entry->uuid, &files[entry_index].name_uuid); toc_entry->offset_address = entry_offset_address; toc_entry->size = files[entry_index].size; toc_entry->flags = 0; entry_offset_address += toc_entry->size; toc_entry++; } /* Add a null uuid entry to mark the end of toc entries */ copy_uuid(&toc_entry->uuid, &uuid_null); toc_entry->offset_address = entry_offset_address; toc_entry->size = 0; toc_entry->flags = 0; /* Save the package to file */ status = write_memory_to_file(fip_base_address, fip_filename, fip_size); if (status != 0) { printf("Error: Failed while writing package to file \"%s\" " "with status=%d.\n", fip_filename, status); return status; } return 0; }