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