| /* |
| * Copyright (c) 2019-2020, Arm Limited. All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| * |
| */ |
| |
| This file is a library text file of boilerplate-text snippets. TF-Fuzz reads in these |
| snippets and then performs targeted text substitutions upon them, to create the indi- |
| vidual PSA commands, and other important code snippets. This one in particular |
| library-text file is what might be called the "personality module" for writing tests |
| with TF-M syntax. |
| |
| Four extremely important things about this file: |
| * The individual text snippets are separated by "backtick" (AKA back-apostrophe) |
| characters (see below). This means that text snippets of TF code can't use backtick |
| characters (reasonably safe for C code). |
| * The text snippets are *positional*. The loop in boilerplate.cpp reads them in, in |
| the order they appear in this file, into a vector of strings. The "const int"s in |
| boilerplate.hpp assign symbolic names to the vector indices. It is therefore |
| *critical* that the, for example, 11th backtick-delineated text snippet in this file, |
| be read into the 11 string in this vector of strings! |
| * This first text snippet that you're now reading -- a README about this file -- is |
| ignored by this boilerplate.cpp loop; it is not read into this vector of snippets. |
| * To make it easier to track the positional nature of the text snippets in this file, |
| the first three characters, plus the leading \n, of these snippets is trimmed off |
| and ignored. These first three characters in each string comprise a sequence |
| number, for checking against the "const int" list in boilerplate.hpp. So, these |
| tags are literally the exactly the 3 characters directly after the backtick termi- |
| nating the previous string. |
| `000 |
| /* |
| * Test purpose: |
| * $purpose |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <time.h> |
| #include <string.h> |
| #include <stdint.h> |
| |
| #include "psa/protected_storage.h" |
| #include "psa/crypto.h" |
| #include "test_framework.h" |
| `001 |
| |
| static uint32_t shift_reg = 0x55555555; |
| static int i; /* generic counter variable */ |
| |
| static void seed_hasher (void) |
| { |
| shift_reg = 0x55555555; |
| } |
| |
| static uint32_t lfsr_1b (uint32_t a_bit) |
| { |
| int odd; |
| uint32_t polynomial = 0xb4bcd35c; |
| |
| odd = ((shift_reg ^ a_bit) & 1) == 1; |
| shift_reg >>= 1; |
| if (odd == 1) { |
| shift_reg ^= polynomial; |
| } |
| if (shift_reg == 0) { |
| /* Should never happen, but... */ |
| seed_hasher(); |
| } |
| return shift_reg; |
| } |
| |
| static uint32_t crc_byte (uint8_t a_byte) |
| { |
| int i; |
| for (i = 0; i < 8; i++) { |
| lfsr_1b ((uint32_t) a_byte); |
| a_byte >>= 1; |
| } |
| return shift_reg; |
| } |
| |
| `002 |
| |
| /* This is not yet right for how to run a test; need to register tests, etc. */ |
| |
| void test_thread (struct test_result_t *ret) { |
| psa_status_t crypto_status; /* result from Crypto calls */ |
| psa_status_t sst_status; |
| `003 |
| (void)sst_status; |
| /* "void" to prevent unused-variable warning, since the variable may not |
| * be used in this particular test case. |
| */ |
| |
| crypto_status = psa_crypto_init(); |
| if (crypto_status != PSA_SUCCESS) { |
| TEST_FAIL("Could not initialize Crypto."); |
| return; |
| } |
| |
| TEST_LOG("Test $purpose"); |
| `004 |
| static int $var = $init; |
| `005 |
| static uint8_t $var[] = "$init"; |
| `006 |
| static uint8_t $var[2048] = "$init"; |
| `007 |
| static size_t $var = $init; |
| `008 |
| static psa_key_attributes_t $var; |
| `009 |
| static psa_algorithm_t $var; |
| `010 |
| static psa_key_lifetime_t $var; |
| `011 |
| static psa_key_type_t $var; |
| `012 |
| static psa_key_usage_t $var; |
| `013 |
| static psa_key_handle_t $var; |
| `014 |
| $type $var = $init; |
| `015 |
| TEST_LOG("$message"); |
| `016 |
| psa_ps_remove($uid); |
| `017 |
| if (sst_status != PSA_SUCCESS) { |
| TEST_FAIL("Failed to tear down an SST asset upon test completion."); |
| return; |
| } |
| `018 |
| psa_destroy_key($handle); |
| `019 |
| if (crypto_status != PSA_SUCCESS) { |
| TEST_FAIL("Failed to tear down a crypto asset upon test completion"); |
| return; |
| } |
| `020 |
| |
| /* Test completed */ |
| ret->val = TEST_PASSED; |
| } |
| `021 PSA_SUCCESS`022 PSA_ERROR_DOES_NOT_EXIST`023 |
| /* $op SST asset $description with data $data_source. */ |
| sst_status = psa_ps_set($uid, $length, $data, |
| $flags); |
| `024 |
| if (sst_status != $expect) { |
| TEST_FAIL("psa_ps_set() expected $expect."); |
| return; |
| } |
| `025 |
| sst_status = psa_ps_get($uid, $offset, $length, $act_data, |
| &$act_length); |
| `026 |
| if (sst_status != $expect) { |
| TEST_FAIL("psa_ps_get() expected $expect."); |
| return; |
| } |
| `027 |
| if (sst_status != $expect) { |
| TEST_FAIL("psa_ps_get() expected $expect."); |
| return; |
| } |
| /* Check that the data is correct */ |
| if (memcmp($act_data, $exp_data, |
| $length) != 0) { |
| TEST_FAIL("Read data should be equal to result data"); |
| return; |
| } |
| `028 |
| /* Hash the actual data for later data-leak checking: */ |
| seed_hasher(); |
| for (i = 0; i < strlen((char *) $act_data_var); ++i) { |
| crc_byte ($act_data_var[i]); |
| } |
| /* $hash_var = shift_reg; */ |
| `029 |
| sst_status = psa_ps_remove($uid); |
| `030 |
| if (sst_status != $expect) { |
| TEST_FAIL("psa_ps_remove() expected $expect."); |
| return; |
| } |
| `031 |
| $policy = psa_key_attributes_init(); |
| `032 |
| psa_reset_key_attributes (&$policy); |
| `033 |
| psa_set_key_usage_flags ( |
| &$policy, |
| psa_get_key_usage_flags (&$policy) |
| | $flag |
| ); |
| `034 |
| psa_set_key_lifetime (&$policy, $life); |
| `035 |
| psa_set_key_bits (&$policy, $size); |
| `036 |
| psa_set_key_type (&$policy, $type); |
| `037 |
| psa_set_key_algorithm (&$policy, $algorithm); |
| `038 |
| psa_set_key_usage_flags (&$policy, $usage); |
| `039 |
| $life = psa_get_key_lifetime (&$policy); |
| `040 |
| $life = psa_get_key_lifetime (&$policy); |
| if ($life == PSA_KEY_LIFETIME_VOLATILE) { |
| TEST_LOG("$policy: Lifetime is volatile."); |
| } else { |
| TEST_LOG("$policy: Lifetime is persistent."); |
| } |
| `041 |
| $size = psa_get_key_bits (&$policy); |
| `042 |
| $type = psa_get_key_type (&$policy); |
| `043 |
| $type = psa_get_key_type (&$policy); |
| TEST_LOG("$policy: Key-type code == $type."); |
| `044 |
| $algorithm = psa_get_key_algorithm (&$policy); |
| `045 |
| $algorithm = psa_get_key_algorithm (&$policy); |
| TEST_LOG("$policy: Key-algorithm code == $algorithm."); |
| `046 |
| $usage = psa_get_key_usage_flags (&$policy); |
| `047 |
| if (($usage & $usage_string) != 0) { |
| TEST_LOG("$policy: $print_usage_true_string."); |
| } else { |
| TEST_LOG("$policy: $print_usage_false_string."); |
| } |
| `048 |
| crypto_status = psa_get_key_attributes ($key, &$policy); |
| `049 |
| if (crypto_status != $expect) { |
| TEST_FAIL("psa_get_key_attributes() expected $expect."); |
| return; |
| } |
| `050 |
| crypto_status = psa_generate_key (&$policy, &$key); |
| `051 |
| if (crypto_status != $expect) { |
| TEST_FAIL("psa_generate_key() expected $expect."); |
| return; |
| } |
| `052 |
| crypto_status |
| = psa_import_key (&$policy, $data, $length, &$key); |
| `053 |
| if (crypto_status != $expect) { |
| TEST_FAIL("psa_import_key() expected $expect."); |
| return; |
| } |
| `054 |
| crypto_status = psa_copy_key ($master, &$policy, &$copy); |
| `055 |
| if (crypto_status != $expect) { |
| TEST_FAIL("psa_copy_key() expected $expect."); |
| return; |
| } |
| `056 |
| /* Check that the data is correct */ |
| if (memcmp($act_data, $exp_data, |
| $length) != 0) { |
| TEST_FAIL("Read data should be equal to result data"); |
| return; |
| } |
| `057 |
| crypto_status |
| = psa_export_key ($key, $data, $length, &$act_size); |
| `058 |
| if (crypto_status != $expect) { |
| TEST_FAIL("psa_export_key() expected $expect."); |
| return; |
| } |
| `059 |
| crypto_status = psa_destroy_key($key); |
| `060 |
| if (crypto_status != $expect) { |
| TEST_FAIL("psa_destroy_key() expected $expect."); |
| return; |
| } |
| ` |