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/template/README b/tf_fuzz/template/README
new file mode 100644
index 0000000..3cfc309
--- /dev/null
+++ b/tf_fuzz/template/README
@@ -0,0 +1,10 @@
+These classes describe "tracker" objects for parsing test templates, and for
+generating PSA calls from them.
+
+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/template_dir.html
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
diff --git a/tf_fuzz/template/crypto_template_line.cpp b/tf_fuzz/template/crypto_template_line.cpp
new file mode 100644
index 0000000..3cf8a35
--- /dev/null
+++ b/tf_fuzz/template/crypto_template_line.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 "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"
+#include "crypto_asset.hpp"
+#include "crypto_template_line.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class set_policy_template_line follow:
+**********************************************************************************/
+
+set_policy_template_line::set_policy_template_line (tf_fuzz_info *resources)
+    : policy_template_line (resources)
+{
+    // No further setup to be performed.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// Default destructor:
+set_policy_template_line::~set_policy_template_line (void)
+{
+    // TODO:  Add an error for this being invoked.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class set_policy_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class read_policy_template_line follow:
+**********************************************************************************/
+
+read_policy_template_line::read_policy_template_line (tf_fuzz_info *resources)
+    : policy_template_line (resources)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// Default destructor:
+read_policy_template_line::~read_policy_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class read_policy_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class set_key_template_line follow:
+**********************************************************************************/
+
+set_key_template_line::set_key_template_line (tf_fuzz_info *resources)
+    : key_template_line (resources)
+{
+    // Nothing further to initialize.
+}
+
+// Default destructor:
+set_key_template_line::~set_key_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class set_key_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class remove_key_template_line follow:
+**********************************************************************************/
+
+remove_key_template_line::remove_key_template_line (tf_fuzz_info *resources)
+    : key_template_line (resources)
+{
+    is_remove = true;  // template_line's constructor defaults this to false
+}
+
+// Default destructor:
+remove_key_template_line::~remove_key_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class remove_key_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class read_key_template_line follow:
+**********************************************************************************/
+
+read_key_template_line::read_key_template_line (tf_fuzz_info *resources)
+    : key_template_line (resources)
+{
+    char gibberish_buffer[4096];  string databuff;
+    int data_length;
+    set_data.string_specified = (rand()%2) == 1?  true : false;
+
+    // Go ahead and create a literal-data string even if not ultimately used:
+    data_length = test_state->gibbergen.pick_sentence_len();
+    test_state->gibbergen.sentence (gibberish_buffer, gibberish_buffer + data_length);
+    databuff = gibberish_buffer;  set_data.set (databuff);
+
+    set_data.file_specified = (!set_data.string_specified && (rand()%2) == 1)?  true : false;
+    set_data.file_path = "";  // can't really devise a random path
+}
+
+// Default destructor:
+read_key_template_line::~read_key_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class read_key_template_line.
+**********************************************************************************/
diff --git a/tf_fuzz/template/crypto_template_line.hpp b/tf_fuzz/template/crypto_template_line.hpp
new file mode 100644
index 0000000..4626536
--- /dev/null
+++ b/tf_fuzz/template/crypto_template_line.hpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CRYPTO_TEMPLATE_LINE_HPP
+#define CRYPTO_TEMPLATE_LINE_HPP
+
+#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 "psa_asset.hpp"
+//class psa_asset;  // just need a forward reference
+#include "template_line.hpp"
+#include "psa_call.hpp"
+*/
+using namespace std;
+
+
+class set_policy_template_line : public policy_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            /* If the name of the primary asset is known, then add calls at
+               random, otherwise append to end.  If not, then we do not know
+               what asset-name barrier to search for. */
+            bool add_to_end_bool = (random_asset != psa_asset_usage::all);
+
+            // Add the calls of interest:
+            define_call<init_policy_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_random_after_barrier, yes_set_barrier  );
+            define_call<reset_policy_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_random_after_barrier, yes_set_barrier  );
+            policy_info.usage_string.assign ("0");  // clear out all usages
+            define_call<set_policy_usage_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_random_after_barrier, yes_set_barrier  );
+            if (policy_info.exportable) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_EXPORT");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            if (policy_info.copyable) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_COPY");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            if (policy_info.can_encrypt) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_ENCRYPT");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            if (policy_info.can_decrypt) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_DECRYPT");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            if (policy_info.can_sign) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_SIGN");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            if (policy_info.can_verify) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_VERIFY");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            if (policy_info.derivable) {
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_DERIVE");
+                define_call<add_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, dont_set_barrier  );
+            }
+            define_call<set_policy_lifetime_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, dont_set_barrier  );
+            define_call<set_policy_algorithm_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, dont_set_barrier  );
+            define_call<set_policy_type_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end, yes_set_barrier  );
+            define_call<set_policy_size_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end, yes_set_barrier  );
+        }
+        set_policy_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~set_policy_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class read_policy_template_line : public policy_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            /* If the name of the primary asset is known, then add calls at
+               random, otherwise append to end.  If not, then we do not know
+               what asset-name barrier to search for. */
+            bool add_to_end_bool = (random_asset != psa_asset_usage::all);
+
+            if (policy_info.get_policy_from_key) {
+                define_call<get_key_policy_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end_bool, yes_set_barrier  );
+            }
+            define_call<get_policy_usage_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, yes_set_barrier  );
+            define_call<get_policy_lifetime_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, dont_set_barrier  );
+            define_call<get_policy_algorithm_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, dont_set_barrier  );
+            define_call<get_policy_type_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, dont_set_barrier  );
+            define_call<get_policy_size_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end_bool, dont_set_barrier  );
+            if (print_data) {
+                /* Printing data, so we need to read and filter usage for various
+                   attributes, one by one: */
+                policy_info.print_usage_true_string.assign ("key can be exported.");
+                policy_info.print_usage_false_string.assign ("key cannot be exported.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_EXPORT");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, dont_set_barrier  );
+                policy_info.print_usage_true_string.assign ("key can be copied.");
+                policy_info.print_usage_false_string.assign ("key cannot be copied.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_COPY");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, dont_set_barrier  );
+                policy_info.print_usage_true_string.assign ("key works for encryption.");
+                policy_info.print_usage_false_string.assign ("key is not for encryption.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_ENCRYPT");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, dont_set_barrier  );
+                policy_info.print_usage_true_string.assign ("key works for decyption.");
+                policy_info.print_usage_false_string.assign ("key is not for decyption.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_DECRYPT");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, dont_set_barrier  );
+                policy_info.print_usage_true_string.assign ("key works for signing.");
+                policy_info.print_usage_false_string.assign ("key is not for signing.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_SIGN");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, dont_set_barrier  );
+                policy_info.print_usage_true_string.assign ("key can be used to verify.");
+                policy_info.print_usage_false_string.assign ("key not for verify.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_VERIFY");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, dont_set_barrier  );
+                policy_info.print_usage_true_string.assign ("key can derive other keys.");
+                policy_info.print_usage_false_string.assign ("key cannot derive other keys.");
+                policy_info.usage_string.assign ("PSA_KEY_USAGE_DERIVE");
+                define_call<print_policy_usage_call> (set_data, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, yes_set_barrier  );
+            }
+        }
+        read_policy_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~read_policy_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class set_key_template_line : public key_template_line
+{
+public:
+   // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            if (policy_info.copy_key) {
+                // Copying a key:
+                define_call<copy_key_call> (set_info, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, yes_set_barrier);
+            } else if (set_data.string_specified || set_data.random_data) {
+                // Key data (key material) supplied:
+                define_call<create_key_call> (set_info, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, yes_set_barrier);
+            } else {
+                // Generate from scratch:
+                define_call<generate_key_call> (set_info, random_data,
+                                fill_in_template, create_call, temLin, rsrc,
+                                add_to_end, yes_set_barrier);
+            }
+        }
+        set_key_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~set_key_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class read_key_template_line : public key_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            define_call<read_key_data_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end, yes_set_barrier);
+        }
+        read_key_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~read_key_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class remove_key_template_line : public key_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            define_call<remove_key_call> (set_data, random_data,
+                            fill_in_template, create_call, temLin, rsrc,
+                            add_to_end, yes_set_barrier);
+        }
+        remove_key_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~remove_key_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // #ifndef CRYPTO_TEMPLATE_LINE_HPP
diff --git a/tf_fuzz/template/crypto_template_line.o b/tf_fuzz/template/crypto_template_line.o
new file mode 100644
index 0000000..42e8502
--- /dev/null
+++ b/tf_fuzz/template/crypto_template_line.o
Binary files differ
diff --git a/tf_fuzz/template/secure_template_line.cpp b/tf_fuzz/template/secure_template_line.cpp
new file mode 100644
index 0000000..73fbde3
--- /dev/null
+++ b/tf_fuzz/template/secure_template_line.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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 "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 "secure_template_line.hpp"
+#include "sst_call.hpp"
+#include "sst_template_line.hpp"
+#include "sst_asset.hpp"
+#include "crypto_asset.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class security_hash_template_line follow:
+**********************************************************************************/
+
+//**************** security_hash_template_line methods ****************
+
+bool security_hash_template_line::copy_template_to_call (psa_call *call)
+{
+    // Copy asset info to call object for creation code -- the entire vector:
+    for (auto as_name : asset_info.asset_name_vector) {
+        /* Also copy into template line object's local vector: */
+        call->asset_info.asset_name_vector.push_back (as_name);
+    }
+    call->asset_info.id_n = asset_info.id_n;
+        // this call is currently limited to name-based
+    call->asset_info.name_specified = true;
+    call->asset_info.asset_ser_no = asset_info.asset_ser_no;  // TODO:  Does this make sense?
+    call->asset_info.how_asset_found = asset_search::found_active;
+    call->random_asset = random_asset;
+    call->set_data.string_specified = false;  // shouldn't matter, but...
+    call->set_data.file_specified = false;
+    call->set_data.file_path.assign("");
+    call->set_data.set("");
+    call->set_data.flags_string.assign ("");
+    call->exp_data.pf_info_incomplete = true;
+    return true;
+}
+
+security_hash_template_line::security_hash_template_line (tf_fuzz_info *resources)
+    : security_template_line (resources)
+{
+}
+// Default destructor:
+security_hash_template_line::~security_hash_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class security_hash_template_line.
+**********************************************************************************/
+
diff --git a/tf_fuzz/template/secure_template_line.hpp b/tf_fuzz/template/secure_template_line.hpp
new file mode 100644
index 0000000..7f53c70
--- /dev/null
+++ b/tf_fuzz/template/secure_template_line.hpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* Objects typed to subclasses of the these classes are constructed and filled in
+   by the parser as it parses the test template.  Although these objects do largely
+   correspond to template lines, there's no real correlation to lines in the
+   generated code. */
+
+#ifndef SECURE_TEMPLATE_LINE_HPP
+#define SECURE_TEMPLATE_LINE_HPP
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <new>
+
+/* 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;
+
+/* Note:  The following are sub-classed from security (above). */
+
+class security_hash_template_line : public security_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_data, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc)
+        {
+            define_call<hash_call> (set_data, random_data, fill_in_template,
+                                    create_call, temLin, rsrc,
+                                    add_to_end, yes_set_barrier);
+        }
+        bool copy_template_to_call (psa_call *the_call);
+        security_hash_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~security_hash_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif // #ifndef SECURE_TEMPLATE_LINE_HPP
+
diff --git a/tf_fuzz/template/secure_template_line.o b/tf_fuzz/template/secure_template_line.o
new file mode 100644
index 0000000..bec2487
--- /dev/null
+++ b/tf_fuzz/template/secure_template_line.o
Binary files differ
diff --git a/tf_fuzz/template/sst_template_line.cpp b/tf_fuzz/template/sst_template_line.cpp
new file mode 100644
index 0000000..829071a
--- /dev/null
+++ b/tf_fuzz/template/sst_template_line.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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 "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_template_line.hpp"
+#include "sst_asset.hpp"
+
+
+/**********************************************************************************
+   Methods of class set_sst_template_line follow:
+**********************************************************************************/
+
+//**************** set_sst_template_line methods ****************
+
+set_sst_template_line::set_sst_template_line (tf_fuzz_info *resources)
+    : sst_template_line (resources)  // constructor)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+
+// Default destructor:
+set_sst_template_line::~set_sst_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+
+/**********************************************************************************
+   End of methods of class set_sst_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class read_sst_template_line follow:
+**********************************************************************************/
+
+read_sst_template_line::read_sst_template_line (tf_fuzz_info *resources)
+    : sst_template_line (resources)  // (constructor)
+{
+    char gibberish_buffer[4096];  string databuff;
+    int data_length;
+    set_data.string_specified = (rand()%2) == 1?  true : false;
+
+    // Go ahead and create a literal-data string even if not needed:
+    data_length = test_state->gibbergen.pick_sentence_len();
+    test_state->gibbergen.sentence (gibberish_buffer, gibberish_buffer + data_length);
+    databuff = gibberish_buffer;  set_data.set (databuff);
+
+    set_data.file_specified
+        = (!set_data.string_specified && (rand()%2) == 1)?  true : false;
+    set_data.file_path = "";  // can't really devise a random path
+}
+
+// Default destructor:
+read_sst_template_line::~read_sst_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class read_sst_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class remove_sst_template_line follow:
+**********************************************************************************/
+
+remove_sst_template_line::remove_sst_template_line (tf_fuzz_info *resources)
+    : sst_template_line (resources)  // (constructor)
+{
+    is_remove = true;  // template_line's constructor defaults this to false
+}
+
+// Default destructor:
+remove_sst_template_line::~remove_sst_template_line (void)
+{
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class remove_sst_template_line.
+**********************************************************************************/
+
diff --git a/tf_fuzz/template/sst_template_line.hpp b/tf_fuzz/template/sst_template_line.hpp
new file mode 100644
index 0000000..bec927c
--- /dev/null
+++ b/tf_fuzz/template/sst_template_line.hpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SST_TEMPLATE_LINE_HPP
+#define SST_TEMPLATE_LINE_HPP
+
+#include <cstdlib>  // for rand()
+
+/* 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_asset.hpp"
+#include "template_line.hpp"
+#include "psa_call.hpp"
+*/
+
+
+using namespace std;
+
+class set_sst_template_line : public sst_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            define_call<sst_set_call> (set_info, random_data, fill_in_template,
+                                       create_call, temLin, rsrc, add_to_end,
+                                       dont_set_barrier);
+        }
+        set_sst_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~set_sst_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+        string rand_creation_flags (void);  // choose a random set of creation flags
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class remove_sst_template_line : public sst_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            define_call<sst_remove_call> (set_info, random_data, fill_in_template,
+                                       create_call, temLin, rsrc, add_to_end,
+                                       dont_set_barrier);
+        }
+        remove_sst_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~remove_sst_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class read_sst_template_line : public sst_template_line
+{
+public:
+    // Data members:
+    // Methods:
+        void setup_call (set_data_info set_info, bool random_data,
+                         bool fill_in_template, bool create_call,
+                         template_line *temLin, tf_fuzz_info *rsrc) {
+            define_call<sst_get_call> (set_info, random_data, fill_in_template,
+                                       create_call, temLin, rsrc, add_to_end,
+                                       dont_set_barrier);
+        }
+        read_sst_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~read_sst_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+#endif  // #ifndef SST_TEMPLATE_LINE_HPP
diff --git a/tf_fuzz/template/sst_template_line.o b/tf_fuzz/template/sst_template_line.o
new file mode 100644
index 0000000..2be4f31
--- /dev/null
+++ b/tf_fuzz/template/sst_template_line.o
Binary files differ
diff --git a/tf_fuzz/template/template_line.cpp b/tf_fuzz/template/template_line.cpp
new file mode 100644
index 0000000..a8625b1
--- /dev/null
+++ b/tf_fuzz/template/template_line.cpp
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* Objects typed to subclasses of the these classes are constructed and filled in by
+   the parser as it parses test-template lines.  There is not necessarily a one-to-one
+   correspondence between the template lines and either the PSA commands generated nor
+   PSA assets they manipulate.  PSA assets (which persist through the test) and PSA
+   commands are therefore tracked in separate objects, but referenced here. */
+
+#include <vector>
+#include <algorithm>  // for STL find()
+
+#include "class_forwards.hpp"
+
+#include "data_blocks.hpp"
+#include "boilerplate.hpp"
+#include "randomization.hpp"
+#include "gibberish.hpp"
+#include "compute.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"
+#include "crypto_asset.hpp"
+
+
+
+/**********************************************************************************
+   Methods of class template_line follow:
+**********************************************************************************/
+
+// Constructor, passing in the tf_fuzz object for reference to all objects:
+template_line::template_line (tf_fuzz_info *resources) : test_state(resources)
+{
+    set_data.file_path.assign ("");
+    assign_data_var_specified = false;
+    set_data.flags_string.assign ("");
+    random_asset = psa_asset_usage::all;
+        // if not deleting a random asset of a certain type, then search all as usual
+    target_barrier = "";
+    set_data.file_specified = false;
+    print_data = hash_data = false;
+    call_ser_no = -1;
+    asset_2_name.assign ("");  asset_3_name.assign ("");
+    is_remove = false;  // will correct this in the remove case
+}
+
+/**********************************************************************************
+   Class template_line methods regarding setting and getting asset-names follow:
+**********************************************************************************/
+
+// Default destructor:
+template_line::~template_line (void)
+{
+    // Destruct the vectors of asset names/IDs:
+    asset_info.asset_name_vector.erase (asset_info.asset_name_vector.begin(),
+                                        asset_info.asset_name_vector.end());
+    asset_info.asset_id_n_vector.erase (asset_info.asset_id_n_vector.begin(),
+                                        asset_info.asset_id_n_vector.end());
+}
+
+// (Default constructor not used)
+
+/**********************************************************************************
+   End of methods of class template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class sst_template_line follow:
+**********************************************************************************/
+
+// (Currently, no need to specialize copy_template_to_call() for individual SST ops.)
+bool sst_template_line::copy_template_to_call (psa_call *call)
+{
+    // Copy asset info to call object for creation code:
+    call->asset_info = asset_info;
+    call->set_data = set_data;
+    call->set_data.string_specified =   set_data.string_specified
+                                     || set_data.random_data;
+        // not really right, but more convenient to combine these two cases
+    call->assign_data_var_specified = assign_data_var_specified;
+    call->assign_data_var = assign_data_var;
+    call->random_asset = random_asset;
+    if (target_barrier == "") {  // barriers are probably not used for SST, but...
+        call->target_barrier = asset_info.get_name();
+    } else {
+        call->target_barrier = target_barrier;
+    }
+    call->set_data.flags_string.assign (set_data.flags_string);
+    call->exp_data = expect;
+    call->exp_data.pf_info_incomplete = true;
+    call->id_string = asset_name;  // data = expected
+    call->print_data = print_data;
+    call->hash_data = hash_data;
+    return true;
+}
+
+sst_template_line::sst_template_line (tf_fuzz_info *resources)
+                                          : template_line (resources)
+{
+    asset_info.asset_type = psa_asset_type::sst;
+}
+
+// Default destructor:
+sst_template_line::~sst_template_line (void)
+{
+    // No real clean-up needed.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+
+/**********************************************************************************
+   End of methods of class sst_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class key_template_line follow:
+**********************************************************************************/
+
+key_template_line::key_template_line (tf_fuzz_info *resources)
+                                          : template_line (resources)
+{
+    asset_info.asset_type = psa_asset_type::key;
+}
+
+bool key_template_line::copy_template_to_call (psa_call *call)
+{
+    // Copy asset info to call object for creation code:
+    call->asset_info = asset_info;
+    call->set_data = set_data;
+    call->set_data = set_data;
+    call->policy = policy_info;
+    call->asset_2_name = asset_2_name;
+    call->asset_3_name = asset_3_name;
+    call->set_data.string_specified =   set_data.string_specified
+                                     || set_data.random_data;
+        // not really right, but more convenient to combine these two cases
+    call->assign_data_var_specified = assign_data_var_specified;
+    call->assign_data_var = assign_data_var;
+    call->random_asset = random_asset;
+    if (target_barrier == "") {  // barriers are probably not used for SST, but...
+        call->target_barrier = asset_info.get_name();
+    } else {
+        call->target_barrier = target_barrier;
+    }
+    call->set_data.flags_string.assign (set_data.flags_string);
+    call->exp_data = expect;
+    call->exp_data.pf_info_incomplete = true;
+    call->id_string = asset_name;  // data = expected
+    call->print_data = print_data;
+    call->hash_data = hash_data;
+    return true;
+}
+
+// Create ID-based name:
+string key_template_line::make_id_based_name (uint64_t id_n, string &name)
+{
+    string result = "Key_ID_";
+    result.append(to_string(id_n));
+    return result;
+}
+
+// Default destructor:
+key_template_line::~key_template_line (void)
+{
+    // No real clean-up needed.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+
+/**********************************************************************************
+   End of methods of class key_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class policy_template_line follow:
+**********************************************************************************/
+
+policy_template_line::policy_template_line (tf_fuzz_info *resources)
+            : template_line (resources)
+{
+    asset_info.asset_type = psa_asset_type::policy;
+}
+
+bool policy_template_line::copy_template_to_call (psa_call *call)
+{
+    // Copy asset info to call object for creation code:
+    call->asset_info = asset_info;
+    call->set_data = set_data;
+    call->set_data = set_data;
+    call->policy = policy_info;
+    call->asset_2_name = asset_2_name;
+    call->asset_3_name = asset_3_name;
+    call->set_data.string_specified =   set_data.string_specified
+                                     || set_data.random_data;
+        // not really right, but more convenient to combine these two cases
+    call->assign_data_var_specified = assign_data_var_specified;
+    call->assign_data_var = assign_data_var;
+    call->random_asset = random_asset;
+    if (target_barrier == "") {  // barriers are probably not used for SST, but...
+        call->target_barrier = asset_info.get_name();
+    } else {
+        call->target_barrier = target_barrier;
+    }
+    call->set_data.flags_string.assign (set_data.flags_string);
+    call->exp_data = expect;
+    call->exp_data.pf_info_incomplete = true;
+    call->id_string = asset_name;  // data = expected
+    call->print_data = print_data;
+    call->hash_data = hash_data;
+    return true;
+}
+
+// Create ID-based name:
+string policy_template_line::make_id_based_name (uint64_t id_n, string &name)
+{
+    string result = "Policy_ID_";
+    result.append(to_string(id_n));
+    //
+    return result;
+}
+
+// Default destructor:
+policy_template_line::~policy_template_line (void)
+{
+    // No real clean-up needed.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+
+/**********************************************************************************
+   End of methods of class policy_template_line.
+**********************************************************************************/
+
+
+/**********************************************************************************
+   Methods of class security_template_line follow:
+**********************************************************************************/
+
+security_template_line::security_template_line (tf_fuzz_info *resources)
+            : template_line (resources)
+{
+}
+
+// Default destructor:
+security_template_line::~security_template_line (void)
+{
+    // No real clean-up needed.
+    return;  // just to have something to pin a breakpoint onto
+}
+
+// (Default constructor not used)
+
+
+/**********************************************************************************
+   End of methods of class security_template_line.
+**********************************************************************************/
+
diff --git a/tf_fuzz/template/template_line.hpp b/tf_fuzz/template/template_line.hpp
new file mode 100644
index 0000000..143232d
--- /dev/null
+++ b/tf_fuzz/template/template_line.hpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* Objects typed to subclasses of the these classes are constructed and filled in by
+   the parser as it parses test-template lines.  There is not necessarily a one-to-one
+   correspondence between the template lines and either the PSA commands generated nor
+   PSA assets they manipulate.  PSA assets (which persist through the test) and PSA
+   commands are therefore tracked in separate objects, but referenced here. */
+
+#ifndef TEMPLATE_LINE_HPP
+#define TEMPLATE_LINE_HPP
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+#include <new>
+
+/* 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 template_line
+{
+public:
+    // Data members:  // low value to hide these behind setters and getters
+        // Everything about the test -- accumulated PSA commands, assets, etc.:
+        tf_fuzz_info *test_state;
+        /* Note:  The following are pointers to the psa_asset and psa_call currently
+           being worked with.  These objects these are first placed on the appropriate
+           vector in test_state of such objects, and then referenced here. */
+        expect_info expect;  // everything about expected results
+        set_data_info set_data;  // everything about setting PSA-asset data
+        asset_name_id_info asset_info;  // everything about the asset(s) for this line
+        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
+        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. */
+        key_policy_info policy_info;  // specific to crypto, but must be in base class
+        long call_ser_no;  // unique identifer for psa_call tracker object
+        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 or from a named variable
+        string assign_data_var;  // name of variable to dump (assign) data into
+        bool print_data;  // true to print asset data to test log
+        bool hash_data;  // true to hash data for later comparison
+        /* Vectors of asset names or IDs.  These are used to create several similar
+           PSA calls from a single template line. */
+        bool is_remove;  // true if this template line is to remove an asset
+    // Methods (mostly for calling from within yyparse()):
+        virtual bool copy_template_to_call (psa_call *the_call) = 0;
+        virtual void setup_call (set_data_info set_data, bool random_data,
+                                 bool fill_in_template, bool create_call,
+                                 template_line *temLin, tf_fuzz_info *rsrc) = 0;
+        template_line (tf_fuzz_info *resources);  // (constructor)
+        virtual ~template_line (void);
+
+protected:  // a lot simpler to just let subclasses access these directly
+    // Data members:
+        // Parallel vectors of PSA-asset info, by asset identified:
+        /* Not all template lines involve expected data, but all that do use it,
+           use it the same, so include it here. */
+        string asset_name;  // parsed from template, assigned to psa_asset object
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+/* Note:  The following are sub-classed from template_line (above), and then further
+          subclassed in sst_template_line.*pp, crypto_template_line.*pp, etc.  Concep-
+          tually, these subclasses might be more logically put in those sub-classing
+          files, but this gives a more-even balance of file size and complexity. */
+
+
+class sst_template_line : public template_line
+{
+public:
+    // Data members:
+        // SST-asset info:
+        // PSA-call info:
+    // Methods:
+        bool copy_template_to_call (psa_call *the_call);
+        sst_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~sst_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+class key_template_line : public template_line
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_template_to_call (psa_call *the_call);
+        string make_id_based_name (uint64_t id_n, string &name);
+            // create ID-based asset name
+        key_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~key_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+class policy_template_line : public template_line
+{
+public:
+    // Data members:
+    // Methods:
+        bool copy_template_to_call (psa_call *the_call);
+        policy_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~policy_template_line (void);
+
+protected:
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+        string make_id_based_name (uint64_t id_n, string &name);
+            // create ID-based asset name
+};
+
+
+class security_template_line : public template_line
+{
+public:
+    // Data members:  // low value to hide these behind setters and getters
+        // Everything about the test -- accumulated PSA commands, assets, etc.:
+    // Methods (for calling from within yyparse()):
+        security_template_line (tf_fuzz_info *resources);  // (constructor)
+        ~security_template_line (void);
+
+protected:  // a lot simpler to just let subclasses access these directly
+    // Data members:
+    // Methods:
+
+private:
+    // Data members:
+    // Methods:
+};
+
+
+#endif  // TEMPLATE_LINE_HPP
diff --git a/tf_fuzz/template/template_line.o b/tf_fuzz/template/template_line.o
new file mode 100644
index 0000000..ccdf59d
--- /dev/null
+++ b/tf_fuzz/template/template_line.o
Binary files differ