1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <psa/crypto.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10
11 #include "psa/service.h"
12 #include "psa_manifest/tfm_dummy_partition.h"
13
14 #define NUM_SECRETS 5
15
16 struct dp_secret {
17 uint8_t secret[16];
18 };
19
20 struct dp_secret secrets[NUM_SECRETS] = {
21 { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} },
22 { {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} },
23 { {2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} },
24 { {3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} },
25 { {4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} },
26 };
27
28 typedef void (*psa_write_callback_t)(void *handle, uint8_t *digest,
29 uint32_t digest_size);
30
tfm_dp_secret_digest(uint32_t secret_index,size_t digest_size,size_t * p_digest_size,psa_write_callback_t callback,void * handle)31 static psa_status_t tfm_dp_secret_digest(uint32_t secret_index,
32 size_t digest_size, size_t *p_digest_size,
33 psa_write_callback_t callback, void *handle)
34 {
35 uint8_t digest[32];
36 psa_status_t status;
37
38 /* Check that secret_index is valid. */
39 if (secret_index >= NUM_SECRETS) {
40 return PSA_ERROR_INVALID_ARGUMENT;
41 }
42
43 /* Check that digest_size is valid. */
44 if (digest_size != sizeof(digest)) {
45 return PSA_ERROR_INVALID_ARGUMENT;
46 }
47
48 status = psa_hash_compute(PSA_ALG_SHA_256, secrets[secret_index].secret,
49 sizeof(secrets[secret_index].secret), digest,
50 digest_size, p_digest_size);
51
52 if (status != PSA_SUCCESS) {
53 return status;
54 }
55 if (*p_digest_size != digest_size) {
56 return PSA_ERROR_PROGRAMMER_ERROR;
57 }
58
59 callback(handle, digest, digest_size);
60
61 return PSA_SUCCESS;
62 }
63
64 typedef psa_status_t (*dp_func_t)(psa_msg_t *);
65
psa_write_digest(void * handle,uint8_t * digest,uint32_t digest_size)66 static void psa_write_digest(void *handle, uint8_t *digest,
67 uint32_t digest_size)
68 {
69 psa_write((psa_handle_t)handle, 0, digest, digest_size);
70 }
71
tfm_dp_secret_digest_ipc(psa_msg_t * msg)72 static psa_status_t tfm_dp_secret_digest_ipc(psa_msg_t *msg)
73 {
74 size_t num = 0;
75 uint32_t secret_index;
76
77 if (msg->in_size[0] != sizeof(secret_index)) {
78 /* The size of the argument is incorrect */
79 return PSA_ERROR_PROGRAMMER_ERROR;
80 }
81
82 num = psa_read(msg->handle, 0, &secret_index, msg->in_size[0]);
83 if (num != msg->in_size[0]) {
84 return PSA_ERROR_PROGRAMMER_ERROR;
85 }
86
87 return tfm_dp_secret_digest(secret_index, msg->out_size[0],
88 &msg->out_size[0], psa_write_digest,
89 (void *)msg->handle);
90 }
91
dp_signal_handle(psa_signal_t signal,dp_func_t pfn)92 static void dp_signal_handle(psa_signal_t signal, dp_func_t pfn)
93 {
94 psa_status_t status;
95 psa_msg_t msg;
96
97 status = psa_get(signal, &msg);
98 switch (msg.type) {
99 case PSA_IPC_CONNECT:
100 psa_reply(msg.handle, PSA_SUCCESS);
101 break;
102 case PSA_IPC_CALL:
103 status = pfn(&msg);
104 psa_reply(msg.handle, status);
105 break;
106 case PSA_IPC_DISCONNECT:
107 psa_reply(msg.handle, PSA_SUCCESS);
108 break;
109 default:
110 psa_panic();
111 }
112 }
113
tfm_dp_req_mngr_init(void)114 psa_status_t tfm_dp_req_mngr_init(void)
115 {
116 psa_signal_t signals = 0;
117
118 while (1) {
119 signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
120 if (signals & TFM_DP_SECRET_DIGEST_SIGNAL) {
121 dp_signal_handle(TFM_DP_SECRET_DIGEST_SIGNAL,
122 tfm_dp_secret_digest_ipc);
123 } else {
124 psa_panic();
125 }
126 }
127
128 return PSA_ERROR_SERVICE_FAILURE;
129 }
130