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