blob: 649e9503ab14b664368fd116f4cf48fbf961d92c [file] [log] [blame]
Julian Hall700aa362021-05-13 15:30:39 +01001/*
Julian Hall6e02acf2022-02-22 16:25:03 +00002 * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
Julian Hall700aa362021-05-13 15:30:39 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h>
8#include <string.h>
9#include "iat_client.h"
10#include <common/tlv/tlv.h>
11#include <psa/initial_attestation.h>
Julian Hall99a57e32021-07-28 14:18:50 +010012#include <service/common/client/service_client.h>
Julian Hall700aa362021-05-13 15:30:39 +010013#include <protocols/service/attestation/packed-c/get_token.h>
14#include <protocols/service/attestation/packed-c/get_token_size.h>
15#include <protocols/service/attestation/packed-c/opcodes.h>
16#include <protocols/rpc/common/packed-c/status.h>
17
18/**
19 * @brief The singleton psa_iat_client instance
20 *
Julian Hall99a57e32021-07-28 14:18:50 +010021 * The psa attestation C API assumes a single backend service provider.
Julian Hall700aa362021-05-13 15:30:39 +010022 */
Julian Hall99a57e32021-07-28 14:18:50 +010023static struct service_client instance;
Julian Hall700aa362021-05-13 15:30:39 +010024
25
26psa_status_t psa_iat_client_init(struct rpc_caller *caller)
27{
Julian Hall99a57e32021-07-28 14:18:50 +010028 return service_client_init(&instance, caller);
Julian Hall700aa362021-05-13 15:30:39 +010029}
30
31void psa_iat_client_deinit(void)
32{
Julian Hall99a57e32021-07-28 14:18:50 +010033 service_client_deinit(&instance);
Julian Hall700aa362021-05-13 15:30:39 +010034}
35
36int psa_iat_client_rpc_status(void)
37{
38 return instance.rpc_status;
39}
40
41psa_status_t psa_initial_attest_get_token(
42 const uint8_t *auth_challenge, size_t challenge_size,
43 uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
44{
45 psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
46 size_t req_len = tlv_required_space(challenge_size);
47
Julian Hallb7db5802021-07-26 16:20:40 +010048 if (!token_buf || !token_buf_size) return PSA_ERROR_INVALID_ARGUMENT;
49
Julian Hall700aa362021-05-13 15:30:39 +010050 struct tlv_record challenge_record;
51 challenge_record.tag = TS_ATTESTATION_GET_TOKEN_IN_TAG_AUTH_CHALLENGE;
52 challenge_record.length = challenge_size;
53 challenge_record.value = auth_challenge;
54
55 rpc_call_handle call_handle;
56 uint8_t *req_buf;
57
58 *token_size = 0;
59
60 call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len);
61
62 if (call_handle) {
63
64 uint8_t *resp_buf;
65 size_t resp_len;
Julian Halld1dfda52021-11-25 18:46:45 +010066 rpc_opstatus_t opstatus;
Julian Hall700aa362021-05-13 15:30:39 +010067 struct tlv_iterator req_iter;
68
69 tlv_iterator_begin(&req_iter, req_buf, req_len);
70 tlv_encode(&req_iter, &challenge_record);
71
72 instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
73 TS_ATTESTATION_OPCODE_GET_TOKEN, &opstatus, &resp_buf, &resp_len);
74
75 if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
76
77 psa_status = opstatus;
78
79 if (psa_status == PSA_SUCCESS) {
80
81 struct tlv_const_iterator resp_iter;
82 struct tlv_record decoded_record;
83 tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
84
85 if (tlv_find_decode(&resp_iter,
86 TS_ATTESTATION_GET_TOKEN_OUT_TAG_TOKEN, &decoded_record)) {
87
88 if (decoded_record.length <= token_buf_size) {
89
90 memcpy(token_buf, decoded_record.value, decoded_record.length);
91 *token_size = decoded_record.length;
92 }
93 else {
94 /* Provided buffer is too small */
95 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
96 }
97 }
98 else {
99 /* Mandatory response parameter missing */
100 psa_status = PSA_ERROR_GENERIC_ERROR;
101 }
102 }
103 }
104
105 rpc_caller_end(instance.caller, call_handle);
106 }
107
108 return psa_status;
109}
110
111psa_status_t psa_initial_attest_get_token_size(
112 size_t challenge_size, size_t *token_size)
113{
114 psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
115 struct ts_attestation_get_token_size_in req_msg;
116 size_t req_len = sizeof(struct ts_attestation_get_token_size_in);
117
118 *token_size = 0; /* For failure case */
119
120 req_msg.challenge_size = challenge_size;
121
122 rpc_call_handle call_handle;
123 uint8_t *req_buf;
124
125 call_handle = rpc_caller_begin(instance.caller, &req_buf, req_len);
126
127 if (call_handle) {
128
129 uint8_t *resp_buf;
130 size_t resp_len;
Julian Halld1dfda52021-11-25 18:46:45 +0100131 rpc_opstatus_t opstatus;
Julian Hall700aa362021-05-13 15:30:39 +0100132
133 memcpy(req_buf, &req_msg, req_len);
134
135 instance.rpc_status = rpc_caller_invoke(instance.caller, call_handle,
136 TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE, &opstatus, &resp_buf, &resp_len);
137
138 if (instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
139
140 psa_status = opstatus;
141
142 if (psa_status == PSA_SUCCESS) {
143
144 if (resp_len >= sizeof(struct ts_attestation_get_token_size_out)) {
145
146 struct ts_attestation_get_token_size_out resp_msg;
147 memcpy(&resp_msg, resp_buf, sizeof(struct ts_attestation_get_token_size_out));
148 *token_size = resp_msg.token_size;
149 }
150 else {
151 /* Failed to decode response message */
152 psa_status = PSA_ERROR_GENERIC_ERROR;
153 }
154 }
155 }
156
157 rpc_caller_end(instance.caller, call_handle);
158 }
159
160 return psa_status;
161}