1 /** @file
2  * Copyright (c) 2022 Arm Limited or its affiliates. All rights reserved.
3  * SPDX-License-Identifier : Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16 **/
17 
18 #include <psa_adac.h>
19 #include <psa_adac_debug.h>
20 #include <adac_util.h>
21 #include <pal_interfaces.h>
22 #include <string.h>
23 
24 enum {
25     BUFFER_UNINITIALIZED = 0,
26     BUFFER_EMPTY,
27     BUFFER_REQUEST,
28     BUFFER_RESPONSE
29 };
30 static size_t static_buffer_size;
31 static uint8_t *static_buffer_pointer;
32 static uint8_t static_buffer_status = BUFFER_UNINITIALIZED;
33 
static_buffer_msg_init(uint8_t * buffer,size_t size)34 int static_buffer_msg_init(uint8_t *buffer, size_t size)
35 {
36     int ret = -1;
37 
38     if (static_buffer_status == BUFFER_UNINITIALIZED) {
39         static_buffer_size = size;
40         static_buffer_pointer = buffer;
41         static_buffer_status = BUFFER_EMPTY;
42         ret = 0;
43     }
44     return ret;
45 }
46 
static_buffer_msg_release(void)47 int static_buffer_msg_release(void)
48 {
49     int ret = -1;
50 
51     if (static_buffer_status == BUFFER_EMPTY) {
52         static_buffer_size = 0;
53         static_buffer_pointer = NULL;
54         static_buffer_status = BUFFER_UNINITIALIZED;
55         ret = 0;
56     }
57     return ret;
58 }
59 
request_packet_build(uint16_t command,uint8_t * data,size_t data_size)60 request_packet_t *request_packet_build(uint16_t command, uint8_t *data, size_t data_size)
61 {
62     request_packet_t *request = NULL;
63 
64     if ((static_buffer_status == BUFFER_EMPTY) &&
65         (data_size <= (static_buffer_size - sizeof(request_packet_t)))) {
66         request = (request_packet_t *) static_buffer_pointer;
67         request->command = command;
68         request->data_count = data_size / 4UL;
69         (void) memcpy((void *) request->data, (void *) data, data_size);
70         static_buffer_status = BUFFER_REQUEST;
71     }
72     return request;
73 }
74 
request_packet_lock(size_t * max_data_size)75 request_packet_t *request_packet_lock(size_t *max_data_size)
76 {
77     request_packet_t *request = NULL;
78 
79     if (static_buffer_status == BUFFER_EMPTY) {
80         if (max_data_size != NULL)
81             *max_data_size = static_buffer_size - sizeof(response_packet_t);
82 
83         request = (request_packet_t *) static_buffer_pointer;
84         static_buffer_status = BUFFER_REQUEST;
85     }
86     return request;
87 }
88 
request_packet_release(request_packet_t * packet)89 int request_packet_release(request_packet_t *packet)
90 {
91     int ret = -1;
92 
93     if (static_buffer_status == BUFFER_REQUEST) {
94         static_buffer_status = BUFFER_EMPTY;
95         ret = 0;
96     }
97     return ret;
98 }
99 
response_packet_lock(size_t * max_data_size)100 response_packet_t *response_packet_lock(size_t *max_data_size)
101 {
102     response_packet_t *response = NULL;
103 
104     if (static_buffer_status == BUFFER_EMPTY) {
105         if (max_data_size != NULL)
106             *max_data_size = static_buffer_size - sizeof(response_packet_t);
107 
108         response = (response_packet_t *) static_buffer_pointer;
109         static_buffer_status = BUFFER_RESPONSE;
110     }
111     return response;
112 }
113 
response_packet_release(response_packet_t * packet)114 int response_packet_release(response_packet_t *packet)
115 {
116     int ret = -1;
117 
118     if (static_buffer_status == BUFFER_RESPONSE) {
119         static_buffer_status = BUFFER_EMPTY;
120         ret = 0;
121     }
122     return ret;
123 }
124 
msg_interface_init(void * ctx,uint8_t buffer[],size_t buffer_size)125 int msg_interface_init(void *ctx, uint8_t buffer[], size_t buffer_size)
126 {
127     pal_msg_interface_init(ctx);
128     return static_buffer_msg_init(buffer, buffer_size);
129 }
130 
msg_interface_free(void * ctx)131 int msg_interface_free(void *ctx)
132 {
133     pal_msg_interface_free(ctx);
134     return static_buffer_msg_release();
135 }
136 
request_packet_send(request_packet_t * packet)137 int request_packet_send(request_packet_t *packet)
138 {
139     if (packet == NULL)
140         return -1;
141 
142     size_t size = sizeof(request_packet_t) + 4 * packet->data_count;
143 
144     //PSA_ADAC_LOG_DUMP("msg", "send", (uint8_t *) packet, size);
145     return pal_message_send((uint8_t *) packet, size);
146 }
147 
message_receive(uint8_t buffer[],size_t max,size_t * size)148 static int message_receive(uint8_t buffer[], size_t max, size_t *size)
149 {
150     size_t length;
151 
152     length = sizeof(response_packet_t);
153     if (pal_message_receive(buffer, length) != length)
154     {
155         PSA_ADAC_LOG_ERR("transport", "Error receiving message header\n");
156         return -1;
157     }
158     response_packet_t *p = (response_packet_t *) buffer;
159 
160     if (4 + p->data_count * 4 > max)
161     {
162         PSA_ADAC_LOG_ERR("transport", "Message would overflow buffer (%d > %d)\n",
163                                             4 + p->data_count * 4, (int) max);
164         return -1;
165     }
166     if (p->data_count)
167     {
168         length = p->data_count * 4;
169         if (pal_message_receive((uint8_t *) p->data, length) != length)
170         {
171             PSA_ADAC_LOG_ERR("transport", "Error receiving message body\n");
172             return -1;
173         }
174     }
175     //PSA_ADAC_LOG_DUMP("msg", "receive", buffer, sizeof(response_packet_t) + p->data_count * 4);
176     return 0;
177 }
178 
response_packet_receive()179 response_packet_t *response_packet_receive()
180 {
181     size_t max = 0;
182     response_packet_t *r = response_packet_lock(&max);
183 
184     if (r != NULL) {
185         if (message_receive((uint8_t *) r, max, NULL) == 0)
186             return r;
187 
188         PSA_ADAC_LOG_ERR("transport", "Error Receiving Response");
189         response_packet_release(r);
190     } else {
191         PSA_ADAC_LOG_ERR("transport", "Error Locking Response");
192     }
193     return NULL;
194 }
195 
196 // Not used by test. Required for building dependent ADAC crypto libraries
psa_adac_platform_init(void)197 void psa_adac_platform_init(void)
198 {
199     ;
200 }
201 
202