Add tf_fuzz tool
This is fully derived from tf-m repo.
Signed-off-by: Karl Zhang <karl.zhang@arm.com>
Change-Id: I8d35e70eda9081af66d8fa3f3cb4beb1d953060e
diff --git a/tf_fuzz/calls/README b/tf_fuzz/calls/README
new file mode 100644
index 0000000..c57499e
--- /dev/null
+++ b/tf_fuzz/calls/README
@@ -0,0 +1,10 @@
+These classes define objects that describe everything needed to generate a PSA
+call.
+
+For more information, please browse to:
+
+ https://ci.trustedfirmware.org/job/tf-m-build-test-nightly/lastSuccessfulBuild/artifact/build-docs/tf-m_documents/install/doc/user_guide/html/docs/user_guides/tf_fuzz/calls_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/calls/crypto_call.cpp b/tf_fuzz/calls/crypto_call.cpp
new file mode 100644
index 0000000..85d7ac0
--- /dev/null
+++ b/tf_fuzz/calls/crypto_call.cpp
@@ -0,0 +1,1385 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <cstdlib>
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "variables.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "randomization.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "crypto_call.hpp"
+#include "sst_asset.hpp"
+
+
+/**********************************************************************************
+ Methods of class policy_call follow:
+**********************************************************************************/
+
+/* Most of the policy classes, in their fill_in_prep_code() method, need to ensure
+ that, at a minimum, the policy variable (psa_key_attributes_t) exists, so, just
+ to cut down code duplication: */
+void policy_call::policy_fill_in_prep_code (void)
+{
+ vector<variable_info>::iterator policy_variable;
+
+ policy_variable = test_state->find_var (asset_info.get_name());
+ if (policy_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (asset_info.get_name());
+ policy_variable = test_state->find_var (asset_info.get_name());
+ prep_code.assign (test_state->bplate->bplate_string[declare_policy]);
+ find_replace_1st ("$var", asset_info.get_name(), prep_code);
+ }
+}
+
+
+policy_call::policy_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : crypto_call(test_state, call_ser_no, how_asset_found)
+{
+ // Note: Key attributes are set in the key_policy_info constructor.
+}
+policy_call::~policy_call (void)
+{
+ // Nothing further to delete.
+ return; // just to have something to pin a breakpoint onto
+}
+
+vector<psa_asset*>::iterator policy_call::resolve_asset (bool create_asset_bool,
+ psa_asset_usage where) {
+ vector<psa_asset*>::iterator found_asset;
+ vector<psa_asset*> *asset_vector;
+ int asset_pick;
+
+ if (random_asset != psa_asset_usage::all) {
+ // != psa_asset_usage::all means to choose some known asset at random:
+ if (random_asset == psa_asset_usage::active) {
+ asset_vector = &(test_state->active_policy_asset);
+ asset_info.how_asset_found = asset_search::found_active;
+ } else if (random_asset == psa_asset_usage::deleted) {
+ asset_vector = &(test_state->deleted_policy_asset);
+ asset_info.how_asset_found = asset_search::found_deleted;
+ } else {
+ // "invalid" assets are not currently used.
+ cerr << "\nError: Tool-internal: Please report error 1102 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(1102);
+ }
+ if (asset_vector->size() > 0) {
+ /* Pick an active or deleted asset at random: */
+ asset_pick = rand() % asset_vector->size();
+ found_asset = asset_vector->begin() + asset_pick;
+ /* Copy asset information into template tracker: */
+ asset_info.id_n = (*found_asset)->asset_info.id_n;
+ asset_info.asset_ser_no
+ = (*found_asset)->asset_info.asset_ser_no;
+ } else {
+ if (random_asset == psa_asset_usage::active) {
+ cerr << "\nError: A policy call asks for a "
+ << "randomly chosen active asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1010);
+ } else if (random_asset == psa_asset_usage::deleted) {
+ cerr << "\nError: A policy call asks for a "
+ << "randomly chosen deleted asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1011);
+ } // "invalid" assets are not currently used.
+ }
+ } else {
+ // Find the asset by name:
+ asset_info.how_asset_found = test_state->find_or_create_policy_asset (
+ psa_asset_search::name, where,
+ asset_info.get_name(), 0, asset_info.asset_ser_no,
+ create_asset_bool, found_asset );
+ if ( asset_info.how_asset_found == asset_search::unsuccessful
+ || asset_info.how_asset_found == asset_search::something_wrong ) {
+ cerr << "\nError: Tool-internal: Please report error 108 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(108);
+ }
+ }
+ return found_asset;
+}
+
+/**********************************************************************************
+ End of methods of class policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class key_call follow:
+**********************************************************************************/
+
+key_call::key_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : crypto_call(test_state, call_ser_no, how_asset_found)
+{
+ asset_info.the_asset = nullptr;
+}
+key_call::~key_call (void)
+{
+ // Nothing further to delete.
+ return; // just to have something to pin a breakpoint onto
+}
+
+vector<psa_asset*>::iterator key_call::resolve_asset (bool create_asset_bool,
+ psa_asset_usage where) {
+ vector<psa_asset*>::iterator found_asset;
+ vector<psa_asset*> *asset_vector;
+ int asset_pick;
+
+ if (random_asset != psa_asset_usage::all) {
+ // != psa_asset_usage::all means to choose some known asset at random:
+ if (random_asset == psa_asset_usage::active) {
+ asset_vector = &(test_state->active_key_asset);
+ asset_info.how_asset_found = asset_search::found_active;
+ } else if (random_asset == psa_asset_usage::deleted) {
+ asset_vector = &(test_state->deleted_key_asset);
+ asset_info.how_asset_found = asset_search::found_deleted;
+ } else {
+ // "invalid" assets are not currently used.
+ cerr << "\nError: Tool-internal: Please report error 1103 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(1103);
+ }
+ if (asset_vector->size() > 0) {
+ /* Pick an active or deleted asset at random: */
+ asset_pick = rand() % asset_vector->size();
+ found_asset = asset_vector->begin() + asset_pick;
+ /* Copy asset information into template tracker: */
+ asset_info.id_n = (*found_asset)->asset_info.id_n;
+ asset_info.asset_ser_no
+ = (*found_asset)->asset_info.asset_ser_no;
+ } else {
+ if (random_asset == psa_asset_usage::active) {
+ cerr << "\nError: A key call asks for a "
+ << "randomly chosen active asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1012);
+ } else if (random_asset == psa_asset_usage::deleted) {
+ cerr << "\nError: A key call asks for a "
+ << "randomly chosen deleted asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1013);
+ } // "invalid" assets are not currently used.
+ }
+ } else {
+ // Find the asset by name:
+ asset_info.how_asset_found = test_state->find_or_create_key_asset (
+ psa_asset_search::name, where,
+ asset_info.get_name(), 0, asset_info.asset_ser_no,
+ create_asset_bool, found_asset );
+ if ( asset_info.how_asset_found == asset_search::unsuccessful
+ || asset_info.how_asset_found == asset_search::something_wrong ) {
+ cerr << "\nError: Tool-internal: Please report error 108 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(108);
+ }
+ }
+ return found_asset;
+}
+
+/**********************************************************************************
+ End of methods of class key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class init_policy_call follow:
+**********************************************************************************/
+
+init_policy_call::init_policy_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[init_policy]);
+ call_description = "initialize-policy call";
+}
+init_policy_call::~init_policy_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool init_policy_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void init_policy_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void init_policy_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class init_policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class reset_policy_call follow:
+**********************************************************************************/
+
+reset_policy_call::reset_policy_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[reset_policy]);
+ call_description = "policy reset call";
+}
+reset_policy_call::~reset_policy_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool reset_policy_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void reset_policy_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void reset_policy_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class reset_policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class add_policy_usage_call follow:
+**********************************************************************************/
+
+add_policy_usage_call::add_policy_usage_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[add_policy_usage]);
+ call_description = "policy add-usage call";
+}
+add_policy_usage_call::~add_policy_usage_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool add_policy_usage_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void add_policy_usage_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+ /* TODO: The variable this creates should have been declared already. Should
+ this instead produce an error if it doesn't exist? */
+}
+
+void add_policy_usage_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$flag", policy.usage_string, call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class add_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class set_policy_lifetime_call follow:
+**********************************************************************************/
+
+set_policy_lifetime_call::set_policy_lifetime_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[set_policy_lifetime]);
+ call_description = "policy lifetime-set call";
+}
+set_policy_lifetime_call::~set_policy_lifetime_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_lifetime_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_lifetime_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void set_policy_lifetime_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$life",
+ policy.persistent? "PSA_KEY_LIFETIME_PERSISTENT"
+ : "PSA_KEY_LIFETIME_VOLATILE",
+ call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class set_policy_lifetime_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class set_policy_size_call follow:
+**********************************************************************************/
+
+set_policy_size_call::set_policy_size_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[set_policy_size]);
+ call_description = "policy size-set call";
+}
+set_policy_size_call::~set_policy_size_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_size_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_size_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void set_policy_size_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$size", to_string (policy.n_bits), call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class set_policy_size_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class set_policy_type_call follow:
+**********************************************************************************/
+
+set_policy_type_call::set_policy_type_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[set_policy_type]);
+ call_description = "policy type-set call";
+}
+set_policy_type_call::~set_policy_type_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_type_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_type_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void set_policy_type_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$type", policy.key_type, call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class set_policy_type_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class set_policy_algorithm_call follow:
+**********************************************************************************/
+
+set_policy_algorithm_call::set_policy_algorithm_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[set_policy_algorithm]);
+ call_description = "policy algorithm-set call";
+}
+set_policy_algorithm_call::~set_policy_algorithm_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_algorithm_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_algorithm_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void set_policy_algorithm_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$algorithm", policy.key_algorithm, call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class set_policy_algorithm_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class set_policy_usage_call follow:
+**********************************************************************************/
+
+set_policy_usage_call::set_policy_usage_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[set_policy_usage]);
+ call_description = "policy usage-set call";
+}
+set_policy_usage_call::~set_policy_usage_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool set_policy_usage_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, yes_create_asset);
+}
+
+void set_policy_usage_call::fill_in_prep_code (void)
+{
+ policy_fill_in_prep_code();
+}
+
+void set_policy_usage_call::fill_in_command (void)
+{
+ find_replace_1st ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$usage", "0", call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class set_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class get_policy_lifetime_call follow:
+**********************************************************************************/
+
+get_policy_lifetime_call::get_policy_lifetime_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_policy_lifetime]);
+ call_description = "policy lifetime-get call";
+}
+get_policy_lifetime_call::~get_policy_lifetime_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_lifetime_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_lifetime_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name() + "_life";
+ vector<variable_info>::iterator assign_variable;
+
+ policy_fill_in_prep_code(); // make sure the policy variable itself is defined
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_policy_lifetime]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void get_policy_lifetime_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$life", asset_info.get_name() + "_life", call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class get_policy_lifetime_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class get_policy_size_call follow:
+**********************************************************************************/
+
+get_policy_size_call::get_policy_size_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_policy_size]);
+ call_description = "policy size-get call";
+}
+get_policy_size_call::~get_policy_size_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_size_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_size_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name() + "_size";
+ vector<variable_info>::iterator assign_variable;
+
+ policy_fill_in_prep_code(); // make sure the policy variable itself is defined
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+ find_replace_all ("$var", var_name, prep_code);
+ find_replace_1st ("$init", to_string(exp_data.data.length()), prep_code);
+ }
+}
+
+void get_policy_size_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$size", asset_info.get_name() + "_size", call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class get_policy_size_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class get_policy_type_call follow:
+**********************************************************************************/
+
+get_policy_type_call::get_policy_type_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_policy_type]);
+ call_description = "policy type-get call";
+}
+get_policy_type_call::~get_policy_type_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_type_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_type_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name() + "_type";
+ vector<variable_info>::iterator assign_variable;
+
+ policy_fill_in_prep_code(); // make sure the policy variable itself is defined
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_policy_type]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void get_policy_type_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$type", asset_info.get_name() + "_type", call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class get_policy_type_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class get_policy_algorithm_call follow:
+**********************************************************************************/
+
+get_policy_algorithm_call::get_policy_algorithm_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_policy_algorithm]);
+ call_description = "policy algorithm-get call";
+}
+get_policy_algorithm_call::~get_policy_algorithm_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_algorithm_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_algorithm_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name() + "_algo";
+ vector<variable_info>::iterator assign_variable;
+
+ policy_fill_in_prep_code(); // make sure the policy variable itself is defined
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_policy_algorithm]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void get_policy_algorithm_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$algorithm", asset_info.get_name() + "_algo", call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class get_policy_algorithm_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class get_policy_usage_call follow:
+**********************************************************************************/
+
+get_policy_usage_call::get_policy_usage_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_policy_usage]);
+ call_description = "policy usage-get call";
+}
+get_policy_usage_call::~get_policy_usage_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool get_policy_usage_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void get_policy_usage_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name() + "_usage";
+ vector<variable_info>::iterator assign_variable;
+
+ policy_fill_in_prep_code(); // make sure the policy variable itself is defined
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_policy_usage]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void get_policy_usage_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$usage", asset_info.get_name() + "_usage", call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class get_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class print_policy_usage_call follow:
+**********************************************************************************/
+
+print_policy_usage_call::print_policy_usage_call (tf_fuzz_info *test_state,
+ long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[print_policy_usage]);
+ call_description = "policy usage-print call";
+}
+print_policy_usage_call::~print_policy_usage_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool print_policy_usage_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<policy_asset*> (this, dont_create_asset);
+}
+
+void print_policy_usage_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name() + "_usage";
+ vector<variable_info>::iterator assign_variable;
+
+ policy_fill_in_prep_code(); // make sure the policy variable itself is defined
+ // Make sure policy-usage variable is defined:
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_policy_usage]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void print_policy_usage_call::fill_in_command (void)
+{
+ string var_name = asset_info.get_name() + "_usage";
+
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", asset_info.get_name(), call_code);
+ find_replace_1st ("$usage_string", policy.usage_string, call_code);
+ find_replace_1st ("$usage", var_name, call_code);
+ find_replace_1st ("$print_usage_true_string", policy.print_usage_true_string,
+ call_code);
+ find_replace_1st ("$print_usage_false_string", policy.print_usage_false_string,
+ call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class print_policy_usage_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class get_key_policy_call follow:
+**********************************************************************************/
+
+get_key_policy_call::get_key_policy_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : policy_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_policy]);
+ check_code.assign (test_state->bplate->bplate_string[get_policy_check]);
+ call_description = "policy get call";
+}
+get_key_policy_call::~get_key_policy_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool get_key_policy_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+}
+
+void get_key_policy_call::fill_in_prep_code (void)
+{
+ // No prep code required.
+ return; // just to have something to pin a breakpoint onto
+}
+
+void get_key_policy_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("key", asset_info.get_name(), call_code);
+ find_replace_all ("$policy", policy.asset_2_name, call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class get_key_policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class generate_key_call follow:
+**********************************************************************************/
+
+generate_key_call::generate_key_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : key_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[generate_key]);
+ check_code.assign (test_state->bplate->bplate_string[generate_key_check]);
+ call_description = "key-generate call";
+}
+generate_key_call::~generate_key_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool generate_key_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+}
+
+void generate_key_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name();
+ vector<variable_info>::iterator assign_variable;
+
+ // Make sure key variable is defined:
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_key]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void generate_key_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", policy.asset_2_name, call_code);
+ find_replace_all ("$key", asset_info.get_name(), call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class generate_key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class create_key_call follow:
+**********************************************************************************/
+
+create_key_call::create_key_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : key_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[create_key]);
+ check_code.assign (test_state->bplate->bplate_string[create_key_check]);
+ call_description = "key-create call";
+}
+create_key_call::~create_key_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool create_key_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+}
+
+void create_key_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name();
+ vector<variable_info>::iterator assign_variable;
+ gibberish gib;
+ char gib_buff[500];
+ string t_string;
+
+ // Key variable:
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_key]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+ // Key-data variable:
+ var_name = asset_info.get_name() + "_set_data";
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+ find_replace_all ("$var", var_name, prep_code);
+ int rand_data_length = 12 + (rand() % 100);
+ gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
+ t_string = gib_buff;
+ find_replace_all ("$init", t_string, prep_code);
+ }
+}
+
+void create_key_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$policy", policy.asset_2_name, call_code);
+ find_replace_all ("$data", asset_info.get_name() + "_set_data", call_code);
+ find_replace_all ("$length", to_string (policy.n_bits), call_code);
+ find_replace_all ("$key", asset_info.get_name(), call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class create_key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class copy_key_call follow:
+**********************************************************************************/
+
+copy_key_call::copy_key_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : key_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[copy_key]);
+ check_code.assign (test_state->bplate->bplate_string[copy_key_check]);
+ call_description = "key-copy call";
+}
+copy_key_call::~copy_key_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool copy_key_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<key_asset*> (this, yes_create_asset);
+}
+
+void copy_key_call::fill_in_prep_code (void)
+{
+ string var_name = asset_info.get_name();
+ vector<variable_info>::iterator assign_variable;
+
+ // Make sure key variable is defined:
+ assign_variable = test_state->find_var (var_name);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (var_name);
+ prep_code.append (test_state->bplate->bplate_string[declare_key]);
+ find_replace_all ("$var", var_name, prep_code);
+ }
+}
+
+void copy_key_call::fill_in_command (void)
+{
+ vector<psa_asset*>::iterator key_asset;
+ vector<psa_asset*> *asset_vector;
+ int asset_pick;
+
+ // Calculate the expected results:
+ asset_search find_result;
+ vector<psa_asset*>::iterator asset;
+ long dummy = 0L;
+ // See if the source key does not exist:
+
+ if (random_asset != psa_asset_usage::all) {
+ // != psa_asset_usage::all means to choose some known asset at random:
+ if (random_asset == psa_asset_usage::active) {
+ asset_vector = &(test_state->active_key_asset);
+ find_result = asset_info.how_asset_found = asset_search::found_active;
+ // if empty, we'll error out, below.
+ } else if (random_asset == psa_asset_usage::deleted) {
+ asset_vector = &(test_state->deleted_key_asset);
+ find_result = asset_info.how_asset_found = asset_search::found_deleted;
+ } else {
+ // "invalid" assets are not currently used.
+ cerr << "\nError: Tool-internal: Please report error 1103 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(1103);
+ }
+ if (asset_vector->size() > 0) {
+ /* Pick an active or deleted asset at random: */
+ asset_pick = rand() % asset_vector->size();
+ key_asset = asset_vector->begin() + asset_pick;
+ /* Copy asset information into template tracker: */
+ asset_info.id_n = (*key_asset)->asset_info.id_n;
+ asset_info.asset_ser_no
+ = (*key_asset)->asset_info.asset_ser_no;
+ } else {
+ if (random_asset == psa_asset_usage::active) {
+ cerr << "\nError: A key call asks for a "
+ << "randomly chosen active asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1012);
+ } else if (random_asset == psa_asset_usage::deleted) {
+ cerr << "\nError: A key call asks for a "
+ << "randomly chosen deleted asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1013);
+ } // "invalid" assets are not currently used.
+ }
+ } else {
+ find_result = test_state->
+ find_or_create_key_asset (psa_asset_search::name, psa_asset_usage::active,
+ policy.asset_3_name, (uint64_t) 0, dummy,
+ dont_create_asset, key_asset);
+ }
+ if (find_result != asset_search::found_active) {
+ exp_data.pf_specified = true;
+ exp_data.pf_result_string = "PSA_ERROR_INVALID_ARGUMENT";
+ // TODO: Pull this in from boilerplate file
+ } else {
+ // See if the new policy does not exist:
+ find_result = test_state->
+ find_or_create_policy_asset (psa_asset_search::name, psa_asset_usage::active,
+ policy.asset_2_name, (uint64_t) 0, dummy,
+ dont_create_asset, asset);
+ if (find_result != asset_search::found_active) {
+ exp_data.pf_specified = true;
+ exp_data.pf_result_string = "PSA_ERROR_INVALID_ARGUMENT";
+ // TODO: Pull this in from boilerplate file
+ } else if (!(*asset)->policy.copyable) {
+ // See if the source key does not support export:
+ // TODO: Or wait, it's the original policy for the key, right?
+ exp_data.pf_specified = true;
+ exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
+ }
+ }
+
+ // (call_code already loaded by constructor)
+ find_replace_all ("$master", (*key_asset)->asset_info.get_name(), call_code);
+ find_replace_all ("$policy", policy.asset_2_name, call_code);
+ find_replace_all ("$copy", asset_info.get_name(), call_code);
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class copy_key_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class read_key_data_call follow:
+**********************************************************************************/
+
+read_key_data_call::read_key_data_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : key_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[read_key_data]);
+ check_code.assign (test_state->bplate->bplate_string[read_key_data_check]);
+ call_description = "key read-data call";
+}
+read_key_data_call::~read_key_data_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool read_key_data_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+}
+
+void read_key_data_call::fill_in_prep_code (void)
+{
+ string var_name, length_var_name, actual_length_var_name, var_name_suffix,
+ length_var_name_suffix, temp_string;
+ vector<variable_info>::iterator expect_variable;
+ vector<variable_info>::iterator assign_variable;
+
+ if (exp_data.data_var_specified) {
+ var_name.assign (exp_data.data_var + "_data");
+ length_var_name.assign (exp_data.data_var + "_length");
+ /* If actual-data variable doesn't already exist, create variable tracker,
+ and write declaration for it: */
+ expect_variable = test_state->find_var (exp_data.data_var);
+ if (expect_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (exp_data.data_var);
+ expect_variable = test_state->find_var (exp_data.data_var);
+ prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+ find_replace_1st ("$var", var_name, prep_code);
+ temp_string = (char *) expect_variable->value;
+ find_replace_1st ("$init", temp_string, prep_code);
+ // Input data length:
+ prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+ find_replace_1st ("$var", length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+ // TODO: Is these lengths in bits or bytes?
+ }
+ }
+ // else we're not comparing to named variable, so compare to assigned data.
+ // Actual (output) data length:
+ if (assign_data_var_specified) {
+ var_name.assign (assign_data_var + "_data");
+ length_var_name.assign (assign_data_var + "_length");
+ actual_length_var_name.assign (assign_data_var + "_act_length");
+ /* If actual-data variable doesn't already exist, create variable tracker,
+ and write declaration for it: */
+ assign_variable = test_state->find_var (assign_data_var);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (assign_data_var);
+ assign_variable = test_state->find_var (assign_data_var);
+ prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+ find_replace_1st ("$var", var_name, prep_code);
+ temp_string = (char *) assign_variable->value;
+ find_replace_1st ("$init", temp_string, prep_code);
+ // Input data length:
+ prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+ find_replace_1st ("$var", length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+ }
+ } else {
+ // Key data not read into a named variable, so use default C variable:
+ var_name = asset_info.get_name() + "_act_data";
+ prep_code.append (test_state->bplate->bplate_string[declare_string]);
+ find_replace_1st ("$var", var_name, prep_code);
+ find_replace_1st ("$init", set_data.get(), prep_code);
+ actual_length_var_name.assign (asset_info.get_name() + "_act_length");
+ prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+ find_replace_1st ("$var", actual_length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
+ }
+ length_var_name_suffix = "_read_length";
+ var_name.assign (asset_info.get_name() + var_name_suffix);
+ length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+ prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+ find_replace_1st ("$var", length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
+}
+
+void read_key_data_call::fill_in_command (void)
+{
+ string var_name, length_var_name, exp_var_name, exp_length_var_name,
+ actual_length_var_name, var_name_suffix, length_var_name_suffix,
+ temp_string;
+
+ // Fill in the PSA command itself:
+ actual_length_var_name.assign (asset_info.get_name() + "_read_length");
+ if (assign_data_var_specified) {
+ var_name.assign (assign_data_var + "_data");
+ length_var_name.assign (assign_data_var + "_length");
+ } else {
+ var_name_suffix = "_act_data";
+ var_name.assign (asset_info.get_name() + var_name_suffix);
+ length_var_name_suffix = "_act_length";
+ length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+ }
+ find_replace_1st ("$data", var_name, call_code);
+ find_replace_1st ("$key", asset_info.get_name(), call_code);
+ string id_string = to_string((long) asset_info.id_n++);
+ find_replace_1st ("$length", length_var_name, call_code);
+ find_replace_1st ("$act_size", actual_length_var_name, call_code);
+
+ // Check data:
+ if (exp_data.data_var_specified) {
+ check_code.assign (test_state->bplate->bplate_string[compare_data]);
+ exp_var_name.assign (exp_data.data_var + "_data");
+ exp_length_var_name.assign (exp_data.data_var + "_length");
+ find_replace_1st ("$act_data", var_name, check_code);
+ find_replace_1st ("$exp_data", exp_var_name, check_code);
+ find_replace_1st ("$length", exp_length_var_name, check_code);
+ }
+
+ // See if the source key did not exist:
+ if (!policy.exportable) {
+ // See if the source key does not support export:
+ exp_data.pf_specified = true;
+ exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
+ }
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class read_key_data_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class remove_key_call follow:
+**********************************************************************************/
+
+remove_key_call::remove_key_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : key_call(test_state, call_ser_no,
+ how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[remove_key]);
+ check_code.assign (test_state->bplate->bplate_string[remove_key_check]);
+ call_description = "key-remove call";
+}
+remove_key_call::~remove_key_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool remove_key_call::copy_call_to_asset (void)
+{
+ return copy_call_to_asset_t<key_asset*> (this, dont_create_asset);
+}
+
+void remove_key_call::fill_in_prep_code (void)
+{
+ // No prep code required.
+ return; // just to have something to pin a breakpoint onto
+}
+
+void remove_key_call::fill_in_command (void)
+{
+ // (call_code already loaded by constructor)
+ find_replace_all ("$key", asset_info.get_name(), call_code);
+ // Calculate the expected results:
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class remove_key_call.
+**********************************************************************************/
+
diff --git a/tf_fuzz/calls/crypto_call.hpp b/tf_fuzz/calls/crypto_call.hpp
new file mode 100644
index 0000000..7fd58cc
--- /dev/null
+++ b/tf_fuzz/calls/crypto_call.hpp
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CRYPTO_CALL_HPP
+#define CRYPTO_CALL_HPP
+
+#include <string>
+#include <vector>
+
+/* This project's header files #including other project headers quickly becomes
+ unrealistically complicated. The only solution is for each .cpp to include
+ the headers it needs.
+#include "psa_call.hpp"
+#include "crypto_asset.hpp"
+*/
+
+template<class T> bool copy_call_to_asset_t (psa_call *call, bool create_asset_bool)
+{
+ vector<psa_asset*>::iterator found_asset;
+
+ found_asset = call->resolve_asset (create_asset_bool, psa_asset_usage::all);
+ // Copy over everything relevant:
+ if (call->asset_info.how_asset_found != asset_search::not_found) {
+ call->asset_info.the_asset = reinterpret_cast<T>(*found_asset);
+ /* Note: The vector is base-class, but the assets in this list
+ themselves *really are* policy_asset-type objects. */
+ int i = call->asset_info.the_asset->set_data.n_set_vars; // save this
+ call->asset_info.the_asset->exp_data.data = call->exp_data.data;
+ call->asset_info.the_asset->set_data = call->set_data;
+ call->asset_info.the_asset->set_data.n_set_vars = call->set_data.n_set_vars = ++i;
+ call->asset_info.the_asset->policy = call->policy;
+ call->asset_info.the_asset->handle_str = call->asset_info.get_name();
+ if (call->asset_info.how_asset_found == asset_search::created_new) {
+ call->asset_info.the_asset->asset_info.name_specified
+ = call->asset_info.name_specified;
+ call->asset_info.the_asset->asset_info.set_name (call->asset_info.get_name());
+ call->asset_info.the_asset->asset_info.asset_ser_no
+ = call->asset_info.asset_ser_no;
+ call->asset_info.the_asset->asset_info.id_n = call->asset_info.id_n;
+ }
+ }
+ return true;
+}
+
+
+using namespace std;
+
+class policy_call : public crypto_call
+{
+public:
+ // Data members: // (low value in hiding these behind setters and getters)
+ // Methods:
+ vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+ psa_asset_usage where);
+ void policy_fill_in_prep_code (void);
+ policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~policy_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+// void calc_result_code (void); for *now* keep this in crypto_call::
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class key_call : public crypto_call
+{
+public:
+ // Data members: // (low value in hiding these behind setters and getters)
+ // Methods:
+ vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+ psa_asset_usage where);
+ key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~key_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+// void calc_result_code (void); for *now* keep this in crypto_call::
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+/**********************************************************************************
+ Derived classes of class policy_call follow:
+**********************************************************************************/
+
+
+class init_policy_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ init_policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~init_policy_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class reset_policy_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ reset_policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~reset_policy_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class set_policy_usage_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ set_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~set_policy_usage_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+/* set_policy_usage_call(), above, gives a policy particular attribute, and resets
+ all others. add_policy_usage_call(), below, ORs in an additional usage
+ attribute, to whatever is already in there. */
+
+class add_policy_usage_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ add_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~add_policy_usage_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class set_policy_lifetime_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ set_policy_lifetime_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~set_policy_lifetime_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class set_policy_algorithm_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ set_policy_algorithm_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~set_policy_algorithm_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class set_policy_size_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ set_policy_size_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~set_policy_size_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class set_policy_type_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ set_policy_type_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~set_policy_type_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class get_policy_lifetime_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ get_policy_lifetime_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~get_policy_lifetime_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class get_policy_size_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ get_policy_size_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~get_policy_size_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class get_policy_type_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ get_policy_type_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~get_policy_type_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class get_policy_algorithm_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ get_policy_algorithm_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~get_policy_algorithm_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class get_policy_usage_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ get_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~get_policy_usage_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+/* This is not actually a PSA call; it just emits code to print out, to the log,
+ information about the usage info retrieved in a get_policy_usage_call above. */
+class print_policy_usage_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ print_policy_usage_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~print_policy_usage_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class get_key_policy_call : public policy_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ get_key_policy_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~get_key_policy_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+/**********************************************************************************
+ End of derived classes of class policy_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Derived classes of class key_call follow:
+**********************************************************************************/
+
+
+class generate_key_call : public key_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ generate_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~generate_key_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class create_key_call : public key_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ create_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~create_key_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class copy_key_call : public key_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ copy_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~copy_key_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class read_key_data_call : public key_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ read_key_data_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~read_key_data_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class remove_key_call : public key_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ remove_key_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~remove_key_call (void);
+
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+/**********************************************************************************
+ End of derived classes of class key_call.
+**********************************************************************************/
+
+#endif // CRYPTO_CALL_HPP
diff --git a/tf_fuzz/calls/crypto_call.o b/tf_fuzz/calls/crypto_call.o
new file mode 100644
index 0000000..d2840ff
--- /dev/null
+++ b/tf_fuzz/calls/crypto_call.o
Binary files differ
diff --git a/tf_fuzz/calls/psa_call.cpp b/tf_fuzz/calls/psa_call.cpp
new file mode 100644
index 0000000..46af409
--- /dev/null
+++ b/tf_fuzz/calls/psa_call.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+
+
+
+/**********************************************************************************
+ Methods of class psa_call follow:
+**********************************************************************************/
+
+//**************** psa_call methods ****************
+
+psa_call::psa_call (tf_fuzz_info *test_state, long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+{
+ this->test_state = test_state;
+ this->asset_info.how_asset_found = how_asset_found;
+ set_data.string_specified = false;
+ set_data.set (""); // actual data
+ assign_data_var.assign (""); // name of variable assigned (dumped) to
+ assign_data_var_specified = false;
+ set_data.file_specified = false;
+ set_data.file_path.assign ("");
+ this->call_ser_no = call_ser_no = unique_id_counter++;
+ // These will be set in the lower-level constructors, but...
+ prep_code = call_code = check_code = "";
+ print_data = hash_data = false;
+ barrier = target_barrier = ""; // not (yet) any barrier for re-ordering calls
+ call_description = "";
+}
+
+psa_call::~psa_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+void psa_call::write_out_prep_code (ofstream &test_file)
+{
+ test_file << prep_code;
+}
+
+void psa_call::write_out_command (ofstream &test_file)
+{
+ test_file << call_code;
+}
+
+void psa_call::write_out_check_code (ofstream &test_file)
+{
+ if (!exp_data.pf_nothing) {
+ test_file << check_code;
+ } else {
+ test_file << " /* (No checks for this PSA call.) */" << endl;
+ }
+}
+
+/**********************************************************************************
+ End of methods of class psa_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class sst_call follow:
+**********************************************************************************/
+
+/* calc_result_code() fills in the check_code string member with the correct
+ result code (e.g., "PSA_SUCCESS" or whatever).
+
+ This is a big part of where the target modeling -- error modeling -- occurs,
+ so lots of room for further refinement here. */
+void sst_call::calc_result_code (void)
+{
+ string formalized; // "proper" result string
+
+ if (!exp_data.pf_nothing) {
+ if (exp_data.pf_pass) {
+ find_replace_all ("$expect",
+ test_state->bplate->bplate_string[sst_pass_string],
+ check_code);
+ } else if (exp_data.pf_fail) {
+ // Check for not-success:
+ find_replace_1st ("!=", "==",
+ check_code);
+ find_replace_all ("$expect",
+ test_state->bplate->bplate_string[sst_pass_string],
+ check_code);
+ find_replace_1st ("expected ", "expected not ",
+ check_code);
+ } else {
+ if (exp_data.pf_specified) {
+ formalized = formalize (exp_data.pf_result_string, "PSA_ERROR_");
+ find_replace_all ("$expect", formalized, check_code);
+ } else {
+ // Figure out what the message should read:
+ switch (asset_info.how_asset_found) {
+ case asset_search::found_active:
+ case asset_search::created_new:
+ find_replace_all ("$expect",
+ test_state->bplate->
+ bplate_string[sst_pass_string],
+ check_code);
+ break;
+ case asset_search::found_deleted:
+ case asset_search::not_found:
+ find_replace_all ("$expect",
+ test_state->bplate->
+ bplate_string[sst_fail_removed],
+ check_code);
+ break;
+ default:
+ find_replace_1st ("!=", "==",
+ check_code); // like "fail", just make sure...
+ find_replace_all ("$expect",
+ test_state->bplate->
+ bplate_string[sst_pass_string],
+ check_code); // ... it's *not* PSA_SUCCESS
+ break;
+ }
+ }
+ }
+ }
+}
+
+vector<psa_asset*>::iterator sst_call::resolve_asset (bool create_asset_bool,
+ psa_asset_usage where) {
+ vector<psa_asset*>::iterator found_asset;
+ vector<psa_asset*> *asset_vector;
+ int asset_pick;
+
+ if (random_asset != psa_asset_usage::all) {
+ // != psa_asset_usage::all means to choose some known asset at random:
+ if (random_asset == psa_asset_usage::active) {
+ asset_vector = &(test_state->active_sst_asset);
+ asset_info.how_asset_found = asset_search::found_active;
+ } else if (random_asset == psa_asset_usage::deleted) {
+ asset_vector = &(test_state->deleted_sst_asset);
+ asset_info.how_asset_found = asset_search::found_deleted;
+ } else {
+ // "invalid" assets are not currently used.
+ cerr << "\nError: Tool-internal: Please report error 1101 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(1101);
+ }
+ if (asset_vector->size() > 0) {
+ /* Pick an active or deleted asset at random: */
+ asset_pick = rand() % asset_vector->size();
+ found_asset = asset_vector->begin() + asset_pick;
+ /* Copy asset information into template tracker: */
+ asset_info.id_n = (*found_asset)->asset_info.id_n;
+ asset_info.asset_ser_no
+ = (*found_asset)->asset_info.asset_ser_no;
+ } else {
+ if (random_asset == psa_asset_usage::active) {
+ cerr << "\nError: An sst call asks for a "
+ << "randomly chosen active asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1008);
+ } else if (random_asset == psa_asset_usage::deleted) {
+ cerr << "\nError: An sst call asks for a "
+ << "randomly chosen deleted asset, when none " << endl
+ << "is currently defined." << endl;
+ exit(1009);
+ } // "invalid" assets are not currently used.
+ }
+ } else {
+ // Find the asset by name:
+ asset_info.how_asset_found = test_state->find_or_create_sst_asset (
+ psa_asset_search::name, where,
+ asset_info.get_name(), 0, asset_info.asset_ser_no,
+ create_asset_bool, found_asset );
+ if ( asset_info.how_asset_found == asset_search::unsuccessful
+ || asset_info.how_asset_found == asset_search::something_wrong ) {
+ cerr << "\nError: Tool-internal: Please report error 108 to " << endl
+ << "TF-Fuzz developers."
+ << endl;
+ exit(108);
+ }
+ }
+ return found_asset;
+}
+
+sst_call::sst_call (tf_fuzz_info *test_state, long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : psa_call(test_state, call_ser_no, how_asset_found)
+{
+ asset_info.the_asset = nullptr;
+ return; // just to have something to pin a breakpoint onto
+}
+sst_call::~sst_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+ End of methods of class sst_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class crypto_call follow:
+**********************************************************************************/
+
+/* calc_result_code() fills in the check_code string member with the correct
+ result code (e.g., "PSA_SUCCESS" or whatever). This "modeling" needs to be
+ improved and expanded upon *massively* more or less mirroring what is seen in
+ .../test/suites/crypto/crypto_tests_common.c in the psa_key_interface_test()
+ method, (starting around line 20ish). */
+void crypto_call::calc_result_code (void)
+{
+ string formalized; // "proper" result string
+
+ if (!exp_data.pf_nothing) {
+ if (exp_data.pf_pass) {
+ find_replace_all ("$expect",
+ test_state->bplate->bplate_string[sst_pass_string],
+ check_code);
+ } else if (exp_data.pf_fail) {
+ // Check for not-success:
+ find_replace_1st ("!=", "==",
+ check_code);
+ find_replace_all ("$expect",
+ test_state->bplate->bplate_string[sst_pass_string],
+ check_code);
+ find_replace_1st ("expected ", "expected not ",
+ check_code);
+ } else {
+ if (exp_data.pf_specified) {
+ formalized = formalize (exp_data.pf_result_string, "PSA_ERROR_");
+ find_replace_all ("$expect", formalized, check_code);
+ } else {
+ // Figure out what the message should read:
+ switch (asset_info.how_asset_found) {
+ case asset_search::found_active:
+ case asset_search::created_new:
+ find_replace_all ("$expect",
+ test_state->bplate->
+ bplate_string[sst_pass_string],
+ check_code);
+ break;
+ case asset_search::not_found:
+ case asset_search::found_deleted:
+ find_replace_all ("$expect", "PSA_ERROR_INVALID_HANDLE",
+ check_code); // TODO: take from boilerplate
+ break;
+ default:
+ find_replace_1st ("!=", "==",
+ check_code); // like "fail", just make sure...
+ find_replace_all ("$expect",
+ test_state->bplate->
+ bplate_string[sst_pass_string],
+ check_code); // ... it's *not* PSA_SUCCESS
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+bool crypto_call::copy_asset_to_call (void)
+{
+ if (asset_info.the_asset == nullptr) {
+ return false;
+ } else {
+ // Get updated asset info from the asset:
+ asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
+ asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+ exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
+ exp_data.data = asset_info.the_asset->exp_data.data;
+ return true;
+ }
+}
+
+
+crypto_call::crypto_call (tf_fuzz_info *test_state, long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : psa_call(test_state, call_ser_no, how_asset_found)
+{
+ // Nothing further to initialize.
+ return; // just to have something to pin a breakpoint onto
+}
+crypto_call::~crypto_call (void)
+{
+ // Nothing further to delete.
+ return; // just to have something to pin a breakpoint onto
+}
+
+/**********************************************************************************
+ End of methods of class crypto_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class security_call follow:
+**********************************************************************************/
+
+security_call::security_call (tf_fuzz_info *test_state, long &call_ser_no, // (constructor)
+ asset_search how_asset_found)
+ : psa_call(test_state, call_ser_no, how_asset_found)
+{
+ // Nothing further to initialize.
+ return; // just to have something to pin a breakpoint onto
+}
+security_call::~security_call (void)
+{
+ // Nothing further to delete.
+ return; // just to have something to pin a breakpoint onto
+}
+
+// resolve_asset() doesn't do anything for security_calls, since there's no asset involved.
+vector<psa_asset*>::iterator security_call::resolve_asset (bool create_asset_bool,
+ psa_asset_usage where)
+{
+ return test_state->active_sst_asset.end(); // (anything)
+}
+
+/* calc_result_code() fills in the check_code string member with the correct result
+ code (e.g., "PSA_SUCCESS" or whatever).
+
+ Since there are no actual PSA calls associated with security calls (so far at least),
+ this should never be invoked. */
+void security_call::calc_result_code (void)
+{
+ // Currently should not be invoked.
+ cerr << "\nError: Internal: Please report error #205 to TF-Fuzz developers." << endl;
+ exit (205);
+}
+
+/**********************************************************************************
+ End of methods of class security_call.
+**********************************************************************************/
+
+
diff --git a/tf_fuzz/calls/psa_call.hpp b/tf_fuzz/calls/psa_call.hpp
new file mode 100644
index 0000000..ed66245
--- /dev/null
+++ b/tf_fuzz/calls/psa_call.hpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_CALL_HPP
+#define PSA_CALL_HPP
+
+#include <string>
+
+/* This project's header files #including other project headers quickly becomes
+ unrealistically complicated. The only solution is for each .cpp to include
+ the headers it needs.
+#include "tf_fuzz.hpp"
+*/
+
+
+using namespace std;
+
+class psa_call
+{
+public:
+ /* Data members -- not all PSA calls have/need these, but they need to be acces-
+ sible polymorphically via a psa_call iterator: */
+ string call_description; // description of the call, just for tracing
+ expect_info exp_data; // everything about expected results
+ set_data_info set_data; // everything about setting PSA-asset-data values
+ asset_name_id_info asset_info; // everything about the asset(s) for this line
+ key_policy_info policy; // (specific to crypto, but have to put this here)
+ string asset_2_name; // if there's a 2nd asset, then this is its name
+ string asset_3_name; // if there's a 3rd asset, then this is its name
+ psa_asset_usage random_asset;
+ /* if asked to use some random asset from active or deleted, this says
+ which. psa_asset_usage::all if not using this feature. */
+ bool assign_data_var_specified; // asset data to/from named variable
+ string assign_data_var; // name of variable to dump (assign) data into
+ // Expected-result info:
+ bool print_data; // true to print asset data to test log
+ bool hash_data; // true to hash data for later comparison
+ string id_string; // not all PSA calls involve an ID, but a diverse set do
+ long call_ser_no; // unique serial# for this psa_call (see note in tf_fuzz.hpp)
+ tf_fuzz_info *test_state; // the big blob with pointers to everything going on
+ string barrier;
+ /* "barrier" is used for template-line operations that resolve a series of
+ PSA calls. In particular, with respect to the fact that TF-Fuzz strives
+ to randomize these multiple calls where possible, meaning interspersing
+ them among other, earlier commands. However, for example, calls to set
+ the aspects of a policy can't be pushed too far back, such as in among
+ calls setting that same policy for a previous operation! "barrier" is
+ either "", in which case this call does not care whether you place calls
+ before it, or it contains the name of an asset that, calls related to
+ which must be placed *after* this call. */
+ string target_barrier;
+ /* asset to tell the psa_call objects to set and search barrier to when
+ re-ordering PSA calls. For key policies, this is not necessarily the
+ nominal asset of that call. For a policy call, it is that policy asset,
+ so that later re-settings of the same policy don't pollute the current
+ setting of that policy. However, for key sets and reads, it is not the
+ key asset, but its policy. */
+ // Methods:
+ virtual vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+ psa_asset_usage where) = 0;
+ virtual bool copy_call_to_asset (void) = 0;
+ virtual bool copy_asset_to_call (void) = 0;
+ virtual void fill_in_prep_code (void) = 0;
+ virtual void fill_in_command (void) = 0;
+ void write_out_prep_code (ofstream &test_file);
+ void write_out_command (ofstream &test_file);
+ void write_out_check_code (ofstream &test_file);
+ psa_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~psa_call (void);
+
+protected:
+ // Data members:
+ string prep_code; // declarations and such prior to all of the calls
+ string call_code; // for the call itself
+ string check_code; // for the code to check success of the call
+ static long unique_id_counter; // counts off unique IDs for assets
+ // Methods:
+ virtual void calc_result_code (void) = 0;
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class sst_call : public psa_call
+{
+public:
+ // Data members: // (low value in hiding these behind setters and getters)
+ // Methods:
+ vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+ psa_asset_usage where);
+ sst_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~sst_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+ void calc_result_code (void);
+
+private:
+ // Data members:
+ // Methods:
+};
+
+class crypto_call : public psa_call
+{
+public:
+ // Data members: // (low value in hiding these behind setters and getters)
+ // Methods:
+ bool copy_asset_to_call (void);
+ crypto_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~crypto_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+ void calc_result_code (void);
+ // for now, the method-overide buck stops here, but that'll probably change
+
+private:
+ // Data members:
+ // Methods:
+};
+
+class security_call : public psa_call
+ /* Strictly speaking, these don't really correspond to PSA calls, so it's a little
+ iffy to subclass them from psa_call. However, the calling patterns work out
+ right. */
+{
+public:
+ // Data members: // (low value in hiding these behind setters and getters)
+ // Methods:
+ vector<psa_asset*>::iterator resolve_asset (bool create_asset_bool,
+ psa_asset_usage where);
+ security_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~security_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+ void calc_result_code (void);
+ // Should never be invoked, since security calls generate no PSA calls.
+
+private:
+ // Data members:
+ // Methods:
+};
+
+#endif // PSA_CALL_HPP
diff --git a/tf_fuzz/calls/psa_call.o b/tf_fuzz/calls/psa_call.o
new file mode 100644
index 0000000..7caabe5
--- /dev/null
+++ b/tf_fuzz/calls/psa_call.o
Binary files differ
diff --git a/tf_fuzz/calls/security_call.cpp b/tf_fuzz/calls/security_call.cpp
new file mode 100644
index 0000000..a99496a
--- /dev/null
+++ b/tf_fuzz/calls/security_call.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <cstdlib>
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "randomization.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "security_call.hpp"
+#include "sst_asset.hpp"
+
+
+
+/**********************************************************************************
+ Methods of class hash_call follow:
+**********************************************************************************/
+
+hash_call::hash_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : security_call(test_state, call_ser_no, how_asset_found)
+{
+ call_description = "hash call";
+}
+hash_call::~hash_call (void)
+{
+ // Nothing further to delete.
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool hash_call::copy_call_to_asset (void)
+{
+ // The assets are not directly involved in this call.
+ return true;
+}
+
+bool hash_call::copy_asset_to_call (void)
+{
+ // The assets are not directly involved in this call.
+ return true;
+}
+
+/* Note: These functions are overridden in all subclasses, but they still need to be
+ defined, or the linker gives the error "undefined reference to `vtable... */
+void hash_call::fill_in_prep_code (void)
+{
+ // No prep code for hash comparisons.
+}
+
+void hash_call::fill_in_command (void)
+{
+ if (asset_info.asset_name_vector.size() > 1) { // nothing to compare with less than 2
+ // Fill in preceding comment:
+ // Fill in the hash-comparison code itself:
+ for (auto outer = asset_info.asset_name_vector.begin();
+ outer < asset_info.asset_name_vector.end();
+ ++outer) {
+ for (auto inner = outer+1;
+ inner < asset_info.asset_name_vector.end();
+ ++inner) {
+ call_code.append (" if ( " + *outer + "_act_hash == " + *inner
+ + "_act_hash) {\n");
+ call_code.append ( " TEST_FAIL(\"Probable data leak between assets "
+ + *outer + " and " + *inner + ".\\n\");\n");
+ call_code.append (" return;\n");
+ call_code.append (" }\n");
+ // TODO: Pull this from boilerplate!!
+ }
+ }
+ } else {
+ call_code.assign (" /* Cannot compare hashes; only one asset specified. */\n");
+
+ }
+}
+
+/**********************************************************************************
+ End of methods of class hash_call.
+**********************************************************************************/
diff --git a/tf_fuzz/calls/security_call.hpp b/tf_fuzz/calls/security_call.hpp
new file mode 100644
index 0000000..e55a278
--- /dev/null
+++ b/tf_fuzz/calls/security_call.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SECURITY_CALL_HPP
+#define SECURITY_CALL_HPP
+
+#include <string>
+#include <vector>
+
+/* This project's header files #including other project headers quickly becomes
+ unrealistically complicated. The only solution is for each .cpp to include
+ the headers it needs. */
+
+
+using namespace std;
+
+class hash_call : public security_call
+{
+public:
+ // Data members: // (low value in hiding these behind setters and getters)
+ // Methods:
+ bool copy_call_to_asset (void);
+ bool copy_asset_to_call (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ /* Hash checks are different from the rest in that there's a single "call" --
+ not a PSA call though -- for all of the assets cited in the template line.
+ In other cases, create a single call for each asset cited by the template
+ line, but in this case it's a single call for all of them. */
+ hash_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~hash_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+// void calc_result_code (void); for *now* keep this in security_call::
+
+private:
+ // Data members:
+ // Methods:
+};
+
+#endif // #ifndef SECURITY_CALL_HPP
diff --git a/tf_fuzz/calls/security_call.o b/tf_fuzz/calls/security_call.o
new file mode 100644
index 0000000..5cfd78c
--- /dev/null
+++ b/tf_fuzz/calls/security_call.o
Binary files differ
diff --git a/tf_fuzz/calls/sst_call.cpp b/tf_fuzz/calls/sst_call.cpp
new file mode 100644
index 0000000..9aa7762
--- /dev/null
+++ b/tf_fuzz/calls/sst_call.cpp
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "sst_call.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+#include "variables.hpp"
+
+
+
+/**********************************************************************************
+ Methods of class sst_set_call follow:
+**********************************************************************************/
+
+sst_set_call::sst_set_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : sst_call(test_state, call_ser_no, how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign (""); // will fill in, depending upon template line content
+ call_code.assign (test_state->bplate->bplate_string[set_sst_call]);
+ check_code.assign (test_state->bplate->bplate_string[set_sst_check]);
+ call_description = "SST-set call";
+}
+sst_set_call::~sst_set_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool sst_set_call::copy_call_to_asset (void)
+{
+ vector<psa_asset*>::iterator found_asset;
+
+ found_asset = resolve_asset (yes_create_asset, psa_asset_usage::all);
+ // Copy over everything relevant:
+ if (asset_info.how_asset_found != asset_search::not_found) {
+ asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
+ /* Note: The vector is base-class, but the assets in this list
+ themselves *really are* sst_asset-type objects. */
+ int i = asset_info.the_asset->set_data.n_set_vars; // save this
+ asset_info.the_asset->set_data = set_data; // TO DO: does this make sense?!
+ asset_info.the_asset->set_data.n_set_vars = set_data.n_set_vars = ++i;
+ asset_info.the_asset->set_data.flags_string.assign (set_data.flags_string);
+ if (asset_info.how_asset_found == asset_search::created_new) {
+ asset_info.the_asset->asset_info.name_specified = asset_info.name_specified;
+ asset_info.the_asset->asset_info.set_name (asset_info.get_name());
+ asset_info.the_asset->asset_info.asset_ser_no = asset_info.asset_ser_no;
+ asset_info.the_asset->asset_info.id_n = asset_info.id_n;
+ }
+ }
+ return true;
+}
+
+bool sst_set_call::copy_asset_to_call (void)
+{
+ // Get updated asset info from the asset:
+ asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
+ asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+ exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
+ exp_data.data = asset_info.the_asset->exp_data.data;
+ return true;
+}
+
+void sst_set_call::fill_in_prep_code (void)
+{
+ string var_name, length_var_name, var_name_suffix, length_var_name_suffix,
+ temp_string;
+ vector<variable_info>::iterator assign_variable;
+
+ if (assign_data_var_specified) {
+ var_name.assign (assign_data_var + "_data");
+ length_var_name.assign (assign_data_var + "_length");
+ /* If actual-data variable doesn't already exist, create variable tracker,
+ and write declaration for it: */
+ assign_variable = test_state->find_var (assign_data_var);
+ if (assign_variable == test_state->variable.end()) {
+ // No such variable exists, so:
+ test_state->make_var (assign_data_var);
+ assign_variable = test_state->find_var (assign_data_var);
+ prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+ find_replace_1st ("$var", var_name, prep_code);
+ temp_string = (char *) assign_variable->value;
+ find_replace_1st ("$init", temp_string, prep_code);
+ // Actual-data length:
+ prep_code.append (test_state->bplate->bplate_string[declare_size_t]);
+ find_replace_1st ("$var", length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+ // Offset (always 0 for now):
+ find_replace_1st ("$offset", "0", prep_code);
+ }
+ } else {
+ // Single string of two lines declaring string data and its length:
+ var_name_suffix = "_set_data";
+ length_var_name_suffix = "_set_length";
+ if (set_data.n_set_vars > 0) {
+ var_name_suffix += "_" + to_string(set_data.n_set_vars);
+ length_var_name_suffix += "_" + to_string(set_data.n_set_vars);
+ // We'll increment set_data.n_set_vars after we fill in the call itself.
+ }
+ var_name.assign (asset_info.get_name() + var_name_suffix);
+ length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+ prep_code = test_state->bplate->bplate_string[declare_string];
+ find_replace_1st ("$var", var_name, prep_code);
+ find_replace_1st ("$init", set_data.get(), prep_code);
+ temp_string.assign (test_state->bplate->bplate_string[declare_int]);
+ find_replace_1st ("static int", "static uint32_t", temp_string);
+ prep_code.append (temp_string);
+ find_replace_1st ("$var", length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(set_data.get().length()), prep_code);
+ }
+}
+
+void sst_set_call::fill_in_command (void)
+{
+ string var_name, length_var_name, var_name_suffix, length_var_name_suffix,
+ temp_string;
+
+ // Fill in preceding comment:
+ if (asset_info.how_asset_found == asset_search::created_new) {
+ find_replace_1st ("$op", "Creating", call_code);
+ } else {
+ find_replace_1st ("$op", "Resetting", call_code);
+ }
+ if (asset_info.name_specified) {
+ find_replace_1st ("$description", "\"" + asset_info.get_name() + ",\"",
+ call_code);
+ } else {
+ find_replace_1st ("$description",
+ "UID = " + to_string((long) asset_info.id_n), call_code);
+ }
+ if (set_data.string_specified) {
+ find_replace_1st ("$data_source",
+ "\"" + set_data.get().substr (0, 10) + "...\"",
+ call_code);
+ } else if (set_data.file_specified) {
+ find_replace_1st ("$data_source", "from file " + set_data.file_path,
+ call_code);
+ } else {
+ find_replace_1st (" $data_source", "", call_code);
+ }
+ // Fill in the PSA command itself:
+ if (assign_data_var_specified) {
+ var_name.assign (assign_data_var + "_data");
+ length_var_name.assign (assign_data_var + "_length");
+ } else {
+ var_name_suffix = "_set_data";
+ if (set_data.n_set_vars > 0) {
+ var_name_suffix += "_" + to_string(set_data.n_set_vars);
+ }
+ var_name.assign (asset_info.get_name() + var_name_suffix);
+ length_var_name_suffix = "_set_length";
+ if (set_data.n_set_vars > 0) {
+ length_var_name_suffix += "_" + to_string(set_data.n_set_vars);
+ }
+ length_var_name.assign (asset_info.get_name() + length_var_name_suffix);
+ }
+ find_replace_1st ("$data", var_name, call_code);
+ find_replace_1st ("$flags", set_data.flags_string, call_code);
+ string id_string = to_string((long) asset_info.id_n);
+ find_replace_1st ("$uid", id_string, call_code);
+ find_replace_1st ("$length", length_var_name, call_code);
+ // Figure out what expected results:
+ if ( set_data.flags_string == "PSA_STORAGE_FLAG_WRITE_ONCE"
+ && set_data.n_set_vars > 0) {
+ exp_data.pf_specified = true;
+ exp_data.pf_result_string = "PSA_ERROR_NOT_PERMITTED";
+ }
+ calc_result_code();
+}
+
+/**********************************************************************************
+ End of methods of class sst_set_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class sst_get_call follow:
+**********************************************************************************/
+
+sst_get_call::sst_get_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : sst_call(test_state, call_ser_no, how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[get_sst_call]);
+ check_code.assign ("");
+ // depends upon the particular usage; will get it in fill_in_command()
+ call_description = "SST-get call";
+}
+sst_get_call::~sst_get_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool sst_get_call::copy_call_to_asset (void)
+{
+ vector<psa_asset*>::iterator found_asset;
+
+ found_asset = resolve_asset (dont_create_asset, psa_asset_usage::active);
+ if (asset_info.how_asset_found != asset_search::not_found) {
+ // will be found for set calls, but not necessarily others
+ asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
+ // Note: Vector is of base-class type, but the assets *are* sst_asset.
+ /* Locating the asset is all we need to do here; copy_asset_to_call() will
+ do the rest. */
+ }
+ return true;
+ // TODO: Shouldn't data be copied over?
+}
+
+bool sst_get_call::copy_asset_to_call (void)
+{
+ if (asset_info.the_asset != nullptr) {
+ // will be found for set calls, but not necessarily others
+ set_data.string_specified = asset_info.the_asset->set_data.string_specified;
+ set_data.file_specified = asset_info.the_asset->set_data.file_specified;
+ set_data.set (asset_info.the_asset->set_data.get());
+ set_data.flags_string = asset_info.the_asset->set_data.flags_string;
+ asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+ asset_info.asset_ser_no = asset_info.the_asset->asset_info.asset_ser_no;
+ asset_info.name_specified = asset_info.the_asset->asset_info.name_specified;
+ asset_info.the_asset->exp_data.n_exp_vars++;
+ exp_data.n_exp_vars = asset_info.the_asset->exp_data.n_exp_vars;
+ }
+ return true;
+}
+
+void sst_get_call::fill_in_prep_code (void)
+{
+ string var_base, var_name, length_var_name, temp_string, var_name_suffix,
+ expected;
+ vector<variable_info>::iterator act_variable, exp_variable;
+
+ if (!(print_data || hash_data)) {
+ // Checking asset data verbatim against expected, so:
+ if (exp_data.data_var_specified) {
+ // Template specified a variable name to "check" against; use that:
+ var_base.assign (exp_data.data_var);
+ exp_variable = test_state->find_var (var_base);
+ if (exp_variable == test_state->variable.end()) {
+ test_state->make_var (var_base);
+ exp_variable = test_state->find_var (var_base);
+ var_name = var_base + "_data";
+ prep_code.append (test_state->bplate->bplate_string[declare_string]);
+ find_replace_1st ("$var", var_name, prep_code);
+ temp_string = (char *) exp_variable->value;
+ find_replace_1st ("$init", temp_string, prep_code);
+ // Expected-data length:
+ temp_string.assign (test_state->bplate->bplate_string[declare_int]);
+ find_replace_1st ("static int", "static size_t", temp_string);
+ }
+ } else {
+ if (exp_data.data_specified) {
+ // Checking against literal expected data:
+ expected.assign (exp_data.data);
+ } else {
+ // Check against what we believe the asset to contain:
+ expected.assign (set_data.get());
+ }
+ var_name_suffix = "_exp_data";
+ if (exp_data.n_exp_vars > 0) {
+ var_name_suffix =
+ var_name_suffix + "_" + to_string(exp_data.n_exp_vars);
+ }
+ var_name.assign (asset_info.get_name() + var_name_suffix);
+ prep_code.assign(test_state->bplate->bplate_string[declare_string]);
+ find_replace_1st("$var", var_name, prep_code);
+ find_replace_1st("$init", expected, prep_code);
+ }
+ }
+ // Actual data:
+ if (assign_data_var_specified) {
+ var_base.assign (assign_data_var);
+ } else {
+ var_base.assign (asset_info.get_name() + "_act");
+ }
+ var_name.assign (var_base + "_data");
+ length_var_name.assign (var_base + "_length");
+ /* If actual-data variable doesn't already exist, create variable tracker,
+ and write declaration for it: */
+ act_variable = test_state->find_var (var_base);
+ if (act_variable == test_state->variable.end()) {
+ test_state->make_var (var_base);
+ act_variable = test_state->find_var (var_base);
+ prep_code.append (test_state->bplate->bplate_string[declare_big_string]);
+ find_replace_1st ("$var", var_name, prep_code);
+ temp_string = (char *) act_variable->value;
+ find_replace_1st ("$init", temp_string, prep_code);
+ // Actual-data length:
+ temp_string.assign (test_state->bplate->bplate_string[declare_int]);
+ find_replace_1st ("static int", "static size_t", temp_string);
+ prep_code.append (temp_string);
+ find_replace_1st ("$var", length_var_name, prep_code);
+ find_replace_1st ("$init", to_string(temp_string.length()), prep_code);
+ // Offset (always 0 for now):
+ find_replace_1st ("$offset", "0", prep_code);
+ }
+ // If hashing the (actual) data, then create a variable for that:
+ if (hash_data && !act_variable->hash_declared) {
+ var_name = var_base + "_hash";
+ prep_code.append (test_state->bplate->bplate_string[declare_generic]);
+ // where to put the hash of the data
+ find_replace_1st ("$type", "uint32_t", prep_code);
+ find_replace_1st ("$var", var_name, prep_code);
+ find_replace_1st ("$init", "0", prep_code); // for now...
+ act_variable->hash_declared = true;
+ }
+}
+
+void sst_get_call::fill_in_command (void)
+{
+ string exp_var_name, act_var_name, act_data_length, hash_var_name,
+ id_string, var_name_suffix;
+
+/* TODO: Flesh-out/fix this (it was a good try/start, but not quite right):
+ // Fill in preceding comment:
+ if (asset_info.how_asset_found == asset_search::created_new) {
+ find_replace_1st ("$op", "Creating", call_code);
+ } else {
+ find_replace_1st ("$op", "Resetting", call_code);
+ }
+ if (asset_info.name_specified) {
+ find_replace_1st ("$description", "\"" + asset_info.get_name() + ",\"",
+ call_code);
+ } else {
+ find_replace_1st ("$description",
+ "UID = " + to_string((long) asset_info.id_n), call_code);
+ }
+ if (set_data.string_specified) {
+ find_replace_1st ("$data_source",
+ "\"" + data.substr (0, 10) + "...\"",
+ call_code);
+ } else if (set_data.file_specified) {
+ find_replace_1st ("$data_source", "from file " + set_data.file_path,
+ call_code);
+ } else {
+ find_replace_1st (" $data_source", "", call_code);
+ }
+*/ // Fill in the call itself:
+ if (print_data || hash_data) {
+ // Dump to variable; no data-check code needed:
+ check_code.assign (test_state->bplate->bplate_string[get_sst_check]);
+ } else {
+ // Check either against literal or variable, so need data-check code too:
+ check_code.assign (test_state->bplate->bplate_string[get_sst_check_all]);
+ }
+ /* Note: Can fill in the check code identically between the dump-to-variable
+ and check-data cases, because the boilerplate for the former is just an
+ abbreviated version of the latter. The find_replace_1st() calls for
+ the check-data stuff will just simply not have any effect. */
+ if (exp_data.data_var_specified) {
+ // Check against data in variable:
+ exp_var_name.assign (exp_data.data_var + "_data");
+ } else {
+ var_name_suffix = "_exp_data";
+ if (exp_data.n_exp_vars > 0) {
+ var_name_suffix =
+ var_name_suffix + "_" + to_string(exp_data.n_exp_vars);
+ }
+ exp_var_name.assign (asset_info.get_name() + var_name_suffix);
+ }
+ if (assign_data_var_specified) {
+ act_var_name.assign (assign_data_var + "_data");
+ act_data_length.assign (assign_data_var + "_length");
+ } else {
+ act_var_name.assign (asset_info.get_name() + "_act_data");
+ act_data_length.assign (asset_info.get_name() + "_act_length");
+ }
+
+ id_string = to_string((long) asset_info.id_n);
+ // Fill in the PSA command itself:
+ find_replace_1st ("$uid", id_string, call_code);
+ find_replace_all ("$length", to_string(set_data.get().length()), call_code);
+ find_replace_1st ("$offset", to_string(set_data.data_offset), call_code);
+ find_replace_1st ("$exp_data", exp_var_name, call_code);
+ find_replace_all ("$act_data", act_var_name, call_code);
+ find_replace_all ("$act_length", act_data_length, call_code);
+ // Perform most of the same substitutions in the check_code:
+// TODO: Make data checks contingent upon the PSA call itself passing?
+ find_replace_1st ("$offset", "0", check_code);
+ find_replace_1st ("$exp_data", exp_var_name, check_code);
+ find_replace_all ("$act_data", act_var_name, check_code);
+ find_replace_all ("$length", act_data_length, check_code);
+ if (print_data) {
+ check_code.append (test_state->bplate->bplate_string[test_log]);
+ find_replace_1st ("$message", act_var_name, check_code);
+ }
+ if (hash_data) {
+ hash_var_name.assign (asset_info.get_name() + "_act_hash");
+ // this is where to put the hash of the data
+ check_code.append (test_state->bplate->bplate_string[get_sst_hash]);
+ find_replace_all ("$act_data_var", act_var_name, check_code);
+ find_replace_all ("$hash_var", hash_var_name, check_code);
+ }
+ // Figure out what expected results:
+ calc_result_code(); // this only fills $expect check_code
+ // Fill in expected data, actual data, and length:
+}
+
+/**********************************************************************************
+ End of methods of class sst_get_call.
+**********************************************************************************/
+
+
+/**********************************************************************************
+ Methods of class sst_remove_call follow:
+**********************************************************************************/
+
+sst_remove_call::sst_remove_call (tf_fuzz_info *test_state, // (constructor)
+ long &call_ser_no,
+ asset_search how_asset_found)
+ : sst_call(test_state, call_ser_no, how_asset_found)
+{
+ // Copy the boilerplate text into local buffers:
+ prep_code.assign ("");
+ call_code.assign (test_state->bplate->bplate_string[remove_sst]);
+ check_code.assign (test_state->bplate->bplate_string[remove_sst_check]);
+ call_description = "SST-remove call";
+}
+sst_remove_call::~sst_remove_call (void)
+{
+ return; // just to have something to pin a breakpoint onto
+}
+
+bool sst_remove_call::copy_call_to_asset (void)
+{
+ vector<psa_asset*>::iterator found_asset;
+
+ found_asset = resolve_asset (dont_create_asset, psa_asset_usage::all);
+ if (asset_info.how_asset_found != asset_search::not_found) {
+ asset_info.the_asset = reinterpret_cast<sst_asset*>(*found_asset);
+ // Note: Vector is of base-class type, but the assets *are* sst_asset.
+ if (asset_info.how_asset_found == asset_search::found_active) {
+ // Delete asset; move it from active vector to deleted vector:
+ test_state->deleted_sst_asset.push_back (asset_info.the_asset);
+ test_state->active_sst_asset.erase (found_asset);
+ } /* if not active, we'll deem the call expected to fail. */
+ }
+ return true;
+}
+
+bool sst_remove_call::copy_asset_to_call (void)
+{
+ if (asset_info.the_asset != nullptr) {
+ set_data.string_specified = asset_info.the_asset->set_data.string_specified;
+ set_data.file_specified = asset_info.the_asset->set_data.file_specified;
+ set_data.flags_string = asset_info.the_asset->set_data.flags_string;
+ asset_info.id_n = asset_info.the_asset->asset_info.id_n;
+ asset_info.name_specified = asset_info.the_asset->asset_info.name_specified;
+ }
+ return true;
+}
+
+void sst_remove_call::fill_in_prep_code (void)
+{
+ // No prep-code.
+ return; // just to have something to pin a breakpoint onto
+}
+
+void sst_remove_call::fill_in_command (void)
+{
+ // Fill in the call:
+ string id_string = to_string((long) asset_info.id_n);
+ find_replace_1st ("$uid", id_string, call_code);
+ // Fill in expected results:
+ calc_result_code(); // this only fills $expect check_code
+}
+
+/**********************************************************************************
+ End of methods of class sst_remove_call.
+**********************************************************************************/
+
diff --git a/tf_fuzz/calls/sst_call.hpp b/tf_fuzz/calls/sst_call.hpp
new file mode 100644
index 0000000..537b21f
--- /dev/null
+++ b/tf_fuzz/calls/sst_call.hpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SST_CALL_HPP
+#define SST_CALL_HPP
+
+#include <string>
+#include <vector>
+#include <cstdint>
+
+/* This project's header files #including other project headers quickly becomes
+ unrealistically complicated. The only solution is for each .cpp to include
+ the headers it needs.
+#include "sst_asset.hpp"
+#include "psa_call.hpp"
+*/
+
+
+using namespace std;
+
+class sst_set_call : public sst_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ bool copy_asset_to_call (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ sst_set_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~sst_set_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+
+class sst_get_call : public sst_call
+{
+public:
+ // Data members:
+ uint32_t offset;
+ uint32_t data_length;
+ string data_var_name;
+ // Methods:
+ bool copy_call_to_asset (void);
+ bool copy_asset_to_call (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ sst_get_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~sst_get_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+class sst_remove_call : public sst_call
+{
+public:
+ // Data members:
+ // Methods:
+ bool copy_call_to_asset (void);
+ bool copy_asset_to_call (void);
+ void fill_in_prep_code (void);
+ void fill_in_command (void);
+ sst_remove_call (tf_fuzz_info *test_state, long &asset_ser_no,
+ asset_search how_asset_found); // (constructor)
+ ~sst_remove_call (void);
+
+protected:
+ // Data members:
+ // Methods:
+
+private:
+ // Data members:
+ // Methods:
+};
+
+#endif // SST_CALL_HPP
+
diff --git a/tf_fuzz/calls/sst_call.o b/tf_fuzz/calls/sst_call.o
new file mode 100644
index 0000000..8b92b0d
--- /dev/null
+++ b/tf_fuzz/calls/sst_call.o
Binary files differ