TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
audit_s_interface_testsuite.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
9 #include "psa_audit_api.h"
10 #include "audit_s_tests.h"
11 #include "tfm_api.h"
12 #include "psa_audit_api.h"
13 #include "audit_core.h"
14 
15 #include "../audit_tests_common.h"
16 
22 #define BASE_RETRIEVAL_LOG_INDEX (6)
23 
29 #define FIRST_RETRIEVAL_LOG_INDEX (0)
30 
31 /* List of tests */
32 static void tfm_audit_test_1001(struct test_result_t *ret);
33 
34 static struct test_t audit_veneers_tests[] = {
35  {&tfm_audit_test_1001, "TFM_AUDIT_TEST_1001",
36  "Secure functional", {TEST_PASSED} },
37 };
38 
40 {
41  uint32_t list_size;
42 
43  list_size = (sizeof(audit_veneers_tests) /
44  sizeof(audit_veneers_tests[0]));
45 
46  set_testsuite("Audit Logging secure interface test (TFM_AUDIT_TEST_1XXX)",
47  audit_veneers_tests, list_size, p_test_suite);
48 }
49 
63 static void tfm_audit_test_1001(struct test_result_t *ret)
64 {
65  psa_status_t status;
66  uint8_t local_buffer[LOCAL_BUFFER_SIZE], idx;
67  struct psa_audit_record *record = (struct psa_audit_record *)
68  &local_buffer[0];
69  uint32_t num_records, stored_size, record_size;
70  struct psa_audit_record *retrieved_buffer;
71 
72  /* Fill the log with 36 records, each record is 28 bytes
73  * we end up filling the log without wrapping
74  */
75  for (idx=0; idx<INITIAL_LOGGING_REQUESTS; idx++) {
76  record->size = sizeof(struct psa_audit_record) - 4;
77  record->id = DUMMY_TEST_RECORD_ID_BASE + idx;
78 
79  /* The record doesn't contain any payload */
80  status = psa_audit_add_record(record);
81  if (status != PSA_SUCCESS) {
82  TEST_FAIL("Record addition has returned an error");
83  return;
84  }
85  }
86 
87  /* Get the log size */
88  status = psa_audit_get_info(&num_records, &stored_size);
89  if (status != PSA_SUCCESS) {
90  TEST_FAIL("Getting log info has returned error");
91  return;
92  }
93 
94  if (stored_size != INITIAL_LOGGING_SIZE) {
95  TEST_FAIL("Expected log size is " STR(INITIAL_LOGGING_SIZE));
96  return;
97  }
98 
99  if (num_records != INITIAL_LOGGING_REQUESTS) {
100  TEST_FAIL("Expected log records are " STR(INITIAL_LOGGING_REQUESTS));
101  return;
102  }
103 
104  /* Retrieve two log records starting from a given index */
105  for (idx=BASE_RETRIEVAL_LOG_INDEX; idx<BASE_RETRIEVAL_LOG_INDEX+2; idx++) {
106  uint8_t *p_buf =
108 
109  status = psa_audit_retrieve_record(idx,
111  NULL,
112  0,
113  p_buf,
114  &record_size);
115 
116  if (status != PSA_SUCCESS) {
117  TEST_FAIL("Retrieve indexes 6 or 7 has returned an error");
118  return;
119  }
120 
121  if (record_size != STANDARD_LOG_ENTRY_SIZE) {
122  TEST_FAIL("Expected log size is " STR(STANDARD_LOG_ENTRY_SIZE));
123  return;
124  }
125  }
126 
127  /* Inspect the content of the second log record retrieved */
128  retrieved_buffer = (struct psa_audit_record *)
129  &local_buffer[offsetof(struct log_hdr,size)+STANDARD_LOG_ENTRY_SIZE];
130 
131  if (retrieved_buffer->id != ( DUMMY_TEST_RECORD_ID_BASE +
132  (BASE_RETRIEVAL_LOG_INDEX+1) )) {
133  TEST_FAIL("Unexpected argument in the index 7 entry");
134  return;
135  }
136 
137  /* Retrieve the last two log records */
138  for (idx=num_records-2; idx<num_records; idx++) {
139  uint8_t *p_buf =
140  &local_buffer[(idx-(num_records-2))*STANDARD_LOG_ENTRY_SIZE];
141 
142  status = psa_audit_retrieve_record(idx,
144  NULL,
145  0,
146  p_buf,
147  &record_size);
148 
149  if (status != PSA_SUCCESS) {
150  TEST_FAIL("Retrieve of last two log records has returned error");
151  return;
152  }
153 
154  if (record_size != STANDARD_LOG_ENTRY_SIZE) {
155  TEST_FAIL("Expected log size is " STR(STANDARD_LOG_ENTRY_SIZE));
156  return;
157  }
158  }
159 
160  /* Inspect the first record retrieved in the local buffer */
161  retrieved_buffer = (struct psa_audit_record *)
162  &local_buffer[offsetof(struct log_hdr,size)];
163 
164  if (retrieved_buffer->id != ( DUMMY_TEST_RECORD_ID_BASE +
165  (INITIAL_LOGGING_REQUESTS-2) )) {
166  TEST_FAIL("Unexpected argument in the second last entry");
167  return;
168  }
169 
170  /* Retrieve the first log item */
171  status = psa_audit_retrieve_record(0,
173  NULL,
174  0,
175  &local_buffer[0],
176  &record_size);
177 
178  if (status != PSA_SUCCESS) {
179  TEST_FAIL("Retrieve of the first log entry has returned error");
180  return;
181  }
182 
183  if (record_size != STANDARD_LOG_ENTRY_SIZE) {
184  TEST_FAIL("Expected log size is " STR(STANDARD_LOG_ENTRY_SIZE));
185  return;
186  }
187 
188  if (retrieved_buffer->id != DUMMY_TEST_RECORD_ID_BASE) {
189  TEST_FAIL("Unexpected argument in the first entry");
190  return;
191  }
192 
193  status = psa_audit_retrieve_record(num_records - 1,
195  NULL,
196  0,
197  &local_buffer[0],
198  &record_size);
199 
200  if (status != PSA_SUCCESS) {
201  TEST_FAIL("Retrieve of last two log entries has returned error");
202  return;
203  }
204 
205  if (record_size != STANDARD_LOG_ENTRY_SIZE) {
206  TEST_FAIL("Expected log size is " STR(STANDARD_LOG_ENTRY_SIZE));
207  return;
208  }
209 
210  /* Inspect the item just retrieved */
211  if (retrieved_buffer->id != ( DUMMY_TEST_RECORD_ID_BASE +
212  (INITIAL_LOGGING_REQUESTS-1) )) {
213  TEST_FAIL("Unexpected argument in the second last entry");
214  return;
215  }
216 
217  /* Fill one more log record, this will wrap */
218  record->size = sizeof(struct psa_audit_record) - 4;
220 
221  /* The addition of this new log item will wrap the log ending */
222  status = psa_audit_add_record(record);
223  if (status != PSA_SUCCESS) {
224  TEST_FAIL("Record addition has returned an error");
225  return;
226  }
227 
228  /* Get the log size */
229  status = psa_audit_get_info(&num_records, &stored_size);
230  if (status != PSA_SUCCESS) {
231  TEST_FAIL("Getting log info has returned error");
232  return;
233  }
234 
235  /* Check that the log state is the same, the item addition just performed
236  * is resulted into the removal of the oldest entry, so log size and number
237  * of log records is still the same as before
238  */
239  if (stored_size != INITIAL_LOGGING_SIZE) {
240  TEST_FAIL("Expected log size is " STR(INITIAL_LOGGING_SIZE));
241  return;
242  }
243 
244  if (num_records != INITIAL_LOGGING_REQUESTS) {
245  TEST_FAIL("Expected log records are " STR(INITIAL_LOGGING_REQUESTS));
246  return;
247  }
248 
249  /* Retrieve the last two log records */
250  for (idx=num_records-2; idx<num_records; idx++) {
251  uint8_t *p_buf =
252  &local_buffer[(idx-(num_records-2))*STANDARD_LOG_ENTRY_SIZE];
253 
254  /* Retrieve the last two items */
255  status = psa_audit_retrieve_record(idx,
257  NULL,
258  0,
259  p_buf,
260  &record_size);
261 
262  if (status != PSA_SUCCESS) {
263  TEST_FAIL("Retrieve of last two log records has returned error");
264  return;
265  }
266 
267  if (record_size != STANDARD_LOG_ENTRY_SIZE) {
268  TEST_FAIL("Expected record size is " STR(STANDARD_LOG_ENTRY_SIZE));
269  return;
270  }
271  }
272 
273  /* Inspect the first record retrieved */
274  if (retrieved_buffer->id != ( DUMMY_TEST_RECORD_ID_BASE +
275  (INITIAL_LOGGING_REQUESTS-1) )) {
276  TEST_FAIL("Unexpected argument in the second last entry");
277  return;
278  }
279 
280  /* Inspect the second record retrieved in the local buffer */
281  retrieved_buffer = (struct psa_audit_record *)
282  &local_buffer[offsetof(struct log_hdr,size)+STANDARD_LOG_ENTRY_SIZE];
283 
284  if (retrieved_buffer->id != ( DUMMY_TEST_RECORD_ID_BASE +
285  (INITIAL_LOGGING_REQUESTS) )) {
286  TEST_FAIL("Unexpected argument in the last entry");
287  return;
288  }
289 
290  /* Fill now one big record that will invalidate all existing records */
291  record->size = MAX_LOG_RECORD_SIZE;
292  record->id = DUMMY_TEST_RECORD_ID_BASE + INITIAL_LOGGING_REQUESTS + 1;
293 
294  /* The record has maximum possible payload for log size of 1024 */
295  status = psa_audit_add_record(record);
296  if (status != PSA_SUCCESS) {
297  TEST_FAIL("Record addition has returned an error");
298  return;
299  }
300 
301  /* Get the log size */
302  status = psa_audit_get_info(&num_records, &stored_size);
303  if (status != PSA_SUCCESS) {
304  TEST_FAIL("Getting log info has returned error");
305  return;
306  }
307 
308  /* Check that the log state has one element with maximum size */
309  if (stored_size != MAX_LOG_SIZE) {
310  TEST_FAIL("Expected log size is " STR(MAX_LOG_SIZE));
311  return;
312  }
313 
314  if (num_records != 1) {
315  TEST_FAIL("Expected log records are 1");
316  return;
317  }
318 
319  /* Try to retrieve the maximum possible size that fits our buffer.
320  * As there is just one big record filling the whole space, nothing
321  * will be returned and the API will fail
322  */
323  status = psa_audit_retrieve_record(0,
325  NULL,
326  0,
327  &local_buffer[0],
328  &record_size);
329 
330  if (status == PSA_SUCCESS) {
331  TEST_FAIL("Retrieve of index 0 should fail as it's too big");
332  return;
333  }
334 
335  if (record_size != 0) {
336  TEST_FAIL("Retrieved log size has unexpected size instead of 0");
337  return;
338  }
339 
340  /* Add two standard length records again */
341  for (idx=0; idx<2; idx++) {
342  record->size = sizeof(struct psa_audit_record) - 4;
343  record->id = DUMMY_TEST_RECORD_ID_BASE +
344  INITIAL_LOGGING_REQUESTS + 2 + idx;
345 
346  /* The record doesn't contain any payload */
347  status = psa_audit_add_record(record);
348  if (status != PSA_SUCCESS) {
349  TEST_FAIL("Record addition has returned an error");
350  return;
351  }
352  }
353 
354  /* Get the log size */
355  status = psa_audit_get_info(&num_records, &stored_size);
356  if (status != PSA_SUCCESS) {
357  TEST_FAIL("Getting log info has returned error");
358  return;
359  }
360 
361  /* As the log was full, the addition of the last two log records results
362  * in the resetting of the log completely. The log will contain only
363  * the last two items we have just added.
364  */
365  if (stored_size != FINAL_LOGGING_SIZE) {
366  TEST_FAIL("Expected log size is " STR(FINAL_LOGGING_SIZE));
367  return;
368  }
369 
370  if (num_records != FINAL_LOGGING_REQUESTS) {
371  TEST_FAIL("Expected log records are " STR(FINAL_LOGGING_REQUESTS));
372  return;
373  }
374 
375  /* Check the length of each record individually */
376  for (idx=0; idx<num_records; idx++) {
377  status = psa_audit_get_record_info(idx, &stored_size);
378  if (status != PSA_SUCCESS) {
379  TEST_FAIL("Getting record size individually has returned error");
380  return;
381  }
382 
383  if (stored_size != STANDARD_LOG_ENTRY_SIZE) {
384  TEST_FAIL("Unexpected log record size for a single standard item");
385  return;
386  }
387  }
388 
389  /* Check that if requesting length of a record which is not there fails */
390  status = psa_audit_get_record_info(num_records, &stored_size);
391  if (status == PSA_SUCCESS) {
392  TEST_FAIL("Getting record size for non-existent record has not failed");
393  return;
394  }
395 
396  ret->val = TEST_PASSED;
397 }
#define STANDARD_LOG_ENTRY_SIZE
A log item with no payload (standard size) has the following size. More details can be found observin...
#define PSA_SUCCESS
Definition: crypto_values.h:35
#define MAX_LOG_SIZE
The maximum possible log size in the current implementation.
#define STR(a)
A standard stringify macro.
#define TEST_FAIL(info_msg)
#define DUMMY_TEST_RECORD_ID_BASE
The log record is initialized with a dummy ID which uses this value as base value.
psa_status_t psa_audit_get_record_info(const uint32_t record_index, uint32_t *size)
Returns the size of the record at the specified index.
enum test_suite_err_t set_testsuite(const char *name, struct test_t *test_list, uint32_t size, struct test_suite_t *p_ts)
Sets test suite parameters.
psa_status_t psa_audit_add_record(const struct psa_audit_record *record)
Adds a record.
Fixed size header for a log record.
Definition: audit_core.h:99
This structure contains the record that is added to the audit log by the requesting secure service...
#define BASE_RETRIEVAL_LOG_INDEX
Base index from where to start elements retrieval.
#define MAX_LOG_RECORD_SIZE
The maximum possible log line size to fill a MAX_LOG_SIZE bytes log.
#define FINAL_LOGGING_SIZE
Size of the final consecutive logging requests.
struct test_result_t ret
#define FINAL_LOGGING_REQUESTS
Number of final consecutive logging requests to perform.
#define INITIAL_LOGGING_REQUESTS
Number of initial consecutive logging requests to perform.
#define INITIAL_LOGGING_SIZE
Size of the initial consecutive logging requests.
enum test_status_t val
#define LOCAL_BUFFER_SIZE
Size in bytes of the local buffer. Size accomodates two standard size (no payload) log items...
void register_testsuite_s_audit_interface(struct test_suite_t *p_test_suite)
Register testsuite for audit logging secure interface.
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
psa_status_t psa_audit_get_info(uint32_t *num_records, uint32_t *size)
Returns the total number and size of the records stored.
psa_status_t psa_audit_retrieve_record(const uint32_t record_index, const uint32_t buffer_size, const uint8_t *token, const uint32_t token_size, uint8_t *buffer, uint32_t *record_size)
Retrieves a record at the specified index.