| /* |
| * Copyright (c) 2021 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <psa/crypto.h> |
| #include <stdbool.h> |
| #include <stdint.h> |
| |
| #include "psa/service.h" |
| #include "psa_manifest/tfm_dummy_partition.h" |
| |
| #define NUM_SECRETS 5 |
| |
| struct dp_secret { |
| uint8_t secret[16]; |
| }; |
| |
| struct dp_secret secrets[NUM_SECRETS] = { |
| { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} }, |
| { {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} }, |
| { {2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} }, |
| { {3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} }, |
| { {4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} }, |
| }; |
| |
| typedef void (*psa_write_callback_t)(void *handle, uint8_t *digest, |
| uint32_t digest_size); |
| |
| static psa_status_t tfm_dp_secret_digest(uint32_t secret_index, |
| size_t digest_size, size_t *p_digest_size, |
| psa_write_callback_t callback, void *handle) |
| { |
| uint8_t digest[32]; |
| psa_status_t status; |
| |
| /* Check that secret_index is valid. */ |
| if (secret_index >= NUM_SECRETS) { |
| return PSA_ERROR_INVALID_ARGUMENT; |
| } |
| |
| /* Check that digest_size is valid. */ |
| if (digest_size != sizeof(digest)) { |
| return PSA_ERROR_INVALID_ARGUMENT; |
| } |
| |
| status = psa_hash_compute(PSA_ALG_SHA_256, secrets[secret_index].secret, |
| sizeof(secrets[secret_index].secret), digest, |
| digest_size, p_digest_size); |
| |
| if (status != PSA_SUCCESS) { |
| return status; |
| } |
| if (*p_digest_size != digest_size) { |
| return PSA_ERROR_PROGRAMMER_ERROR; |
| } |
| |
| callback(handle, digest, digest_size); |
| |
| return PSA_SUCCESS; |
| } |
| |
| typedef psa_status_t (*dp_func_t)(psa_msg_t *); |
| |
| static void psa_write_digest(void *handle, uint8_t *digest, |
| uint32_t digest_size) |
| { |
| psa_write((psa_handle_t)handle, 0, digest, digest_size); |
| } |
| |
| static psa_status_t tfm_dp_secret_digest_ipc(psa_msg_t *msg) |
| { |
| size_t num = 0; |
| uint32_t secret_index; |
| |
| if (msg->in_size[0] != sizeof(secret_index)) { |
| /* The size of the argument is incorrect */ |
| return PSA_ERROR_PROGRAMMER_ERROR; |
| } |
| |
| num = psa_read(msg->handle, 0, &secret_index, msg->in_size[0]); |
| if (num != msg->in_size[0]) { |
| return PSA_ERROR_PROGRAMMER_ERROR; |
| } |
| |
| return tfm_dp_secret_digest(secret_index, msg->out_size[0], |
| &msg->out_size[0], psa_write_digest, |
| (void *)msg->handle); |
| } |
| |
| static void dp_signal_handle(psa_signal_t signal, dp_func_t pfn) |
| { |
| psa_status_t status; |
| psa_msg_t msg; |
| |
| status = psa_get(signal, &msg); |
| switch (msg.type) { |
| case PSA_IPC_CONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| case PSA_IPC_CALL: |
| status = pfn(&msg); |
| psa_reply(msg.handle, status); |
| break; |
| case PSA_IPC_DISCONNECT: |
| psa_reply(msg.handle, PSA_SUCCESS); |
| break; |
| default: |
| psa_panic(); |
| } |
| } |
| |
| psa_status_t tfm_dp_req_mngr_init(void) |
| { |
| psa_signal_t signals = 0; |
| |
| while (1) { |
| signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK); |
| if (signals & TFM_DP_SECRET_DIGEST_SIGNAL) { |
| dp_signal_handle(TFM_DP_SECRET_DIGEST_SIGNAL, |
| tfm_dp_secret_digest_ipc); |
| } else { |
| psa_panic(); |
| } |
| } |
| |
| return PSA_ERROR_SERVICE_FAILURE; |
| } |