1 /*
2 * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <string.h>
9
10 #include "psa/error.h"
11 #include "psa/client.h"
12 #include "psa/initial_attestation.h"
13 #include "psa/crypto.h"
14 #include "attest.h"
15
16 #include "array.h"
17 #include "psa/framework_feature.h"
18 #include "psa/service.h"
19 #include "psa_manifest/tfm_initial_attestation.h"
20 #include "tfm_attest_defs.h"
21
22 #define ECC_P256_PUBLIC_KEY_SIZE PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)
23
24 typedef psa_status_t (*attest_func_t)(const psa_msg_t *msg);
25
26 int32_t g_attest_caller_id;
27
28 #if PSA_FRAMEWORK_HAS_MM_IOVEC == 1
psa_attest_get_token(const psa_msg_t * msg)29 static psa_status_t psa_attest_get_token(const psa_msg_t *msg)
30 {
31 psa_status_t status;
32 const void *challenge_buff;
33 void *token_buff;
34 size_t challenge_size;
35 size_t token_buff_size;
36 size_t token_size;
37
38 token_buff_size = msg->out_size[0];
39 challenge_size = msg->in_size[0];
40
41 if (challenge_size > PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64
42 || challenge_size == 0 || token_buff_size == 0) {
43 return PSA_ERROR_INVALID_ARGUMENT;
44 }
45
46 /* store the client ID here for later use in service */
47 g_attest_caller_id = msg->client_id;
48
49 challenge_buff = psa_map_invec(msg->handle, 0);
50 token_buff = psa_map_outvec(msg->handle, 0);
51
52 status = initial_attest_get_token(challenge_buff, challenge_size,
53 token_buff, token_buff_size, &token_size);
54 if (status == PSA_SUCCESS) {
55 psa_unmap_outvec(msg->handle, 0, token_size);
56 }
57
58 return status;
59 }
60 #else /* PSA_FRAMEWORK_HAS_MM_IOVEC == 1 */
61 /* Buffer to store the created attestation token. */
62 static uint8_t token_buff[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE];
63
psa_attest_get_token(const psa_msg_t * msg)64 static psa_status_t psa_attest_get_token(const psa_msg_t *msg)
65 {
66 psa_status_t status = PSA_SUCCESS;
67 uint8_t challenge_buff[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
68 uint32_t bytes_read = 0;
69 size_t challenge_size;
70 size_t token_buff_size;
71 size_t token_size;
72
73 challenge_size = msg->in_size[0];
74 token_buff_size = msg->out_size[0] < sizeof(token_buff) ?
75 msg->out_size[0] : sizeof(token_buff);
76
77 if (challenge_size > PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64
78 || challenge_size == 0 || token_buff_size == 0) {
79 return PSA_ERROR_INVALID_ARGUMENT;
80 }
81
82 /* store the client ID here for later use in service */
83 g_attest_caller_id = msg->client_id;
84
85 bytes_read = psa_read(msg->handle, 0, challenge_buff, challenge_size);
86 if (bytes_read != challenge_size) {
87 return PSA_ERROR_GENERIC_ERROR;
88 }
89
90 status = initial_attest_get_token(challenge_buff, challenge_size,
91 token_buff, token_buff_size, &token_size);
92 if (status == PSA_SUCCESS) {
93 psa_write(msg->handle, 0, token_buff, token_size);
94 }
95
96 return status;
97 }
98 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC == 1 */
99
psa_attest_get_token_size(const psa_msg_t * msg)100 static psa_status_t psa_attest_get_token_size(const psa_msg_t *msg)
101 {
102 psa_status_t status = PSA_SUCCESS;
103 size_t challenge_size;
104 size_t token_size;
105 size_t bytes_read = 0;
106
107 if (msg->in_size[0] != sizeof(challenge_size)
108 || msg->out_size[0] != sizeof(token_size)) {
109 return PSA_ERROR_INVALID_ARGUMENT;
110 }
111
112 /* store the client ID here for later use in service */
113 g_attest_caller_id = msg->client_id;
114
115 bytes_read = psa_read(msg->handle, 0,
116 &challenge_size, msg->in_size[0]);
117 if (bytes_read != sizeof(challenge_size)) {
118 return PSA_ERROR_INVALID_ARGUMENT;
119 }
120
121 status = initial_attest_get_token_size(challenge_size, &token_size);
122 if (status == PSA_SUCCESS) {
123 psa_write(msg->handle, 0, &token_size, sizeof(token_size));
124 }
125
126 return status;
127 }
128
tfm_attestation_service_sfn(const psa_msg_t * msg)129 psa_status_t tfm_attestation_service_sfn(const psa_msg_t *msg)
130 {
131 switch (msg->type) {
132 case TFM_ATTEST_GET_TOKEN:
133 return psa_attest_get_token(msg);
134 case TFM_ATTEST_GET_TOKEN_SIZE:
135 return psa_attest_get_token_size(msg);
136 default:
137 return PSA_ERROR_NOT_SUPPORTED;
138 }
139
140 return PSA_ERROR_GENERIC_ERROR;
141 }
142
attest_partition_init(void)143 psa_status_t attest_partition_init(void)
144 {
145 return attest_init();
146 }
147