static psa_status_t storage_info(psa_msg_t *msg) { struct psa_storage_info_t info = { 0 }; psa_storage_uid_t key = 0; if ((msg->in_size[0] != sizeof(key)) || (msg->out_size[0] != sizeof(info))) { return PSA_DROP_CONNECTION; } if (psa_read(msg->handle, 0, &key, sizeof(key)) != sizeof(key)) { return PSA_DROP_CONNECTION; } #if defined(TARGET_MBED_SPM) psa_status_t status = psa_its_get_info_impl(psa_identity(msg->handle), key, &info); #else psa_status_t status = psa_its_get_info_impl(msg->client_id, key, &info); #endif if (status == PSA_SUCCESS) { psa_write(msg->handle, 0, &info, msg->out_size[0]); } return status; }
static psa_status_t storage_remove(psa_msg_t *msg) { psa_storage_uid_t key = 0; if (msg->in_size[0] != sizeof(key)) { return PSA_DROP_CONNECTION; } if (psa_read(msg->handle, 0, &key, sizeof(key)) != sizeof(key)) { return PSA_DROP_CONNECTION; } #if defined(TARGET_MBED_SPM) return psa_its_remove_impl(psa_identity(msg->handle), key); #else return psa_its_remove_impl(msg->client_id, key); #endif }
static psa_status_t storage_set(psa_msg_t *msg) { psa_storage_uid_t key = 0; void *data = NULL; uint32_t alloc_size = msg->in_size[1]; psa_storage_create_flags_t flags = 0; if ((msg->in_size[0] != sizeof(key)) || (msg->in_size[2] != sizeof(flags))) { return PSA_DROP_CONNECTION; } if (psa_read(msg->handle, 0, &key, sizeof(key)) != sizeof(key)) { return PSA_DROP_CONNECTION; } if (psa_read(msg->handle, 2, &flags, sizeof(flags)) != sizeof(flags)) { return PSA_DROP_CONNECTION; } data = malloc(alloc_size); if (data == NULL) { return PSA_ERROR_STORAGE_FAILURE; } if (psa_read(msg->handle, 1, data, msg->in_size[1]) != msg->in_size[1]) { free(data); return PSA_ERROR_STORAGE_FAILURE; } #if defined(TARGET_MBED_SPM) psa_status_t status = psa_its_set_impl(psa_identity(msg->handle), key, alloc_size, data, flags); #else psa_status_t status = psa_its_set_impl(msg->client_id, key, alloc_size, data, flags); #endif memset(data, 0, alloc_size); free(data); return status; }
static psa_status_t storage_get(psa_msg_t *msg) { psa_storage_uid_t key = 0; uint32_t offset = 0; if ((msg->in_size[0] != sizeof(key)) || (msg->in_size[1] != sizeof(offset))) { return PSA_DROP_CONNECTION; } if (psa_read(msg->handle, 0, &key, sizeof(key)) != sizeof(key)) { return PSA_DROP_CONNECTION; } if (psa_read(msg->handle, 1, &offset, sizeof(offset)) != sizeof(offset)) { return PSA_DROP_CONNECTION; } uint8_t *data = (uint8_t *)malloc(msg->out_size[0]); if (data == NULL) { return PSA_ERROR_STORAGE_FAILURE; } #if defined(TARGET_MBED_SPM) psa_status_t status = psa_its_get_impl(psa_identity(msg->handle), key, offset, msg->out_size[0], data); #else psa_status_t status = psa_its_get_impl(msg->client_id, key, offset, msg->out_size[0], data); #endif if (status == PSA_SUCCESS) { psa_write(msg->handle, 0, data, msg->out_size[0]); } memset(data, 0, msg->out_size[0]); free(data); return status; }
void part2_main(void *ptr) { uint32_t signals = 0; size_t len = 0; char *str = NULL; while (1) { signals = psa_wait_any(PSA_BLOCK); if (0 == (signals & (ROT_SRV_REVERSE_MSK | ROT_SRV_DB_TST_MSK))) { SPM_PANIC("returned from psa_wait_any without ROT_SRV_REVERSE_MSK or ROT_SRV_DB_TST_MSK bit on\n"); } if (signals & ROT_SRV_REVERSE_MSK) { psa_get(ROT_SRV_REVERSE_MSK, &msg); switch (msg.type) { case PSA_IPC_CALL: { if ((msg.in_size[0] + msg.in_size[1] + msg.in_size[2]) == 0) { SPM_PANIC("got a zero message size to REVERSE ROT_SRV\n"); } len = msg.in_size[0]; str = (char *)malloc(sizeof(char) * len); if (NULL == str) { SPM_PANIC("memory allocation failure\n"); } psa_read(msg.handle, 0, str, len); for (size_t i = 0; i < len / 2; i ++) { char a = str[i]; str[i] = str[len - i - 1]; str[len - i - 1] = a; } psa_write(msg.handle, 0, str, len); free(str); str = NULL; break; } case PSA_IPC_CONNECT: case PSA_IPC_DISCONNECT: break; default: SPM_PANIC("Unexpected message type %d!", (int)(msg.type)); break; } psa_reply(msg.handle, PSA_SUCCESS); } else { // -- Doorbell test psa_get(ROT_SRV_DB_TST_MSK, &msg); switch (msg.type) { case PSA_IPC_CALL: { int32_t caller_part_id = psa_identity(msg.handle); // Doorbell contract is valid only between secure partitions if (PSA_NSPE_IDENTIFIER == caller_part_id) { SPM_PANIC("Caller partition is non secure\n"); } // In doorbell scenario the server first calls psa_reply() psa_reply(msg.handle, PSA_SUCCESS); // Then the servers waits to some driver making long calculations - imitate using osDelay() osDelay(20); // After work is done, ring the doorbell psa_notify(caller_part_id); break; } case PSA_IPC_CONNECT: case PSA_IPC_DISCONNECT: psa_reply(msg.handle, PSA_SUCCESS); break; default: SPM_PANIC("Unexpected message type %d!", (int)(msg.type)); break; } } } }