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/utility/README b/tf_fuzz/utility/README
new file mode 100644
index 0000000..5285fff
--- /dev/null
+++ b/tf_fuzz/utility/README
@@ -0,0 +1,11 @@
+As its name implies, this .../tf_fuzz/utility directory just contains
+various utility-compute code.
+
+
+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/utility_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/utility/compute.cpp b/tf_fuzz/utility/compute.cpp
new file mode 100644
index 0000000..708a1f3
--- /dev/null
+++ b/tf_fuzz/utility/compute.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <cstdint>  // for uint32_t
+#include "compute.hpp"
+
+
+using namespace std;
+
+/**********************************************************************************
+   Methods of class crc32 follow:
+**********************************************************************************/
+
+crc32::crc32 (void)
+{
+    shift_reg = 0x55555555;  // just give it some default value
+}
+
+void crc32::seed_lfsr (uint32_t init_value)
+{
+    shift_reg = init_value;
+}
+
+/* lfsr_1b() performs one shift of the LFSR, factoring in a single bit of info,
+   that single bit must be in the low-order bit of the parameter.  It returns
+   the LFSR value, which may be ignored. */
+uint32_t crc32::lfsr_1b (uint32_t a_bit)
+{
+    bool odd;
+
+    odd = ((shift_reg ^ a_bit) & 1) == 1;
+    shift_reg >>= 1;
+    if (odd) {
+        shift_reg ^= polynomial;
+    }
+    if (shift_reg == 0) {
+        // Theoretically should never happen, but precaution...
+        seed_lfsr (0x55555555);
+    }
+    return shift_reg;
+}
+
+uint32_t crc32::crc (uint8_t a_byte)
+{
+    for (int i = 0;  i < 8;  i++) {
+        lfsr_1b ((uint32_t) a_byte);
+        a_byte >>= 1;
+    }
+    return shift_reg;
+}
+
+uint32_t crc32::crc (uint16_t a_halfword)
+{
+    for (int i = 0;  i < 16;  i++) {
+        lfsr_1b ((uint32_t) a_halfword);
+        a_halfword >>= 1;
+    }
+    return shift_reg;
+}
+
+uint32_t crc32::crc (uint32_t a_word)
+{
+    for (int i = 0;  i < 32;  i++) {
+        lfsr_1b ((uint32_t) a_word);
+        a_word >>= 1;
+    }
+    return shift_reg;
+}
+
+/**********************************************************************************
+   End of methods of class crc32.
+**********************************************************************************/
diff --git a/tf_fuzz/utility/compute.hpp b/tf_fuzz/utility/compute.hpp
new file mode 100644
index 0000000..c6ece6c
--- /dev/null
+++ b/tf_fuzz/utility/compute.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef COMPUTE_HPP
+#define COMPUTE_HPP
+
+#include <cstdlib>
+
+using namespace std;
+
+/* Arguably at least, this LFSR-based hashing code is run more commonly on the
+   target itself -- included in the generated code -- than it is run here.
+   However, it's available here too, such as to parallel-calculate expected hash
+   values. */
+
+class crc32
+{
+public:
+    void seed_lfsr (uint32_t init_value);
+    /* lfsr_1b() performs one shift of the LFSR, factoring in a single bit of info,
+       that single bit must be in the low-order bit of the parameter. */
+    uint32_t lfsr_1b (uint32_t a_bit);
+    // crc() has two overloadings, calculating the CRC for byte or word quantities:
+    uint32_t crc (uint8_t a_byte);
+    uint32_t crc (uint16_t a_halfword);
+    uint32_t crc (uint32_t a_word);
+    crc32 (void);
+private:
+    const uint32_t polynomial = 0xb4bcd35c;
+    uint32_t shift_reg;
+};
+
+#endif /* COMPUTE_HPP */
diff --git a/tf_fuzz/utility/compute.o b/tf_fuzz/utility/compute.o
new file mode 100644
index 0000000..ee4e580
--- /dev/null
+++ b/tf_fuzz/utility/compute.o
Binary files differ
diff --git a/tf_fuzz/utility/data_blocks.cpp b/tf_fuzz/utility/data_blocks.cpp
new file mode 100644
index 0000000..09a25e9
--- /dev/null
+++ b/tf_fuzz/utility/data_blocks.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* These classes "cut down the clutter" by grouping together related data and
+   associated methods (most importantly their constructors) used in template_
+   line, psa_call, psa_asset (etc.). */
+
+#include <string>
+#include <vector>
+#include <cstdint>
+
+#include "class_forwards.hpp"
+
+#include "boilerplate.hpp"
+#include "randomization.hpp"
+#include "gibberish.hpp"
+#include "compute.hpp"
+#include "string_ops.hpp"
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "crypto_asset.hpp"
+#include "find_or_create_asset.hpp"
+#include "psa_call.hpp"
+#include "template_line.hpp"
+#include "tf_fuzz.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class expect_info follow:
+**********************************************************************************/
+
+expect_info::expect_info (void)  // (default constructor)
+{
+    pf_nothing = false;  // by default, TF-Fuzz provides expected results
+    pf_pass = pf_fail = pf_specified = false;
+    pf_result_string.assign ("");  data.assign ("");
+    data_var_specified = false;
+    data_var.assign ("");  // name of expected-data variable
+    data_specified = false;
+    data_matches_asset = false;
+    data.assign ("");
+    pf_info_incomplete = true;
+    n_exp_vars = -1;  // so the first reference is 0 (no suffix), then _1, _2, ...
+    expected_results_saved = false;
+}
+expect_info::~expect_info (void)  // (destructor)
+{}
+
+void expect_info::set_pf_pass (void)
+{
+    pf_pass = true;
+    pf_fail = pf_nothing = pf_specified = false;
+    pf_result_string = "";
+}
+
+void expect_info::set_pf_fail (void)
+{
+    pf_fail = true;
+    pf_pass = pf_nothing = pf_specified = false;
+    pf_result_string = "";
+}
+
+void expect_info::set_pf_nothing (void)
+{
+    pf_nothing = true;
+    pf_fail = pf_pass = pf_specified = false;
+    pf_result_string = "";
+}
+
+void expect_info::set_pf_error (string error)
+{
+    pf_specified = true;
+    pf_result_string.assign (error);  // just default "guess," to be filled in
+    pf_pass = pf_fail = pf_nothing = false;
+}
+
+/* The expected pass/fail results are not available from the parser until the call has
+   already been created.  The flag, pf_info_incomplete, that indicates whether or not
+   the "expects" information has been filled in.  If not, fill it in from the template,
+   once that info has been parsed. */
+void expect_info::copy_expect_to_call (psa_call *the_call)
+{
+    the_call->exp_data.pf_nothing = pf_nothing;
+    the_call->exp_data.pf_pass = pf_pass;
+    the_call->exp_data.pf_fail = pf_fail;
+    the_call->exp_data.pf_specified = pf_specified;
+    the_call->exp_data.pf_result_string = pf_result_string;
+    the_call->exp_data.expected_results_saved = true;
+    the_call->exp_data.pf_info_incomplete = false;
+}
+
+/**********************************************************************************
+   End of methods of class expect_info.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Class set_data_info methods regarding setting and getting asset-data values:
+**********************************************************************************/
+
+string set_data_info::rand_creation_flags (void)
+{
+    return ((rand() % 2) == 1)?
+        "PSA_STORAGE_FLAG_WRITE_ONCE" : "PSA_STORAGE_FLAG_NONE";
+
+    /* TODO:  There are also PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION and
+              PSA_STORAGE_FLAG_NO_CONFIDENTIALITY, but they don't seem to appear
+              in any test suites, so it's iffy as to whether they really exist.
+              We'll not routinely initialize to them, for now at least, but if
+              we want to enable them, then uncomment the following:
+    string result = "";
+    const int most_flags = 2,
+    int n_flags = (rand() % most_flags);
+
+    for (int i = 0;  i < ;  i < n_flags;  ++i) {
+        switch (rand() % 4) {
+            case 0:
+                result += "PSA_STORAGE_FLAG_NONE";
+                break;
+            case 1:
+                result += "PSA_STORAGE_FLAG_WRITE_ONCE";
+                break;
+            case 2:
+                result += "PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION";
+                break;
+            case 3:
+                result += "PSA_STORAGE_FLAG_NO_CONFIDENTIALITY";
+                break;
+        }
+        if (i < n_flags-1)
+            result += " | ";
+    }
+    if (result == "") result = "PSA_STORAGE_FLAG_NONE";
+*/
+}
+
+set_data_info::set_data_info (void)  // (default constructor)
+{
+    literal_data_not_file = true;  // currently, not using files as data sources
+    string_specified = false;
+    data.assign ("");
+    random_data = false;
+    file_specified = false;
+    file_path.assign ("");
+    n_set_vars = -1;  // so the first reference is 0 (no suffix), then _1, _2, ...
+    data_offset = 0;
+    flags_string = rand_creation_flags();
+}
+set_data_info::~set_data_info (void)  // (destructor)
+{}
+
+/* set() establishes:
+   *  An asset's data value from a template line (e.g., set sst snort data "data
+      value"), and
+   *  *That* such a value was directly specified, as opposed to no data value having
+      been specified, or a random data value being requested.
+   Arguably, this method "has side effects," in that it not only sets a value, but
+   also "takes notes" about where that value came from.
+*/
+void set_data_info::set (string set_val)
+{
+    literal_data_not_file = true;  // currently, not using files as data sources
+    string_specified = true;
+    data.assign (set_val);
+}
+
+/* set_calculated() establishes:
+   *  An asset's data value as *not* taken from a template line, and
+   *  *That* such a value was not directly specified in any template line, such as
+      if a random data value being requested.
+   Arguably, this method "has side effects," in that it not only sets a value, but
+   also "takes notes" about where that value came from.
+*/
+void set_data_info::set_calculated (string set_val)
+{
+    literal_data_not_file = true;  // currently, not using files as data sources
+    string_specified = false;
+    data.assign (set_val);
+}
+
+/* randomize() establishes:
+   *  An asset's data value as *not* taken from a template line, and
+   *  *That* such a value was randomized.
+   Arguably, this method "has side effects," in that it not only sets a value, but
+   also "takes notes" about where that value came from.
+*/
+void set_data_info::randomize (void)
+{
+    gibberish gib;
+    char gib_buff[4096];  // spew gibberish into here
+    int rand_data_length = 0;
+
+    string_specified = false;
+    random_data = true;
+    literal_data_not_file = true;
+    rand_data_length = 40 + (rand() % 256);
+        /* Note:  Multiple assets do get different random data */
+    gib.sentence (gib_buff, gib_buff + rand_data_length - 1);
+    data = gib_buff;
+}
+
+/* Getter for protected member, data.  Protected so that it can only be set by
+   set() or set_calculated(), above, to establish not only its value but
+   how it came about. */
+string set_data_info::get (void)
+{
+    return data;
+}
+
+/* Currently, files as data sources aren't used, so this whole method is not "of
+   use," but that might change at some point. */
+bool set_data_info::set_file (string file_name)
+{
+    literal_data_not_file = true;
+    string_specified = false;
+    data.assign ("");
+    file_specified = true;
+    // Remove the ' ' quotes around the file name:
+    file_name.erase (0, 1);
+    file_name.erase (file_name.length()-1, 1);
+    file_path = file_name;
+    return true;
+}
+
+/**********************************************************************************
+   End of methods of class set_data_info.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Class asset_name_id_info methods regarding setting and getting asset-data values:
+**********************************************************************************/
+
+asset_name_id_info::asset_name_id_info (void)  // (default constructor)
+{
+    id_n_not_name = false;  // (arbitrary)
+    id_n = 100LL + ((uint64_t) rand() % 10000);  // default to random ID#
+    asset_name.assign ("");
+    id_n_specified = name_specified = false;  // no ID info yet
+    asset_type = psa_asset_type::unknown;
+    how_asset_found = asset_search::not_found;
+    the_asset = nullptr;
+    asset_ser_no = -1;
+}
+asset_name_id_info::~asset_name_id_info (void)
+{
+    asset_name_vector.clear();
+    asset_id_n_vector.clear();
+}
+
+/* set_name() establishes:
+   *  An asset's "human" name from a template line, and
+   *  *That* that name was directly specified, as opposed to the asset being defined
+      by ID only, or a random name being requested.
+   Arguably, this method "has side effects," in that it not only sets a name, but
+   also "takes notes" about where that name came from.
+*/
+void asset_name_id_info::set_name (string set_val)
+{
+    /* Use this to set the name as specified in the template file.  Call this only
+       if the template file does indeed define a name. */
+    name_specified = true;
+    asset_name.assign (set_val);
+}
+
+/* set_calc_name() establishes:
+   *  An asset's "human" name *not* from a template line, and
+   *  *That* that name was *not* directly specified in any template line.
+   Arguably, this method "has side effects," in that it not only sets a name, but
+   also "takes notes" about where that name came from.
+*/
+void asset_name_id_info::set_calc_name (string set_val)
+{
+    name_specified = false;
+    asset_name.assign (set_val);
+}
+
+// set_just_name() sets an asset's "human" name, without noting how that name came up.
+void asset_name_id_info::set_just_name (string set_val)
+{
+    asset_name.assign (set_val);
+}
+
+/* Getter for protected member, asset_name.  Protected so that it can only be set by
+   set_name() or set_calc_name(), above, to establish not only its value but
+   how it came about. */
+string asset_name_id_info::get_name (void)
+{
+    return asset_name;
+}
+
+// Asset IDs can be set directly from a uint64_t or converted from a string:
+void asset_name_id_info::set_id_n (string set_val)
+{
+    id_n = stol (set_val, 0, 0);
+}
+void asset_name_id_info::set_id_n (uint64_t set_val)
+{
+    id_n = set_val;
+}
+
+// Create ID-based name:
+string asset_name_id_info::make_id_n_based_name (uint64_t id_n)
+{
+    string result;
+
+    switch (asset_type) {
+        case psa_asset_type::sst:
+            result = "SST_ID_";
+            break;
+        case psa_asset_type::key:
+            result = "Key_ID_";
+            break;
+        case psa_asset_type::policy:
+            result = "Policy_ID_";
+            break;
+        default:
+            cerr << "\nError:  Tool-internal:  Please report error "
+                 << "#1223 to the TF-Fuzz developers." << endl;
+            exit(1223);
+    }
+    result.append(to_string(id_n));
+    return result;
+}
+
+/**********************************************************************************
+   End of methods of class asset_name_id_info.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Class key_policy_info methods:
+**********************************************************************************/
+
+key_policy_info::key_policy_info (void)  // (default constructor)
+{
+    get_policy_from_key = false;  // specify policy asset by a key that uses it.
+    copy_key = false;  // not copying one key to another
+    /* The following settings are not necessarily being randomized in mutually-
+       consistent ways, for two reasons:  First, the template should set all that
+       matter, and second, testing TF response to nonsensical settings is also
+       valuable. */
+    exportable  = (rand()%2==1? true : false);
+    copyable    = (rand()%2==1? true : false);
+    can_encrypt = (rand()%2==1? true : false);
+    can_decrypt = (rand()%2==1? true : false);
+    can_sign    = (rand()%2==1? true : false);
+    can_verify  = (rand()%2==1? true : false);
+    derivable   = (rand()%2==1? true : false);
+    persistent  = (rand()%2==1? true : false);
+    // There's a really huge number of possible key types; won't randomize all:
+    key_type = rand_key_type();
+    usage_string.assign ("");
+    print_usage_true_string.assign ("");
+    print_usage_false_string.assign ("");
+    key_algorithm = rand_key_algorithm();
+    n_bits = 55 + (rand() % 1000);
+    gibberish *gib = new gibberish;
+    char buffer[256];
+    char *end;
+    int buf_len = 5ULL + (uint64_t) (rand() % 10);
+    end = gib->word (false, buffer, buffer + buf_len);
+    *end = '\0';
+    buffer[buf_len] = '\0';
+    handle_str = buffer;
+    gib->sentence (buffer, buffer + (40ULL + (uint64_t) (rand() % 200)));
+    key_data = buffer;
+    delete gib;
+}
+key_policy_info::~key_policy_info (void)  // (destructor)
+{
+    return;  // (even if only to have something to pin a breakpoint on)
+}
+
+
+/**********************************************************************************
+   End of methods of class key_policy_info.
+**********************************************************************************/
diff --git a/tf_fuzz/utility/data_blocks.hpp b/tf_fuzz/utility/data_blocks.hpp
new file mode 100644
index 0000000..f4628a5
--- /dev/null
+++ b/tf_fuzz/utility/data_blocks.hpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string>
+
+/* These classes "cut down the clutter" by grouping together related data and
+   associated methods (most importantly their constructors) used in template_
+   line, psa_call, psa_asset (etc.). */
+
+#ifndef DATA_BLOCKS_HPP
+#define DATA_BLOCKS_HPP
+
+/* 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.  However these in particular are mostly axiomatic:  Not
+   dependent upon other classes. */
+
+
+using namespace std;
+
+
+/**********************************************************************************
+  Class expect_info is all about expected data and expected pass/fail information.
+  The members are therefore broken down with prefixes pf_ (for pass/fail) or
+  data_.  Pass/fail, is broadly:
+  *  "Pass" == the test passes
+  *  "Specified" == some specified failure (e.g., no such asset)
+  *  "Nothing" == no expectation
+  Expected data refers to psa-asset data values, generally after reading them.
+  Currently, they are limited to character strings, but that will probably be
+  generalized in the future.
+**********************************************************************************/
+
+class expect_info
+{
+public:
+    // Data members:
+        // Expected-result info:
+        bool pf_nothing;  // true to not generate results-check(s)
+        bool pf_pass;  // if !expect.pf_nothing, then pass is expected
+        bool pf_fail;  // if "expect fail" was specified
+        bool pf_specified;
+            /* if !pf_nothing && !pf_pass, then
+               true == expected result was specified
+               false == tf_fuzz must model expected result, and
+               pf_result_string is the expected result */
+        string pf_result_string;
+        bool data_specified;  // (literal expected data specified)
+        string data;  // what test template expects data from reading an asset to be
+        int n_exp_vars;  // how many check-value variables have been created
+        bool data_var_specified;  // check against a variable
+        string data_var;  // name of variable containing expected data
+        bool pf_info_incomplete;
+            /* In parsing the template, the expect information comes later than the
+               rest of the call info.  This flag tells us to fill in the pass/fail
+               expect info when it comes available. */
+        bool expected_results_saved;
+            /* This indicates whether expected results have or have not already been
+               copied to this call.  It's a "one-shot," so to speak, to copy only
+               once when results are known good.  Since calls can be inserted into
+               earlier points in the call sequence (not always appended), the call
+               sequence has to be gone over for this process multiple times. */
+    // Methods:
+        expect_info (void);  // (default constructor)
+        ~expect_info (void);  // (destructor)
+        void set_pf_pass (void);
+        void set_pf_fail (void);
+        void set_pf_nothing (void);
+        void set_pf_error (string error);
+        void copy_expect_to_call (psa_call *the_call);
+
+protected:
+    // Data members:
+        bool data_matches_asset;
+            /* true if template specifies expected data, and that expected data
+               agrees with that in the asset */
+};
+
+
+/**********************************************************************************
+  Class set_data_info addresses PSA-asset data values as affected, directly or
+  indirctly/implicitly, by the template-line content.  "Directly," that is, by
+  virtue of the template line stating verbatim what to set data to, or indirectly
+  by virtue of telling TF-Fuzz to create random data for it.
+**********************************************************************************/
+
+class set_data_info
+{
+public:
+    // Data members:
+        bool string_specified;
+            // true if a string of data is specified in template file
+        bool random_data;  // true to generate random data for the asset
+        bool file_specified;  // true if a file of expected data was specified
+        bool literal_data_not_file;
+            // true to use data strings rather than files as data source
+        int n_set_vars;  // how many implicit set variables have been created
+        string file_path;  // path to file, if specified
+        string flags_string;
+            // creation flags, nominally for SST but have to be in a vector of base-class
+        uint32_t data_offset;  // offset into asset data
+    // Methods:
+        set_data_info (void);  // (default constructor)
+        ~set_data_info (void);  // (destructor)
+        void set (string set_val);
+        void set_calculated (string set_val);
+        void randomize (void);
+        string get (void);
+        bool set_file (string file_name);
+
+protected:
+    // Data members:
+        string data;  // String describing asset data.
+    // Methods:
+        string rand_creation_flags (void);
+};
+
+
+/**********************************************************************************
+  Class asset_name_id_info groups together and acts upon all information related to the
+  human names (as reflected in the code variable names, etc.) for PSA assets.
+**********************************************************************************/
+
+class asset_name_id_info
+{
+public:
+    // Data members (not much value in "hiding" these behind getters)
+        psa_asset *the_asset;
+        psa_asset_type asset_type;  // SST vs. key vs. policy (etc.)
+        bool id_n_not_name;  // true to create a PSA asset by ID
+        bool name_specified;  // true iff template supplied human name
+        bool id_n_specified;  // true iff template supplied ID #
+        vector<string> asset_name_vector;
+        vector<int> asset_id_n_vector;
+        long asset_ser_no;  // unique ID for psa asset needed to find data string
+        asset_search how_asset_found;
+        uint64_t id_n;  // asset ID# (e.g., SST UID).
+            /* Note:  This is just a holder to pass ID from template-line to call.  The
+               IDs for a given template line are in asset_info.asset_id_n_vector. */
+    // Methods:
+        asset_name_id_info (void);  // (default constructor)
+        ~asset_name_id_info (void);  // (destructor)
+        void set_name (string set_val);
+        void set_calc_name (string set_val);
+        void set_just_name (string set_val);
+        string get_name (void);
+        void set_id_n (string set_val);
+        void set_id_n (uint64_t set_val);
+        string make_id_n_based_name (uint64_t id_n);
+            // create UID-based asset name
+
+protected:
+    // Data members:
+        string asset_name;  // parsed from template, assigned to psa_asset object
+};
+
+
+/**********************************************************************************
+  Class key_policy_info collects together the aspects of a Crypto key attributes
+  ("policies").  These include aspects that can affect TF-Fuzz's test-generation.
+**********************************************************************************/
+
+class key_policy_info
+{
+public:
+    // Data members:
+        // Digested info:
+        bool get_policy_from_key;
+            /* if true, then we must get policy info from a stated key;  the asset
+               here is a key that uses the policy, and not the policy itself. */
+        bool implicit_policy;
+            /* if true, then the key was defined with policy specifications, but not
+               a named policy, meaning that we have to create an implicit policy. */
+        bool copy_key;  // true to indicate copying one key to another
+        bool exportable;   // key data can be exported (viewed - fail exports if not).
+        bool copyable;     // can be copied (fail key-copies if not).
+        bool can_encrypt;  // OK for encryption (fail other uses).
+        bool can_decrypt;  // OK for decryption (fail other uses).
+        bool can_sign;     // OK for signing (fail other operations).
+        bool can_verify;   // OK for verifing a message signature (fail other uses).
+        bool derivable;    // OK for derive other keys (fail other uses).
+        bool persistent;   // must be deleted at the end of test.
+        string usage_string;
+            /* This string is set to a PSA_KEY_USAGE_* value in the template
+               immediately prior to making define_call<add_policy_usage_call>.
+               The copy_template_to_call() therein sets the corresponding string
+               in the call, and that is copied into the code in the fill_in_command()
+               invocation. */
+        string print_usage_true_string;
+            /* For printing out policy usage, this states how to describe the usage
+               if it can be used this way.  This is managed similarly with, and used
+               in conjunction with usage_string above.  NOTE:  THIS ALSO SERVES AS AN
+               INDICATOR WHETHER OR NOT TO PRINT ON A GET-USAGE CALL.  "" means not
+               to print. */
+        string print_usage_false_string;
+            /* Also for printing out policy usage, this is how to describe usage if
+               it cannot be used this way. */
+        string key_type;   // AES, DES, RSA pair, DS public, etc.
+        string key_algorithm;
+        int n_bits;
+           // for get_key_info call (possibly others) exected key size in bits
+        string handle_str; // the text name of the key's "handle"
+        string key_data;   // the key data as best we can know it.
+        string asset_2_name;
+            // if there's a 2nd asset, such as policy on key call, this is its name
+        string asset_3_name;  // if there's a 3rd asset, then this is its name
+
+    // Methods:
+        key_policy_info (void);  // (default constructor)
+        ~key_policy_info (void);  // (destructor)
+
+
+protected:
+    // Data members:
+        bool data_matches_asset;
+            /* true if template specifies expected data, and that expected data
+               agrees with that in the asset */
+};
+
+
+
+#endif // DATA_BLOCKS_HPP
+
diff --git a/tf_fuzz/utility/data_blocks.o b/tf_fuzz/utility/data_blocks.o
new file mode 100644
index 0000000..58a37a9
--- /dev/null
+++ b/tf_fuzz/utility/data_blocks.o
Binary files differ
diff --git a/tf_fuzz/utility/find_or_create_asset.hpp b/tf_fuzz/utility/find_or_create_asset.hpp
new file mode 100644
index 0000000..3daf37c
--- /dev/null
+++ b/tf_fuzz/utility/find_or_create_asset.hpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef FIND_OR_CREATE_ASSET_HPP
+#define FIND_OR_CREATE_ASSET_HPP
+
+using namespace std;
+
+/* This enum defines possible results when asked to find an existing, or create a
+   new PSA asset. */
+enum class asset_search
+{   found_active,  // found as an actively-used asset
+    found_deleted,  // found as a previously-used, but now-unusable asset
+    found_invalid,  // found as a previously-used, but now-unusable asset
+    not_found,  // if not found and if not allowed to create it
+    created_new,  // no such existing asset was found so created new, active asset
+    unsuccessful,  // ran out of memory or whatever
+    something_wrong  // something wrong with the code;  shouldn't happen
+};
+// Search areas:
+enum class psa_asset_usage  // one particular area or all
+{   active,  // found as an actively-used asset
+    deleted,  // found as a previously-used, but now-unusable asset
+    invalid,  // (invalid assets aren't completely defined yet)
+    all,  // if not found and if not allowed to create it
+    none  // just create it
+};
+// In searching for an asset, this enum specifies what to search for:
+enum class psa_asset_search
+{   name,  // its human name
+    id,  // its id, such as SST UID
+    serial  // its serial number assigned upon creation
+};
+// Types of assets:
+enum class psa_asset_type
+{   sst,  // (pretty obvious what each of these mean)
+    key,
+    policy,
+    unknown
+};
+
+
+// A few consts just to make code more readable:
+const bool yes_create_asset = true;
+const bool dont_create_asset = false;
+
+
+/* There are several variants, by asset type, of this method.  So, C++ templating
+   is best.  Note that, while the vectors are pointers to the base, psa_asset type,
+   the individual entries are all of the same ASSET_TYPE type. */
+template <typename ASSET_TYPE>
+asset_search generic_find_or_create_asset (
+    vector<psa_asset*> &active_asset_vector,  // the three vectors of known assets
+    vector<psa_asset*> &deleted_asset_vector,
+    vector<psa_asset*> &invalid_asset_vector,
+    psa_asset_search criterion,  // what to search on
+    psa_asset_usage where,  // where to search
+    string target_name,  // ignored if not searching on name
+    uint64_t target_id,  // also ignored if not searching on ID (e.g., SST UID)
+    long &serial_no,  // search on this if requested, but return serial regardless
+    bool create_asset,  // true to create the asset if it doesn't exist
+    typename vector<psa_asset*>::iterator &asset
+        // returns iterator to the requested asset
+) {
+    ASSET_TYPE *new_asset;
+    bool match = false;  // match found
+    // Look first in active assets:
+    if (where == psa_asset_usage::active || where == psa_asset_usage::all) {
+        for (auto as = active_asset_vector.begin();  as < active_asset_vector.end();
+             ++as) {
+            psa_asset *pass = *as;
+            switch (criterion) {
+                case psa_asset_search::name:  // human-meaningful name
+                    match = (pass->asset_info.get_name() == target_name);
+                    break;
+                case psa_asset_search::id:  // ID#
+                    match = (pass->asset_info.id_n == target_id);
+                    break;
+                default:  // psa_asset_search::serial
+                    match = (pass->asset_info.asset_ser_no == serial_no);
+                    break;
+            }
+            if (match) {
+                asset = as;
+                return asset_search::found_active;
+            }
+        }
+    }
+    // Look then in deleted assets:
+    if (where == psa_asset_usage::deleted || where == psa_asset_usage::all) {
+        for (auto as = deleted_asset_vector.begin();  as < deleted_asset_vector.end();
+             ++as) {
+            psa_asset *pass = *as;
+            switch (criterion) {
+                case psa_asset_search::name:  // human-meaningful name
+                    match = (pass->asset_info.get_name() == target_name);
+                    break;
+                case psa_asset_search::id:  // ID#
+                    match = (pass->asset_info.id_n == target_id);
+                    break;
+                default:  // psa_asset_search::serial
+                    match = (pass->asset_info.asset_ser_no == serial_no);
+                    break;
+            }
+            if (match) {
+                asset = as;
+                if (create_asset) {
+                    /* Asset previously existed, but has since been removed.  Resur-
+                       rect it into active assets, but zap its data: */
+                    pass->set_data.set("");
+                    pass->exp_data.data.assign("");
+                    deleted_asset_vector.erase (as);
+                    active_asset_vector.push_back (pass);
+                    return asset_search::found_active;  // it's active now anyway...
+                } else {
+                    return asset_search::found_deleted;
+                }
+            }
+        }
+    }
+    // Look then in invalid assets:
+    if (where == psa_asset_usage::invalid || where == psa_asset_usage::all) {
+        for (auto as = invalid_asset_vector.begin();  as < invalid_asset_vector.end();
+             ++as) {
+            psa_asset *pass = *as;
+            switch (criterion) {
+                case psa_asset_search::name:  // human-meaningful name
+                    match = (pass->asset_info.get_name() == target_name);
+                    break;
+                case psa_asset_search::id:  // ID#
+                    match = (pass->asset_info.id_n == target_id);
+                    break;
+                default:  // psa_asset_search::serial
+                    match = (pass->asset_info.asset_ser_no == serial_no);
+                    break;
+            }
+            if (match) {
+                asset = as;
+                return asset_search::found_invalid;
+            }
+        }
+    }
+    // Couldn't find it in any of the existing lists, so create it in active assets:
+    if (create_asset) {
+        try {
+            new_asset = new ASSET_TYPE;
+            if (criterion == psa_asset_search::id) {
+                new_asset->asset_info.id_n = target_id;
+            }  // TO DO:  probably should do the same for its name in a name search!
+            active_asset_vector.push_back(new_asset);
+            asset = prev(active_asset_vector.end());
+            return asset_search::created_new;
+        }
+        catch (std::bad_alloc& bad) {
+            std::cerr << "Error:  Failed to allocate an ASSET_TYPE:  " << bad.what()
+                      << endl;
+            return asset_search::unsuccessful;
+        }
+    } else {
+        return asset_search::not_found;
+    }
+    return asset_search::something_wrong;  // should never get here
+}
+
+#endif  // ifndef FIND_OR_CREATE_ASSET_HPP
diff --git a/tf_fuzz/utility/gibberish.cpp b/tf_fuzz/utility/gibberish.cpp
new file mode 100644
index 0000000..58a3f8f
--- /dev/null
+++ b/tf_fuzz/utility/gibberish.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*
+ * These functions produce random-gibberish quasi-words in a quasi-sentence.
+ * Random character streams may be conceptually sufficient, but for testing
+ * purposes, it's much easier for humans to remember and to distinguish semi-
+ * pro-nounceable gibberish like "dokwab neltiegib..." than
+ * "f7H%r^&B*5|j6@Mz>\#...".
+ */
+
+#include <string>
+
+#include "gibberish.hpp"  // shouldn't need any other project headers
+
+
+/**
+ * \brief Returns a letter for random-gibberish quasi-words in a quasi-sentence.
+ *
+ * \return A letter character value.
+ *
+ */
+char gibberish::letter(void)
+{
+    return 'a' + (rand() % ('z'-'a' + 1));
+}
+
+
+/**
+ * \brief Returns a vowel for random-gibberish quasi-words in a quasi-sentence.
+ *
+ * \return A vowel character value.
+ *
+ */
+char gibberish::vowel(void)
+{
+    char vowels[] = "aeiou";
+
+    return vowels[rand() % 5];
+}
+
+
+/**
+ * \brief Returns a consonant for random-gibberish quasi-words in a quasi-sentence.
+ *
+ * \return A consonant character value.
+ *
+ */
+char gibberish::consonant(void)
+{
+    char candidate;
+
+    do {
+        candidate = letter();
+    } while (   candidate == 'a' || candidate == 'e' || candidate == 'i'
+             || candidate == 'o' || candidate == 'u');
+    return candidate;
+}
+
+
+/**
+ * \brief Appends a semi-pronounceable syllable onto a string, stopping before
+ *        the end of the string, for random-gibberish quasi-words in a
+ *        quasi-sentence.  Returns a pointer to the next open spot in the string.
+ *
+ * \param[in] string_ptr Pointer to where to put the word.
+ *
+ * \param[in] stop       Pointer to last character in quasi-sentence.
+ *
+ * \return    Pointer to first character after the word.
+ *
+ */
+char *gibberish::syllable (char *string_ptr, char *stop)
+{
+    char *parser;  /* points into string while building it */
+
+    parser = string_ptr;
+    if ((rand() % 4) < 3) {
+        if (parser < stop) *parser++ = consonant();
+        if (parser < stop) *parser++ = vowel();
+        if (parser < stop) *parser++ = letter();
+    } else {
+        if (parser < stop) *parser++ = vowel();
+        if (((rand() % 4) < 1) && parser < stop) {
+            *parser++ = vowel();
+        }
+        if (parser < stop) *parser++ = consonant();
+    }
+    return parser;
+}
+
+
+/**
+ * \brief Appends a mostly-pronounceable quasi-word onto a quasi-sentence string,
+ *        stopping before the end of the string.  Returns a pointer to the next
+ *        open spot in the string.
+ *
+ * \param[in] initial_cap:  True if the first character should be capitalized.
+ *
+ * \param[in] string_ptr Pointer to where to put the word.
+ *
+ * \param[in] stop       Pointer to last character in quasi-sentence.
+ *
+ * \return    Pointer to first character after the word.
+ *
+ */
+char *gibberish::word (bool initial_cap, char *string_ptr, char *stop)
+{
+    int syllable_count;
+    char *parser;  /* points into string while building it */
+    string avoid_check;
+    bool has_avoid_words;
+    do {
+        has_avoid_words = false;
+        for (syllable_count = 0, parser = string_ptr;
+                syllable_count < 4
+             && (rand() % 5) >= syllable_count
+             && parser < stop;
+             syllable_count++) {
+            parser = syllable (parser, stop);
+        }
+        for (int i = 0;  i < n_avoids;  i++) {
+            avoid_check = string_ptr;
+            if (avoid[i] == avoid_check) {
+                has_avoid_words = true;
+                break;
+            }
+        }
+        if (initial_cap) {
+            *string_ptr -= 'a' - 'A';  /* more or less assumes ASCII */
+        }
+    } while (has_avoid_words);
+    return parser;
+}
+
+
+/**
+ * \brief Creates a mostly-pronounceable, random-gibberish quasi-sentence,
+ *        stopping before the end of the string.
+ *
+ * \param[in] string_ptr Pointer to beginning of string for quasi-sentence.
+ *
+ * \param[in] stop       Pointer to last character in quasi-sentence.
+ *
+ */
+void gibberish::sentence (char *string_ptr, char *stop)
+{
+    char *parser;  /* points into string while building it */
+    char punctuation[] = ".?!";
+
+    *stop = '\0';  /* null-terminate the string */
+    --stop;
+    parser = word (capitalize, string_ptr, stop);
+    if (parser < stop) {
+        *parser++ = ' ';
+    }
+    for (;  parser < stop; ) {
+        parser = word (dont_capitalize, parser, stop);
+        if (parser < stop) {
+            *parser++ = ' ';
+        }
+    }
+    parser--;
+    if (*parser == ' ') {
+        *parser = vowel();  // just to not have a blank at the end
+    }
+    *stop = punctuation[rand() % 3];
+}
+
+
+/**
+ * \brief Chooses a gibberish-sentence length.
+ *
+ */
+int gibberish::pick_sentence_len (void)
+{
+    return min_literal_data_len + (rand() % literal_data_len_span);
+}
+
+
+/**
+ * \brief Constructor for gibberish object.
+ *
+ */
+gibberish::gibberish (void)
+{
+    string holder;
+    
+    for (int i = 0;  i < n_avoids;  i++) {
+        holder = avoid[i];
+        for (long unsigned int j = 0;  j < holder.length();  j++) {
+            holder[j] = holder[j] - 1;
+        }
+        avoid[i] = holder;
+    }
+}
+
+
+/**
+ * \brief Destructor for gibberish object.
+ *
+ */
+gibberish::~gibberish (void)
+{
+    // Nothing to tear down.
+}
diff --git a/tf_fuzz/utility/gibberish.hpp b/tf_fuzz/utility/gibberish.hpp
new file mode 100644
index 0000000..c5692e3
--- /dev/null
+++ b/tf_fuzz/utility/gibberish.hpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*
+ * sec-regress.c&.h implement the Scripted-Call Application, and other functions
+ * for the security-regression testing feature.
+ *
+ */
+
+#ifndef GIBBERISH_HPP
+#define GIBBERISH_HPP
+
+#include <cstdlib>
+
+using namespace std;
+
+class gibberish
+{
+public:  // not much value in hiding these behind getters and setters
+    // Data members:
+        static const int min_literal_data_len = 32, max_literal_data_len = 512,
+            literal_data_len_span = max_literal_data_len - min_literal_data_len;
+    // Methods:
+        gibberish (void);  // (constructor)
+        ~gibberish (void);
+        char letter (void);
+        char vowel (void);
+        char consonant (void);
+        char *syllable (char *string_ptr, char *stop);
+        char *word (bool initial_cap, char *string_ptr, char *stop);
+        int pick_sentence_len (void);
+        void sentence (char *string_ptr, char *stop);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    static const int n_avoids = 42;
+    string avoid[n_avoids] = {"bvup", "epvcmf", "jou", "tusvdu", "dpotu", "gmpbu",
+                              "tipsu", "votjhofe", "csfbl", "fmtf", "mpoh", "txjudi",
+                              "gvdl", "dpoujovf", "gps", "wbhjob", "tjhofe", "dpdl",
+                              "wpje", "dbtf", "tiju", "fovn", "qfojt", "sfhjtufs",
+                              "qjtt", "uzqfefg", "efgbvmu", "ujut", "hpup", "tj{fpg",
+                              "uxbu", "wpmbujmf", "dvou", "dibs", "fyufso", "sfuvso",
+                              "dpjuvt", "vojpo", "ep", "jg", "tubujd", "xijmf"};
+    static const bool capitalize = true;
+    static const bool dont_capitalize = false;
+    // Parameters of random SST-asset generation:
+    // Methods:
+};
+
+#endif /* GIBBERISH_HPP */
diff --git a/tf_fuzz/utility/gibberish.o b/tf_fuzz/utility/gibberish.o
new file mode 100644
index 0000000..b5d4038
--- /dev/null
+++ b/tf_fuzz/utility/gibberish.o
Binary files differ
diff --git a/tf_fuzz/utility/randomization.cpp b/tf_fuzz/utility/randomization.cpp
new file mode 100644
index 0000000..23eb7d2
--- /dev/null
+++ b/tf_fuzz/utility/randomization.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**********************************************************************************
+   Functions in this file are exactly that:  functions, not methods of any class.
+   That is, they are stand-alone, utility functions linked in to the executable,
+   and available to whomever needs them.
+**********************************************************************************/
+
+#include "randomization.hpp"
+
+/**
+ * \brief Selects and returns a random key_usage_t value.
+ *
+ * \details
+ *
+ * \note
+ *
+ */
+string rand_key_usage (void)
+{
+    switch (rand() % 6) {
+        case 0:  return "PSA_KEY_USAGE_EXPORT";
+        case 1:  return "PSA_KEY_USAGE_ENCRYPT";
+        case 2:  return "PSA_KEY_USAGE_DECRYPT";
+        case 3:  return "PSA_KEY_USAGE_SIGN";
+        case 4:  return "PSA_KEY_USAGE_VERIFY";
+        case 5:  return "PSA_KEY_USAGE_DERIVE";
+    }
+    return "";  /* placate compiler */
+}
+
+/**
+ * \brief Selects and returns a random psa_algorithm_t value.
+ *
+ * \details
+ *
+ * \note
+ *
+ */
+/* TODO:  Likely want to make additional versions of these specific for TLS,
+   asymmetric, symmetric... */
+string rand_key_algorithm (void)
+{
+    switch (rand() % 44) {
+        case  0:  return "PSA_ALG_VENDOR_FLAG";
+        case  1:  return "PSA_ALG_CATEGORY_MASK";
+        case  2:  return "PSA_ALG_CATEGORY_HASH";
+        case  3:  return "PSA_ALG_CATEGORY_MAC";
+        case  4:  return "PSA_ALG_CATEGORY_CIPHER";
+        case  5:  return "PSA_ALG_CATEGORY_AEAD";
+        case  6:  return "PSA_ALG_CATEGORY_SIGN";
+        case  7:  return "PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION";
+        case  8:  return "PSA_ALG_CATEGORY_KEY_AGREEMENT";
+        case  9:  return "PSA_ALG_CATEGORY_KEY_DERIVATION";
+        case 10:  return "PSA_ALG_HASH_MASK";
+        case 11:  return "PSA_ALG_MD2";
+        case 12:  return "PSA_ALG_MD4";
+        case 13:  return "PSA_ALG_MD5";
+        case 14:  return "PSA_ALG_RIPEMD160";
+        case 15:  return "PSA_ALG_SHA_1";
+        case 16:  return "PSA_ALG_SHA_224";
+        case 17:  return "PSA_ALG_SHA_256";
+        case 18:  return "PSA_ALG_SHA_384";
+        case 19:  return "PSA_ALG_SHA_512";
+        case 20:  return "PSA_ALG_SHA_512_224";
+        case 21:  return "PSA_ALG_SHA_512_256";
+        case 22:  return "PSA_ALG_SHA3_224";
+        case 23:  return "PSA_ALG_SHA3_256";
+        case 24:  return "PSA_ALG_SHA3_384";
+        case 25:  return "PSA_ALG_SHA3_512";
+        case 26:  return "PSA_ALG_ANY_HASH";
+        case 27:  return "PSA_ALG_MAC_SUBCATEGORY_MASK";
+        case 28:  return "PSA_ALG_HMAC_BASE";
+        case 29:  return "PSA_ALG_MAC_TRUNCATION_MASK";
+        case 30:  return "PSA_ALG_CIPHER_MAC_BASE";
+        case 31:  return "PSA_ALG_CBC_MAC";
+        case 32:  return "PSA_ALG_CMAC";
+        case 33:  return "PSA_ALG_CIPHER_STREAM_FLAG";
+        case 34:  return "PSA_ALG_CIPHER_FROM_BLOCK_FLAG";
+        case 35:  return "PSA_ALG_ARC4";
+        case 36:  return "PSA_ALG_CTR";
+        case 37:  return "PSA_ALG_CFB";
+        case 38:  return "PSA_ALG_OFB";
+        case 39:  return "PSA_ALG_XTS";
+        case 40:  return "PSA_ALG_CBC_NO_PADDING";
+        case 41:  return "PSA_ALG_CBC_PKCS7";
+        case 42:  return "PSA_ALG_CCM";
+        case 43:  return "PSA_ALG_GCM";
+    }
+    return "";  /* placate compiler */
+}
+
+
+/**
+ * \brief Selects and returns a random psa_key_type_t value.
+ *
+ * \details
+ *
+ * \note
+ *
+ */
+string rand_key_type (void)
+{
+    switch (rand() % 24) {
+        case 0:  return "PSA_KEY_TYPE_NONE";
+        case 1:  return "PSA_KEY_TYPE_VENDOR_FLAG";
+        case 2:  return "PSA_KEY_TYPE_CATEGORY_MASK";
+        case 3:  return "PSA_KEY_TYPE_CATEGORY_SYMMETRIC";
+        case 4:  return "PSA_KEY_TYPE_CATEGORY_RAW";
+        case 5:  return "PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY";
+        case 6:  return "PSA_KEY_TYPE_CATEGORY_KEY_PAIR";
+        case 7:  return "PSA_KEY_TYPE_CATEGORY_FLAG_PAIR";
+        case 8:  return "PSA_KEY_TYPE_RAW_DATA";
+        case 9:  return "PSA_KEY_TYPE_HMAC";
+        case 10:  return "PSA_KEY_TYPE_DERIVE";
+        case 11:  return "PSA_KEY_TYPE_AES";
+        case 12:  return "PSA_KEY_TYPE_DES";
+        case 13:  return "PSA_KEY_TYPE_CAMELLIA";
+        case 14:  return "PSA_KEY_TYPE_ARC4";
+        case 15:  return "PSA_KEY_TYPE_CHACHA20";
+        case 16:  return "PSA_KEY_TYPE_RSA_PUBLIC_KEY";
+        case 17:  return "PSA_KEY_TYPE_RSA_KEY_PAIR";
+        case 18:  return "PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE";
+        case 19:  return "PSA_KEY_TYPE_ECC_KEY_PAIR_BASE";
+        case 20:  return "PSA_KEY_TYPE_ECC_CURVE_MASK";
+        case 21:  return "PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE";
+        case 22:  return "PSA_KEY_TYPE_DH_KEY_PAIR_BASE";
+        case 23:  return "PSA_KEY_TYPE_DH_GROUP_MASK";
+        default:  return "";
+    }
+    return "";  /* placate compiler */
+}
+
+
+
diff --git a/tf_fuzz/utility/randomization.hpp b/tf_fuzz/utility/randomization.hpp
new file mode 100644
index 0000000..2eb72f6
--- /dev/null
+++ b/tf_fuzz/utility/randomization.hpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef RANDOMIZATION_HPP
+#define RANDOMIZATION_HPP
+
+#include <string>
+
+using namespace std;
+
+string rand_key_usage (void);
+
+string rand_key_algorithm (void);
+
+string rand_key_type (void);
+
+#endif  /* #ifndef RANDOMIZATION_HPP */
diff --git a/tf_fuzz/utility/randomization.o b/tf_fuzz/utility/randomization.o
new file mode 100644
index 0000000..1d19db9
--- /dev/null
+++ b/tf_fuzz/utility/randomization.o
Binary files differ
diff --git a/tf_fuzz/utility/string_ops.cpp b/tf_fuzz/utility/string_ops.cpp
new file mode 100644
index 0000000..9c14140
--- /dev/null
+++ b/tf_fuzz/utility/string_ops.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "string_ops.hpp"
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
+
+// Replace first occurrence of find_str within orig of replace_str:
+size_t find_replace_1st (const string &find_str, const string &replace_str,
+                         string &orig) {
+    size_t where = 0;
+    where = orig.find(find_str, where);
+    if (where != string::npos) {
+        orig.replace(where, find_str.length(), replace_str);
+    }
+    return where;
+}
+
+// Replace all occurrences of find_str in "this" string, with replace_str:
+size_t find_replace_all (const string &find_str, const string &replace_str,
+                         string &orig) {
+    size_t where = 0;
+    do {
+        where = orig.find(find_str, where);
+        if (where != string::npos) {
+            orig.replace(where, find_str.length(), replace_str);
+        }
+    } while (where != string::npos);
+    return where;
+}
+
+
+string formalize (string input, string prefix) {
+    // First capitalize the input string:
+    for (auto cp = input.begin();  cp < input.end();  cp++) {
+        *cp = (char) toupper (*cp);
+    }
+    // If it already begins with the prefix...
+    if (input.substr (0, prefix.length()) == prefix) {
+        // then return it as capitalized:
+        return input;
+    } else {
+        // If not, prefix it with that prefix:
+        return prefix + input;
+    }
+}
+
+/* This implementation assumes ASCII character encoding and no "special characters" --
+   loosely speaking, "English." */
+string string_or_hex (string input, int clump_size) {
+    uint32_t n_alphanum = 0;  // the number of alphanumeric characters
+    bool prose = true;  // the string is alphanumeric, space, or common punctuation
+    ostringstream hex_stream;
+
+    for (auto cp = input.begin();  cp < input.end();  cp++) {
+        if ((int) *cp < 0) {
+            prose = false;
+            break;
+        }
+        if (   (*cp >= '0' && *cp <= '9')
+            || (*cp >= 'a' && *cp <= 'z') || (*cp >= 'A' && *cp <= 'Z')
+            || (*cp == ' ') || (*cp == ',') || (*cp == '.')
+            || (*cp == '?') || (*cp == '!')
+           ) {
+            n_alphanum++;
+        }
+    }
+    if (   prose  // so far at least!
+        && (  (input.length() - n_alphanum) // number of chars that are not "English"
+            < (input.length() >> 3)  // 1/8 of the length of the string
+       )   ) {
+        return input;  // take it at face-value
+    }
+    // It's not run-of-the-mill text, so create a hex string:
+    int i = 0;
+    for (auto cp = input.begin();  cp < input.end();  cp++) {
+        hex_stream << setfill('0') << setw(2) << hex << (((unsigned) *cp) & 0xff);
+        if (++i >= clump_size) {
+            hex_stream << " ";
+            i = 0;
+        }
+    }
+    return hex_stream.str();
+}
+
+string binary_from_hex (string input) {
+    stringstream hex_stream;
+    uint8_t aByte;  // each byte as we grab it
+    string result = "";
+    string holder_string = "";
+
+    hex_stream.str(input);
+    hex_stream.width(2);
+    while (!hex_stream.eof()) {
+        hex_stream >> skipws >> setw(2) >> holder_string;
+        try {   // TODO:  May not catch all bad-chars.
+            aByte = stoi(holder_string, 0, 16);
+        }
+        catch (const invalid_argument &arg_err) {
+            cerr << "Error 2345:  Non-hexadecimal character found in binary-data string ("
+                 << arg_err.what() << endl;
+            exit (2345);
+        }
+        result += aByte;
+    }
+    return result;
+}
diff --git a/tf_fuzz/utility/string_ops.hpp b/tf_fuzz/utility/string_ops.hpp
new file mode 100644
index 0000000..83e4d9a
--- /dev/null
+++ b/tf_fuzz/utility/string_ops.hpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef STRING_OPS_HPP
+#define STRING_OPS_HPP
+
+#include <cstddef>
+#include <string>
+
+using namespace std;
+
+// Replace first occurrence of find_str within orig of replace_str:
+size_t find_replace_1st (const string &find_str, const string &replace_str,
+                         string &orig);
+
+// Replace all occurrences of find_str in "this" string, with replace_str:
+size_t find_replace_all (const string &find_str, const string &replace_str,
+                         string &orig);
+
+/* In both of the above string-replacement functions, the return value is start
+   offset to the (last) occurrence of "find_str" within "orig." */
+
+/* formalize() turns an abbreviated, "human" name for a PSA setting into its
+   presumed official name.  Examples:
+   "export" with prefix "PSA_KEY_USAGE_" becomes "PSA_KEY_USAGE_EXPORT".
+   "generic_error" with prefix "PSA_ERROR_" becomes "PSA_ERROR_GENERIC_ERROR".
+   "PSA_ERROR_INVALID_ARGUMENT" stays unchanged as "PSA_ERROR_INVALID_ARGUMENT".
+*/
+string formalize (string input, string prefix);
+
+/* string_or_hex() takes a string (e.g., describing a key's "material" -- data),
+   and:
+   *  If it "appears to be" alphanumeric, then returns it unaltered.
+   *  Otherwise, if it "appears to be binary data, it returns a new string of
+      it as hex digits.
+   *  clump_size is how many bytes to clump together between spaces */
+string string_or_hex (string input, int clump_size);
+
+/* binary_from_hex() takes a string of hex characters, and returns a string
+   containing those raw byte values (i.e., not human-readable, and not really
+   a string in the usual sense of the word).  In the future, it would be good
+   to address binary data better. */
+string binary_from_hex (string input);
+
+#endif  // #ifndef STRING_OPS_HPP
diff --git a/tf_fuzz/utility/string_ops.o b/tf_fuzz/utility/string_ops.o
new file mode 100644
index 0000000..5f3d9ac
--- /dev/null
+++ b/tf_fuzz/utility/string_ops.o
Binary files differ
diff --git a/tf_fuzz/utility/variables.cpp b/tf_fuzz/utility/variables.cpp
new file mode 100644
index 0000000..ab2a823
--- /dev/null
+++ b/tf_fuzz/utility/variables.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* This file defines information to track regarding variables in the generated test
+   code. */
+
+#include <string>
+#include <vector>
+#include <list>
+#include <iostream>
+#include <fstream>
+
+#include "class_forwards.hpp"
+
+#include "data_blocks.hpp"
+#include "psa_asset.hpp"
+#include "crypto_asset.hpp"
+#include "psa_call.hpp"
+#include "find_or_create_asset.hpp"
+#include "variables.hpp"
+#include "gibberish.hpp"
+
+/* 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.  However these in particular are mostly axiomatic:  Not
+   dependent upon other classes. */
+
+
+using namespace std;
+
+
+/**********************************************************************************
+   Methods of class variable_info follow:
+**********************************************************************************/
+
+variable_info::variable_info (void)  // (default constructor)
+{
+    gibberish *gib = new gibberish;
+
+    hash_declared = value_known = false;
+    name = "";
+    length = 100 + (rand() % 800);
+    gib->sentence ((char*) value, (char*) value + length);
+        // TODO:  Sizes of random data neesds to be strategized better
+    type = psa_asset_type::unknown;
+    delete gib;
+}
+
+variable_info::variable_info (string var_name, psa_asset_type var_type)
+{  // (constructor with known name and type)
+    gibberish *gib = new gibberish;
+
+    hash_declared = value_known = false;
+    name.assign (var_name);
+    length = 100 + (rand() % 800);
+    gib->sentence ((char*) value, (char*) value + length);
+        // TODO:  Sizes of random data needs to be strategized better
+    type = var_type;
+    delete gib;
+}
+
+variable_info::~variable_info (void)  // (destructor)
+{}
+
+
+/**********************************************************************************
+   End of methods of class variable_info.
+**********************************************************************************/
diff --git a/tf_fuzz/utility/variables.hpp b/tf_fuzz/utility/variables.hpp
new file mode 100644
index 0000000..886acc3
--- /dev/null
+++ b/tf_fuzz/utility/variables.hpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <string>
+#include <vector>
+
+/* This file defines information to track regarding variables in the generated test
+   code. */
+
+#ifndef VARIABLES_HPP
+#define VARIABLES_HPP
+
+/* 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.  However these in particular are mostly axiomatic:  Not
+   dependent upon other classes. */
+
+
+using namespace std;
+
+
+/**********************************************************************************
+  Class variable_info tracks everything we know about a given variable in the
+  generated C code.
+**********************************************************************************/
+
+class variable_info
+{
+public:
+    // Data members:
+        /* The existence of this variable tracker means that the data variable and
+           the length variable have been declared, but there are other variants on
+           this variable that may or may not have been declared already.  Thus
+           the *_declared bool(s) below. */
+        bool hash_declared;  // true if the hash of this variable has been declared
+        bool value_known;  // true if the variable's value can be known in simulation
+        string name;  // variable name
+        unsigned char value[2048];  // the current value of the variable
+        int length;  // of the variable's value
+        psa_asset_type type;  // type of info contained in the variable
+
+    // Methods:
+        variable_info (void);  // (default constructor)
+        variable_info (  // (constructor with known name and type)
+            string var_name, psa_asset_type var_type
+        );
+        ~variable_info (void);  // (destructor)
+
+protected:
+    // Data members:
+};
+
+
+#endif // VARIABLES_HPP
+
diff --git a/tf_fuzz/utility/variables.o b/tf_fuzz/utility/variables.o
new file mode 100644
index 0000000..bc7772a
--- /dev/null
+++ b/tf_fuzz/utility/variables.o
Binary files differ